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
{
"id": "cst_...",
"object": "customer",
"type": "individual",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@example.com",
"phone": "+12125551234",
"nationality": "US",
"externalId": "usr_12345",
"status": "active",
"signedAgreement": true,
"signedAgreementAt": "2026-03-20T14:15:22Z",
"wallets": [
{
"id": "wlt_...",
"type": "custodial",
"address": "0x7B3a...D9b1",
"network": "polygon",
"asset": "usdc",
"balance": "1234.56",
"estimatedValueUsd": "1234.56"
}
],
"endorsements": [
{ "name": "basic", "status": "ACTIVE" },
{ "name": "cryptoCustody", "status": "ACTIVE" },
{ "name": "usd", "status": "PENDING" }
],
"createdAt": "2026-01-15T10:30:00Z",
"updatedAt": "2026-01-15T10:30:00Z"
}
type is individual, the only type supported today. status is active or inactive; an inactive customer cannot create new transactions. There are no intermediate customer states: all compliance granularity lives in the endorsement statuses.
PII fields you send on create or update (birthDate, residentialAddress, ipAddress, identifyingInformation) are write-only. OMS accepts them but never returns them.
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. The only required field is type; everything else is optional and can be added later with PATCH /customers/{customerId}.
{
"type": "individual",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@example.com",
"phone": "+12125551234",
"nationality": "US",
"birthDate": "1990-05-15",
"residentialAddress": {
"line1": "123 Main St",
"city": "New York",
"state": "NY",
"country": "US",
"zipCode": "10001"
},
"identifyingInformation": [
{ "type": "ssn", "issuingCountry": "US", "number": "123456789" }
],
"endorsements": ["cryptoCustody", "usd"]
}
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.
| Endorsement | Unlocks |
|---|
basic | Baseline identity checks. Auto-included whenever another endorsement is requested. |
cryptoCustody | Custodial stablecoin wallets. |
usd | USD fiat rails, including bank and cash payouts. |
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 a status, and where relevant a requirements object (fields that are complete, pending, missing, or have issues) and rejectionReasons.
| Endorsement status | Meaning |
|---|
INACTIVE | Not yet requested or not started. |
PENDING | Under compliance review. |
ISSUES | Requires attention; see requirements.issues. |
ACTIVE | Approved and usable. |
REJECTED | Denied; see rejectionReasons. |
REVOKED_ISSUES | Previously active, now revoked pending resolution. |
OFFBOARDED | Terminated. |
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.
{
"data": {
"customerId": "cst_...",
"estimatedBalanceValue": "1234.56",
"estimatedBalanceCurrencyCode": "USD",
"updatedAt": "2026-01-15T10:30:00Z"
}
}
Key operations
| Operation | Endpoint |
|---|
| Create a customer | POST /customers |
| List customers | GET /customers |
| Retrieve a customer | GET /customers/{customerId} |
| Update a customer | PATCH /customers/{customerId} |
| Delete a customer | DELETE /customers/{customerId} |
| Get aggregated balance | GET /customers/{id}/balance |
| List wallets | GET /customers/{id}/wallets |
| Create a wallet | POST /customers/{id}/wallets |
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.