Skip to main content
A person (per_...) is a natural person (human) or legal person (company, trust, other entity). Persons are standalone until an onboarding application referencing them is approved. Every person is built from claims, typed data points capturing identity, residence, ownership, PEP status, and so on. Every POST /persons must include at least the mandatory claim set for its person_type:
person_typeMandatory claims
naturalidentity + contact_details
legalregistration + contact_details
Omitting any of these returns 400 invalid_request with detail <person_type> persons require claim types [...]; missing: [...]. You can include additional claims in the same request (and usually will, to round out the person’s profile). person_type determines which claim types are acceptable.
person_typeRepresentsExample claim types
naturalA humanidentity, contact_details, nationalities, residence, tax_residencies, pep_status, employment, financial_profile
legalA company, trust, partnership, or other legal entityregistration, contact_details, lei, registered_address, business_nature, relationships
operating_address is also a legal-person claim. You only add it when the legal owner’s registered_address has operating_address_is_same set to false; see conditional requirements. Legal persons declare counterparties (directors, shareholders, UBOs, trustees, signatories) via a relationships claim. Related persons must already exist. Claim types are enforced against person_type: mismatches on POST /persons or POST /persons/{person_id}/claims return 400 invalid_request. See the claim type reference.

Creating a person

POST /persons with person_type and a non-empty claims array. Creation is atomic: if any claim fails validation, nothing is persisted.
import requests

response = requests.post(
    "https://api.engine.usesophic.com/persons",
    headers={
        "Authorization": "Bearer YOUR_ACCESS_TOKEN",
        "Content-Type": "application/json",
    },
    json={
        "person_type": "natural",
        "claims": [
            {
                "claim_type": "identity",
                "first_name": "Ada",
                "last_name": "Lovelace",
                "date_of_birth": "1985-12-10",
            },
            {
                "claim_type": "contact_details",
                "phone_number": "+447700900123",
                "email": "ada@example.com",
            },
            {
                "claim_type": "residence",
                "line1": "1 Example Street",
                "postal_code": "SW1A 1AA",
                "city": "London",
                "country_code": "GB",
            },
        ],
    },
)
person = response.json()

Response

A successful request returns 201 Created:
{
  "id": "per_m4k7r9s2",
  "created_at": "2026-04-18T09:30:00Z",
  "modified_at": "2026-04-18T09:30:00Z",
  "person_type": "natural",
  "full_name": "Ada Lovelace",
  "claims": [
    {
      "id": "clm_abc123",
      "created_at": "2026-04-18T09:30:00Z",
      "status": "pending",
      "claim_type": "identity",
      "first_name": "Ada",
      "last_name": "Lovelace",
      "date_of_birth": "1985-12-10"
    },
    {
      "id": "clm_def456",
      "created_at": "2026-04-18T09:30:00Z",
      "status": "pending",
      "claim_type": "contact_details",
      "phone_number": "+447700900123",
      "email": "ada@example.com"
    },
    {
      "id": "clm_ghi789",
      "created_at": "2026-04-18T09:30:00Z",
      "status": "pending",
      "claim_type": "residence",
      "line1": "1 Example Street",
      "line2": null,
      "line3": null,
      "district_county": null,
      "postal_code": "SW1A 1AA",
      "city": "London",
      "country_code": "GB"
    }
  ]
}
FieldDescription
idThe person’s unique ID, prefix per_.
person_typenatural or legal.
full_nameNatural: "{first_name} {last_name}" from the identity claim. Legal: entity_name from registration, or empty.
claimsThe claims you provided. Each element carries id, created_at, status: pending, claim_type, and the fields defined for that claim_type. To get the full claim (with person, lifecycle, verified_at, superseded_at, archived_at) for a specific claim later, call GET /persons/{person_id}/claims/{claim_id}. See claim lifecycle.
Persons don’t have their own status; lifecycle lives on claims. See lifecycle.
POST /persons doesn’t de-duplicate retries. Record the returned id and reuse it on retries.

Retrieving a person

Use GET /persons/{id} to fetch the person record. Claims aren’t included; list them separately.
curl https://api.engine.usesophic.com/persons/per_m4k7r9s2 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Use GET /persons/{person_id}/claims to list the person’s claims, filtered by claim_type or status. By default you get every row for the person (current and historical) newest-first. Pass include_history=false to collapse to just the current rows (active + in_flight) per type. See listing and retrieving claims.
curl "https://api.engine.usesophic.com/persons/per_m4k7r9s2/claims?status=verified" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Authorities

When an application referencing a person is approved, that person becomes an authority on the resulting customer and accounts.
authority_typeMeaning
ownerThe primary owner of the customer.
joint_ownerA joint owner on a shared customer.
signatoryCan sign on behalf of the customer but doesn’t own it.
power_of_attorneyActs under a power of attorney arrangement.
tradingAuthorised to place trades on the customer’s accounts.
List authorities per person with GET /persons/{id}/authorities, or per customer with GET /customers/{id}/authorities. Create one person for the legal entity and one for every director, shareholder, UBO, trustee, settlor, or authorised signatory. Then add a relationships claim on the legal person.
{
  "person_type": "legal",
  "claims": [
    {
      "claim_type": "registration",
      "legal_name": "Ada & Co Ltd",
      "registration_number": "12345678",
      "date_of_incorporation": "2020-06-01",
      "country_of_incorporation": "GB",
      "entity_type": "private_limited_company"
    },
    {
      "claim_type": "relationships",
      "relationships": [
        {
          "related_person": "per_ada",
          "relationship_type": "director",
          "appointment_date": "2020-06-01"
        },
        {
          "related_person": "per_grace",
          "relationship_type": "shareholder",
          "ownership_percentage": "50.00"
        }
      ]
    }
  ]
}
Related persons must already exist; an unknown related_person ID fails the request with 400 and nothing is persisted. See claim types for the full relationships schema.