Skip to main content
A claim (clm_...) is a typed data point on a person. Each has a claim_type, a status, and the fields defined for that type, validated against a strict schema. Applications validate against claims.

Lifecycle

Every claim row carries a status plus two retirement timestamps — archived_at (pending-only) and superseded_at (verified-only) — plus a convenience lifecycle discriminator derived from them.

status

ValueDescription
pendingSubmitted, not yet confirmed by compliance.
verifiedConfirmed by compliance. verified_at is set.

Retirement timestamps

FieldSet onMeaning
archived_atpending rows onlyStamped when a subsequent POST /persons/{id}/claims for the same (person, claim_type) replaces this pending row.
superseded_atverified rows onlyStamped when compliance approves a newer pending and displaces this verified row as the authoritative value.
At most one row per (person, claim_type) is “current” for each status — the current pending (status=pending AND archived_at IS NULL) and the current verified (status=verified AND superseded_at IS NULL).

lifecycle

lifecycle is a convenience discriminator that tells you, in one field, where a claim sits.
ValueMeaning
activeThe most recent verified claim for its type — the currently authoritative value.
in_flightA pending claim waiting for compliance to verify it.
historicalA claim (pending or verified) that’s been replaced by a newer one. Kept for audit.

State transitions

pending ──▶ verified
FromToTrigger
(none)pendingPOST /persons or POST /persons/{person_id}/claims. The new row is in_flight. If a current pending for the same claim_type already exists, its archived_at is stamped in the same transaction and it becomes historical. Verified rows are not touched.
pendingverifiedCompliance review. If a prior active verified of the same type exists, its superseded_at is stamped in the same step and it becomes historical. Not self-service.
A person can have more than one claim of the same claim_type. The current value is the row whose lifecycle is active. Submitting a new claim of the same type archives the current pending (if any) atomically and inserts a fresh in_flight pending. That new row takes over as active once compliance verifies it — which also stamps superseded_at on the prior active row.

Updating a claim value

Post a new claim of the same type. Any current pending for that type is archived atomically (its archived_at is stamped; its status stays pending and it remains retrievable). The new row starts as pending with lifecycle: in_flight, and becomes the current active value once compliance verifies it.
curl -X POST https://api.engine.usesophic.com/persons/per_m4k7r9s2/claims \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "claim_type": "residence",
    "line1": "42 New Street",
    "postal_code": "EC2A 4RQ",
    "city": "London",
    "country_code": "GB"
  }'

Creating a claim

POST /persons/{person_id}/claims with the claim as the body. claim_type tells us which claim you’re sending.
import requests

response = requests.post(
    "https://api.engine.usesophic.com/persons/per_m4k7r9s2/claims",
    headers={
        "Authorization": "Bearer YOUR_ACCESS_TOKEN",
        "Content-Type": "application/json",
    },
    json={
        "claim_type": "pep_status",
        "is_pep": False,
        "has_pep_association": False,
    },
)
claim = response.json()
The response is the full claim:
{
  "id": "clm_abc123",
  "person": "per_m4k7r9s2",
  "created_at": "2026-04-18T09:30:00Z",
  "status": "pending",
  "lifecycle": "in_flight",
  "verified_at": null,
  "superseded_at": null,
  "archived_at": null,
  "claim_type": "pep_status",
  "is_pep": false,
  "has_pep_association": false,
  "pep_role": null,
  "pep_role_start_date": null,
  "pep_role_end_date": null,
  "pep_associate_name": null,
  "pep_associate_relationship": null
}
FieldDescription
idThe claim’s unique ID, prefix clm_.
personID of the person this claim belongs to.
created_atISO-8601 timestamp of when the claim was submitted.
statuspending or verified. See lifecycle.
lifecycleactive, in_flight, or historical. Derived per row — tells you whether this is the current value, the current pending update, or history. See lifecycle.
verified_atISO-8601 timestamp of verification, or null if still pending.
superseded_atISO-8601 timestamp stamped by compliance when a newer verified claim of the same type displaces this verified row. null while this is the current active verified. Only ever set on verified rows.
archived_atISO-8601 timestamp stamped when a subsequent POST /persons/{id}/claims for the same claim_type replaces this pending row. null while this is the current in_flight pending. Only ever set on pending rows.
claim_typeThe claim’s type. Determines which other fields are present.
other fieldsDepend on claim_type (e.g. is_pep, pep_role, …). See claim type reference.

