Skip to main content
A customer is the top-level identity record in OMS. Every wallet belongs to a customer, and so does every transaction. No financial operation can happen without one.

Object

type is individual or business. name is an individual’s first, middle, and last names joined by spaces, or a business’s legal name (the companyLegalName you send on create or update). A business customer has no person-name fields. status tracks where the customer is in onboarding. Filter GET /customers by the same values. PII fields you send on create or update (birthDate, residentialAddress, ipAddress, identifyingInformation) are write-only. OMS accepts them but never returns them. A single-call GET /customers/{customerId} response also carries a totalBalance summary: totalUsd is fiatUsd + cryptoUsd to two decimals, covering fiat wallets and custodial crypto wallets. Non-custodial wallets are not yet valued, so a customer holding one reads an undercount. The field is omitted when the rollup cannot be read; treat an absent field as unknown rather than zero. The list, create, and update endpoints do not carry it. The wallets array is a simplified flat view, one entry per wallet-asset combination. Read the full wallet representation with GET /wallets/{id}/balance. See Wallets for the wallet resource.

Create a customer

POST /customers. Set type. An individual requires firstName and lastName; a business requires companyLegalName and email and does not accept person-name fields. Other fields are optional and can be added later with PATCH /customers/{customerId}.
Creation usually returns 201 with the customer. When creation outlasts the request, OMS returns 202 with the ID the customer will have and a Retry-After header:
The customer reads as 404 until creation finishes. Repeat the same request with the same Idempotency-Key to follow it: the repeat returns 202 while creation is still running and 201 with the customer once it is done. Create the customer record first, then collect the identifying fields for your KYC flow and submit them on create or with a later update. OMS handles compliance screening; your application handles identity collection. In sandbox, endorsements are auto-approved.

Endorsements

Endorsements track KYC and compliance status. Each unlocks a set of operations, and each carries its own status so you can see exactly where a customer stands. Request endorsements in the endorsements array on create or update. If you omit the array on create, OMS defaults to cryptoCustody and usd, which auto-includes basic. On update, listing endorsement names adds them and triggers re-evaluation; existing endorsements are never removed. Each endorsement in the response carries its type and a status from the same set as the customer status. Where relevant, it also carries a requirements object (fields that are complete, pending, missing, or have issues) and, when rejected, a failure. An endorsement never reads further along than its customer, and an endorsement that was not requested is left out. An endorsement must be active before its capability unlocks.

Balance

GET /customers/{id}/balance returns the customer’s estimated total balance aggregated across all of their wallets and assets. Pass estimatedBalanceCurrencyCode to value the aggregate in a currency other than USD.

Key operations

POST, PATCH, and DELETE requests accept an Idempotency-Key header. Use a stable key tied to your internal user ID to safely retry on network failure.

Webhook events

OMS emits customer.created, customer.statusChanged, and customer.updated for every change to a customer. The payload is the full customer in the shape above, so your handler can act on data.status, data.endorsements, and data.hold or data.failure without a follow-up read. See Customers in the webhook events catalog for when each event fires.