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. To create and verify a customer step by step, follow the customer onboarding guide. This page is the reference for the customer resource.

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; its response returns companyLegalName and the company facts you sent, such as legalEntityType, registrationCountry, and incorporationAddress. PII fields you send on create or update (birthDate, residentialAddress, ipAddress, identifyingInformation, and a business’s businessTaxId) are write-only. OMS accepts them but never returns them. A business response reports hasBusinessTaxId instead. A single-customer GET /customers/{customerId} response also carries a totalBalance summary: totalUsd is fiatUsd + cryptoUsd to two decimals, covering fiat wallets and custodial crypto wallets. fiatUsd can be negative after an ACH clawback, so render the sign as received. Non-custodial wallets are not yet valued, so a customer holding one reads an undercount. totalBalance.updatedAt is when the custodial wallet provider last updated the crypto balances; it is omitted when the provider reports no timestamp, for example when the customer holds no custodial crypto wallet. The whole field is omitted when the rollup cannot be read, so treat an absent field as unknown rather than zero. The list, create, and update endpoints do not carry it. List a customer’s wallets with GET /wallets?customerId={customerId}. See Wallets for the wallet resource.

Statuses

status tracks where the customer is in onboarding. Filter GET /customers by the same values.

Create request

POST /customers requires type. An individual requires firstName and lastName; a business requires companyLegalName and email and does not accept person-name fields. Other fields are optional in the schema, but your project’s verification policy decides what a create must carry (see below). Whether a customer is verified, and whether OMS relies on your own verification or verifies the customer itself, is configured per project, separately for individuals (KYC) and businesses (KYB). It is not a per-request choice.

Required fields when your project requires KYC

On a project that requires KYC for individuals and provisions custodial wallets, an individual create must include all of the following: Addresses in New York (NY), Texas (TX), and Vermont (VT) are not supported on these projects. See Supported jurisdictions.
endorsements and metadata appear in the create schema but are not yet supported on POST /customers. A request that sends either is rejected. Omit both; OMS requests the default endorsements for you (see Endorsements).

Create responses

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, and onboarding continues asynchronously after that. 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.

Validation errors

An invalid field returns 400 with error code 2001 (invalid argument). The cause field names the specific field and reason; read it before you retry. Fields the schema does not define are ignored without an error, so a misspelled field name is silently dropped rather than rejected. Every response carries a Request-Id header; include it when you contact support. In sandbox, avoid the word “test” in customer names and email addresses. Fraud checks run on sandbox customers too, and these values can be flagged.

Updating a customer

PATCH /customers/{customerId} adds or changes fields. identifyingInformation entries are appended, and signedAgreement can only move from false to true. Changes to residentialAddress, lastName, identifyingInformation, or ipAddress trigger re-evaluation of the customer’s endorsements. DELETE /customers/{customerId} is a soft delete: the customer moves to offboarded.

Endorsements

Endorsements track what a customer is cleared for. Each unlocks a set of operations and carries its own status, so you can see exactly where a customer stands. OMS requests cryptoCustody and usd (which includes basic) for every new customer. 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 listing 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: for example, a quote that moves funds through a custodial wallet returns 403 KYCRequired when the customer’s cryptoCustody endorsement is not active.

Business onboarding

A business customer is onboarded with the people behind the company: its beneficial owners, controllers, directors, signatories, and representatives. Business onboarding must be enabled for your project.
  • Beneficiaries: POST and GET /customers/{customerId}/beneficiaries, and GET, PUT, and DELETE /customers/{customerId}/beneficiaries/{beneficiaryId}. Each beneficiary requires roles (beneficialOwner, controller, director, signatory, or representative). birthDate, taxId, and identificationNumber are write-only; reads report hasBirthDate, hasTaxId, and hasIdentificationNumber.
  • Onboardings: POST and GET /customers/{customerId}/onboardings, and GET /customers/{customerId}/onboardings/{onboardingId}. The request names one to five beneficiaryIds and a partnerAttestation (id, provider, attestedAt) recording the business verification you performed.
An onboarding starts pending and ends active or rejected, with a failureCode of rejected or processingFailed when it does not succeed. The customer’s status follows it: pending while the onboarding runs and rejected if it is rejected. Both POST requests accept an Idempotency-Key header, so you can retry them safely. Beneficiaries are versioned. PUT takes the current version and a full input: non-sensitive fields you omit are cleared, while write-only identifiers you omit keep their values and an empty string clears them. DELETE takes the current version as a query parameter.

Key operations

GET /customers filters by status, email, externalId, createdAfter, and createdBefore, and pages with limit and cursor. A status-filtered page can hold fewer than limit rows while hasMore is still true, so keep paging until hasMore is false.
POST requests require an Idempotency-Key header. Use a stable key tied to your internal user ID so a retry after a network failure cannot create a second customer.

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. A new customer is first announced as pending, then moved by customer.statusChanged. See Customers in the webhook events catalog for when each event fires.