Listing and retrieving claims

List a person’s claims, optionally filtered by type or status. By default the endpoint returns every row for the person — current and historical — newest-first by created_at (with id as a tiebreaker). This gives you an audit-ready view without a second request. Pass ?include_history=false to collapse to at most two rows per claim_type: the current active verified (if any) and the current in_flight pending (if any).
Breaking change. include_history previously defaulted to false (bare GET returned only current rows). It now defaults to true (bare GET returns full history). If you were relying on the old behavior, pass ?include_history=false explicitly.
curl "https://api.engine.usesophic.com/persons/per_m4k7r9s2/claims?claim_type=residence" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Query parameterValuesNotes
claim_typeAny claim_typeOptional.
statuspending, verifiedOptional. status=pending on the default view returns every pending (current + archived); status=verified returns every verified (current + superseded). Combine with include_history=false to get just the current pending or current verified per type.
include_historytrue, falseOptional, default true. Set to false to collapse to the current rows only (active + in_flight).
Retrieve a specific claim by ID via GET /persons/{person_id}/claims/{claim_id}. This always returns the exact claim you asked for — including archived pendings and superseded verifieds — with lifecycle on the response.
Claims can’t be deleted. To correct a pending submission — or update a previously verified one — post a new claim of the same type via POST /persons/{person_id}/claims. Any current pending for that type is archived automatically. See updating a claim value.

Claim type reference

Unknown fields are rejected. Dates are ISO-8601, country codes ISO-3166-1 alpha-2.
Most claim types are specific to natural or legal persons; contact_details is valid on both. Creating a claim whose claim_type isn’t valid for the target’s person_type returns 400 invalid_request (e.g. Claim type 'relationships' is not allowed on natural persons.). See claim creation errors.

Natural-person claims

Acceptable when person_type is natural.

identity

FieldTypeRequiredNotes
first_namestringyes
last_namestringyes
date_of_birthdateyesISO-8601.

nationalities

FieldTypeRequiredNotes
nationalitiesarray of objectsyesNon-empty.
Each nationalities entry:
FieldTypeRequiredNotes
country_codestringyesISO-3166-1 alpha-2.
basisenum | nullnoOne of birth, naturalisation, descent, marriage, investment_programme, other.

residence

FieldTypeRequiredNotes
line1stringyes
line2string | nullno
line3string | nullno
district_countystring | nullno
postal_codestringyes
citystringyes
country_codestringyesISO-3166-1 alpha-2.

tax_residencies

FieldTypeRequiredNotes
tax_residenciesarray of objectsyesNon-empty.
Each tax_residencies entry:
FieldTypeRequiredNotes
country_codestringyesISO-3166-1 alpha-2.
tinstring | nullnoTax identification number. Free-form string; we don’t validate format at the claim layer.
tin_exemption_reasonenum | nullnoOne of not_issued, pending_application, not_required.
Supply a tin or tin_exemption_reason for each tax residency. The claim layer accepts either, but an onboarding application is expected to carry a tin where available.

fatca_status

FieldTypeRequired
is_us_personbooleanyes

pep_status

FieldTypeRequiredNotes
is_pepbooleanyes
pep_rolestring | nullconditionalRequired when is_pep is true.
pep_role_start_datedate | nullconditionalRequired when is_pep is true.
pep_role_end_datedate | nullno
has_pep_associationbooleanyes
pep_associate_namestring | nullconditionalRequired when has_pep_association is true.
pep_associate_relationshipstring | nullconditionalRequired when has_pep_association is true.

education_level

FieldTypeRequiredValues
education_levelenumyesnone, secondary, bachelors, masters, doctorate, professional

employment

FieldTypeRequiredNotes
employment_statusenumyesemployed, self_employed, retired, student, unemployed.
industryenum | nullconditionalRequired when employment_status is employed or self_employed. See industry values.
industry_otherstring | nullconditionalRequired when industry is other.

financial_profile

