accountId. Send that id in the Kash-Account header on every call you make for the user.
All routes on this page need a partner key with the partner:accounts scope. They name the account in the path, so they refuse a Kash-Account header with 400 ACCOUNT_HEADER_NOT_ALLOWED.
Before you create an account
- Consent. Create an account only after the user has agreed in your app, for example by tapping a button. That action is their consent to the API acting on the trade and withdrawal instructions you send for them. Send when they agreed and which terms they saw.
- Country. Send the user’s real country. Kash’s country rules, including the block on sanctioned countries, apply to it at trade and withdrawal time. Account creation itself does not refuse by country. Update it with
PATCHif it changes. - Destination. Register the user’s own address in your app. Every withdrawal goes there and nowhere else.
Create an account
Unknown fields are refused with
400 VALIDATION_FAILED.
The answer is 202 Accepted. The account starts in provisioning, with no deposit address yet:
account) and under data. Read either.
When the wallet is ready you receive the account.active webhook with the depositAddress. You can also poll GET /v1/partner/accounts/{accountId} until status is active.
Creating the same account twice
- Same
Idempotency-Key(a retry of the same request): the stored202is returned unchanged, with the headerIdempotent-Replay: true. Nothing runs again. - Different
Idempotency-Key, sameexternalId: the existing account is returned with200and_meta.idempotent: true. The body you sent is not applied to it: to change its destination or country, usePATCH. - After a release the
externalIdis free again. Creating it makes a new account with a newaccountId.
Account statuses
An account that is
provisioning or provisioning_failed has no wallet, so calls that read the account’s wallet (balance, portfolio, positions, trades) are refused with 409 ACCOUNT_NOT_ACTIVE until it is active.
When provisioning fails
You receiveaccount.provisioning_failed with a reason:
Release the account and create it again, which gives it a new
accountId. If it recurs, contact ZeroID support with the accountId.
Read and find accounts
GET /v1/partner/accounts returns { data: Account[], pagination: { cursor, hasMore, limit }, _meta }, newest first, with cursor pagination. limit is 1 to 100, default 20. externalId is an exact match and returns an empty page when you have no account for that id. Released accounts are not listed.
An account id that is unknown, malformed, released or another organisation’s is answered with the same 404 ACCOUNT_NOT_FOUND, so ids cannot be probed.
Change the destination or country
destination, country or both. The answer is 200 with the account. It works in any status except released.
- Sending the destination the account already has changes nothing, does not restart the hold and sends no webhook.
- A country change takes effect for the next trade and withdrawal. It sends no webhook.
- A destination change answers
503 ROUTE_DISABLEDwhen account changes are switched off, and503 DEPENDENCY_UNAVAILABLEwhen that switch cannot be read. Nothing changed; retry.
Suspend and reactivate
- Suspend moves an
activeaccount tosuspended. Trades and withdrawals are refused until you reactivate it. The account keeps its funds, can still be read and released, and can still redeem winnings. - Reactivate moves a
suspendedaccount back toactive. - Asking for the status the account already has answers
200with_meta.idempotent: trueand changes nothing. - Any other status answers
409 ACCOUNT_NOT_ACTIVE, and thedetailnames the status. Aprovisioningorprovisioning_failedaccount can be neither suspended nor reactivated.
Account resource
Next
Funding and balance
Fund the deposit address and read what is available.
Webhooks
Account, withdrawal, payout and trade events.