List your sub-clients
Registry rows, newest first, each carrying its own `totalHeldUsd` and `lastActivityAt` (#109 MR B). Money held for a sub-client is money you ADMINISTER — it is never part of your own balances, and no aggregate ACROSS sub-clients is returned here.
Registry rows, newest first, each carrying its own totalHeldUsd and lastActivityAt (#109 MR B). Money held for a sub-client is money you ADMINISTER — it is never part of your own balances, and no aggregate ACROSS sub-clients is returned here.
Authorization
bearer In: header
Query Parameters
The nextCursor from the previous page. Omit it for the first page. Treat it as opaque.
Rows per page, 1-100. Defaults to 25.
value <= 10025Defaults to returning both.
Value in
- "ACTIVE"
- "CLOSED"
Return only the sub-client carrying this identifier of yours.
Case-insensitive search across legal name, external ref and email.
ISO 3166-1 alpha-2. Matches the derivation reported as the row country.
Filter to one sub-client kind.
Value in
- "person"
- "business"
Header Parameters
Act on behalf of one of your sub-clients. The value is that sub-client id, and the request then reads and writes that sub-client's own accounts and registry rows rather than yours. Omit it to act as yourself. A route that does not accept the header refuses it with 400 ON_BEHALF_OF_NOT_ALLOWED_HERE rather than ignoring it — that includes every vault route (deposits, withdrawals, conversions, sub-accounts, positions), the webhook registry, and POST /sub-clients, since a sub-client never has sub-clients of its own. An id that is not one of your sub-clients answers 404 ON_BEHALF_OF_NOT_FOUND; a closed one answers 409 ON_BEHALF_OF_SUB_CLIENT_CLOSED; and a key restricted to a subset of your sub-clients answers 403 ON_BEHALF_OF_NOT_ALLOWED_FOR_KEY for any node outside it.
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/api/partner/v1/sub-clients?cursor=f39b0c74-51ae-4d82-9b06-3c7e2a5d1f80&limit=25&externalRef=acme%3Acust-04231&q=khalifa&country=BH"{ "data": { "items": [ { "accounts": [ { "accountId": "7e2a0c53-4d81-49b6-8f37-1a5c9e0b2d74", "balance": { "available": "1000.00", "reserved": "0.00", "total": "1000.00" }, "capabilities": { "holdCrypto": true, "holdSavings": false, "receive": true, "sendCrypto": true, "sendExternal": false, "sendInternal": true }, "createdAt": "2026-08-14T08:42:11.000Z", "currency": "EUR", "disclosure": { "items": [ "ENVIRONMENT_IS_TESTNET: The environment is a testnet (Arbitrum Sepolia). No mainnet deployment exists.", "YIELD_IS_SIMULATED: The vault rate is set administratively and the interest it produces is minted as fresh underlying, not earned. It does not represent a return generated by deployed capital.", "FIAT_RAILS_ARE_MOCKED: No real fiat movement occurs. Balances are ledger entries against a sandbox provider.", "CONVERSION_RATES_ARE_MARKET_QUOTED_OR_REFUSED: A conversion is priced only by an external venue that quotes independently of TCB. When no such venue can price the pair, the conversion is refused rather than priced from an internal table. Read rate.pricingModel on every conversion: MARKET is a venue quote; any other value is not a market rate and must not be presented as one.", "CONTRACTS_ARE_UNAUDITED: No audit has been performed. Mainnet is gated on a two-firm audit that has not been commissioned.", "CUSTODY_IS_TCB_SUBACCOUNT: Everything held for the client — its vault shares, and the tcbUSD it holds between the steps of the tokenised deposit chain — is held in TCB custody, in the one TCB wallet assigned to the client. The client holds no keys and moves those tokens only through this API; each sub-account's shares and tcbUSD are book entries against what that wallet holds.", "INTEGRATION_AGREEMENT_ONLY: Fees as published on the rate card; no yield share, no return commitment." ], "summary": "This is a pilot integration on a testnet. Nothing in this system earns anything: the yield is simulated and the fiat rails are mocked.", "version": "2026-10-27" }, "externalRef": "acme:payroll-eur", "iban": { "active": false, "bic": "TCBKBHBMXXX", "holderName": "Fatima Al-Khalifa", "iban": "BH29TCBK00001234567890" }, "label": "Payroll reserve", "localRails": [ { "active": false, "bankAddress": "Wiesenstrasse 17, 8952 Schlieren, Switzerland", "bankName": "InCore Bank AG", "beneficiaryName": "Fatima Al-Khalifa", "bic": "INCOCHZZ", "currency": "EUR", "iban": "CH0508799123456789012", "paymentReference": "TCB-7K2M9QXA", "rail": "SEPA / SEPA Instant" } ], "ownerId": "c4f81e2a-9b60-4d37-a512-8e0f3c6b7d95", "ownerType": "SUB_CLIENT", "role": "MAIN", "status": "ACTIVE" } ], "caps": { "USD": { "daily": "50000", "perTransfer": "10000" } }, "country": "BH", "createdAt": "2026-08-14T08:42:11.000Z", "cryptoAccounts": [ { "accountId": "3b9e2f71-0c4d-4a58-9e16-7d2c5a8f1b40", "address": "0x5c1f0a2b3d4e5f60718293a4b5c6d7e8f9012345", "balances": [ { "asset": "USDC", "balance": "250.5" } ], "chain": "ARBITRUM", "status": "ACTIVE" } ], "disclosure": { "items": [ "ENVIRONMENT_IS_TESTNET: The environment is a testnet (Arbitrum Sepolia). No mainnet deployment exists.", "YIELD_IS_SIMULATED: The vault rate is set administratively and the interest it produces is minted as fresh underlying, not earned. It does not represent a return generated by deployed capital.", "FIAT_RAILS_ARE_MOCKED: No real fiat movement occurs. Balances are ledger entries against a sandbox provider.", "CONVERSION_RATES_ARE_MARKET_QUOTED_OR_REFUSED: A conversion is priced only by an external venue that quotes independently of TCB. When no such venue can price the pair, the conversion is refused rather than priced from an internal table. Read rate.pricingModel on every conversion: MARKET is a venue quote; any other value is not a market rate and must not be presented as one.", "CONTRACTS_ARE_UNAUDITED: No audit has been performed. Mainnet is gated on a two-firm audit that has not been commissioned.", "CUSTODY_IS_TCB_SUBACCOUNT: Everything held for the client — its vault shares, and the tcbUSD it holds between the steps of the tokenised deposit chain — is held in TCB custody, in the one TCB wallet assigned to the client. The client holds no keys and moves those tokens only through this API; each sub-account's shares and tcbUSD are book entries against what that wallet holds.", "INTEGRATION_AGREEMENT_ONLY: Fees as published on the rate card; no yield share, no return commitment." ], "summary": "This is a pilot integration on a testnet. Nothing in this system earns anything: the yield is simulated and the fiat rails are mocked.", "version": "2026-10-27" }, "externalRef": "acme:cust-04231", "kind": "person", "lastActivityAt": "2026-09-20T14:12:00.000Z", "legalName": "Fatima Al-Khalifa", "status": "ACTIVE", "subClientId": "c4f81e2a-9b60-4d37-a512-8e0f3c6b7d95", "totalHeldUsd": "1250.00", "updatedAt": "2026-08-28T09:00:00.000Z", "verification": { "attestedAt": "2026-08-28T09:00:00.000Z", "capabilities": { "holdCrypto": true, "holdSavings": false, "receive": true, "sendCrypto": true, "sendExternal": false, "sendInternal": true }, "level": "RELIANCE", "requirements": { "currentlyDue": [ "identity.person.dateOfBirth", "attestation", "screening" ], "disabledReason": null, "eventuallyDue": [], "pastDue": [] }, "status": "VERIFIED", "verifiedAt": "2026-08-28T09:00:00.000Z" } } ], "nextCursor": "c4f81e2a-9b60-4d37-a512-8e0f3c6b7d95" }, "success": true, "timestamp": "2026-09-02T10:15:30.000Z"}Register a sub-account POST
Creates a named partition of your omnibus position. A sub-account is a partition of YOUR book: it confers no wallet, no key and no allowlist entry, and every share still sits in the one sub-account wallet TCB custodies for you. Use the returned subAccountId on deposits and withdrawals to attribute them; omit it and they land in your default sub-account.
Create a sub-client POST
Creates a sub-client and, atomically, reserves one MAIN account per requested currency. Every one of them receives on the sub-client's IBAN, which carries its own legal name as the payee name, and each also carries local details for its currency where the currency has them. Nothing is live yet: every capability is false and the details are inactive until the sub-client is VERIFIED — it must not be given out, is not entered into verification of payee, and accepts no funds. `identity` and `attestation` are both optional on this call: omitting either leaves the sub-client REQUIREMENTS_DUE, which names what is still outstanding, rather than rejecting the call. Cannot be called under x-on-behalf-of — a sub-client never has sub-clients.