FieldTypeRequiredNotes
annual_income_eurenumyesSee EUR amount bands.
income_sourcesarray of enumyesNon-empty. Values: salary, business_income, investments, pension, inheritance, other.
net_worth_eurenumyesSame bands as annual_income_eur.
wealth_sourcesarray of enumyesNon-empty. Values: savings, business_sale, investments, inheritance, property_sale, gift, other.

investment_experience

FieldTypeRequiredNotes
has_prior_experiencebooleanyes
asset_classesarray of enumconditionalNon-empty when has_prior_experience is true. Values: equities, bonds, funds, derivatives, crypto, other.

expected_activity

FieldTypeRequiredNotes
funding_currencystringyesISO-4217 code (EUR, USD, GBP…).
asset_classesarray of stringyesThe asset classes the customer expects to trade.
annual_transactionsstringyesBand value: 1_10, 11_20, 21_50, gt_50.
investment_amountstringyesSee EUR amount bands.

Shared claim types

Acceptable on both natural and legal persons.

contact_details

How to reach the person. Required on every POST /persons.
FieldTypeRequired
phone_numberstringyes
emailstring | nullno
Acceptable when person_type is legal.

registration

FieldTypeRequiredNotes
legal_namestringyes
trading_namestring | nullno
registration_numberstringyes
date_of_incorporationdateyes
country_of_incorporationstringyesISO-3166-1 alpha-2.
entity_typeenumyesprivate_limited_company, public_limited_company, partnership, llp, sole_proprietorship, trust, foundation, nonprofit, other.

lei

FieldTypeRequiredNotes
identifierstringyes20 alphanumeric characters. We normalise it to uppercase.
expiry_datedateyes

registered_address

The legal registration address.
FieldTypeRequiredNotes
line1stringyes
line2string | nullno
line3string | nullno
district_countystring | nullno
postal_codestringyes
citystringyes
country_codestringyesISO-3166-1 alpha-2.
operating_address_is_samebooleannoDefaults to false. Set true if the entity operates from its registered address — in that case the operating_address claim and proof_of_operating_address evidence aren’t required on an application.

operating_address

Where the business trades from. Same shape as residence. Send this claim only when the legal owner’s registered_address has operating_address_is_same set to false (the default). See conditional requirements.

business_nature

FieldTypeRequiredNotes
business_activityenumyesSee industry values.
business_activity_otherstring | nullconditionalRequired when business_activity is other.
annual_turnover_eurenumyesSee EUR amount bands.
is_regulatedbooleanyes
license_numberstring | nullno
issues_bearer_sharesbooleanyes
has_nominee_shareholdersbooleanyesWhen true, an onboarding application for this entity also needs a nominee_agreement evidence file attached to the legal owner. See conditional requirements.
has_shell_bank_relationshipsbooleanyes

relationships

Legal-person-only. Declares directors, shareholders, UBOs, trustees, settlors, and authorised signatories.
FieldTypeRequiredNotes
relationshipsarrayyesNon-empty. See entry fields below.
Each relationship entry:
FieldTypeRequiredNotes
related_personstringyesID of an existing person. Unknown IDs fail the request with 400.
relationship_typeenumyesdirector, shareholder, beneficial_owner, trustee, settlor, authorised_signatory.
control_typeenum | nullnoownership, voting, other.
ownership_percentagedecimal (string) | nullnoE.g. "25.50".
appointment_datedate | nullno
end_datedate | nullno
Different relationship_type values carry different onboarding requirements. director and authorised_signatory also need a board_resolution evidence file authorising them to act on the entity; the others don’t. See related-person requirements.

Reference values

EUR amount bands

ValueRange
lt_50kUnder €50,000
50k_100k€50,000 – €100,000
100k_250k€100,000 – €250,000
250k_500k€250,000 – €500,000
500k_1m€500,000 – €1,000,000
1m_3m€1,000,000 – €3,000,000
gt_3mOver €3,000,000

Industry values

agriculture, mining, manufacturing, utilities, construction, wholesale_retail, transport_logistics, hospitality, media_telecoms, technology, financial_services, insurance, real_estate, professional_services, education, healthcare, arts_entertainment, public_administration, defence, non_profit, gambling, extractives, precious_metals, cryptocurrency, other. Pair other with the _other text field on the same claim (employment.industry_other, business_nature.business_activity_other).