Skip to main content
A payout sends money from an account to a saved contact, which is a bank account or a wallet address. Save the contact with POST /dapi/v1/contacts, then book the payout with POST /dapi/v1/payouts. Who funds a payout depends on the paying account, and the response names it in authorization (Authorization). These routes take X-Hevn-Account to act for a client (Acting as a client).

Save a contact

Response 201, Location: /dapi/v1/contacts/ct_3K9…
The identifiers each method needs in bank.fields are in Rails. Field rules are on Create a contact. To edit, delete or list contacts, see Update a contact, Delete a contact and List saved contacts.

Check capabilities

Both calls are optional. POST /dapi/v1/payouts applies the same checks.

Book the payout

Call POST /dapi/v1/payouts with the contact and one amount.
Response 201, Location: /dapi/v1/payouts/po_4c8a…
The body fields and the response are on Create an outgoing transfer. To pay from the fiat balance, see Bank-held balance. The example is a payout for a client linked through HEVN Connect. Other paying accounts return another authorization and the fields that go with it.

Retries

Send an Idempotency-Key with each booking. Key format, replay windows and bookings without a key are in Idempotency-Key. A retry with the same key and terms returns the same po_… and quote. Until the payout is funded, a replay returns what the booking returned: an approval with debit or intent, authorization: "client" again (create a new sign session), or the same transfer with wallet. Once the payout is funded, a replay returns it with none of these. The rules for a changed request are on Create an outgoing transfer. A retry under the same key with another sourceAccount returns 409 idempotency_key_reused. Without a key, a request with another sourceAccount books a new payout.
Reuse the key when you retry. A new key books a second payout.

Authorization

authorization on the response names who funds the payout. Read it before status: each value returns awaitingSignature after booking. The values are defined in Authorization values. publicKey is required when your developer key signs. Without it the call returns 422 validation_failed with details.field = "publicKey". It is not used with client or wallet. A payout from the main wallet of a client that is not linked through HEVN Connect returns 403 account_not_controlled. A client created with POST /dapi/v1/clients pays from an external account. With authorization: "client", the holder approves the payout in a sign session of the sign-in window (Approve the payout).

Track it to completion

Read GET /dapi/v1/payouts/{payoutId}. A pollUrl points to this route (polling).
Response 200
The fields of the read, attention and transactionId among them, are on Retrieve an outgoing transfer.

Pay from your own account

Book without X-Hevn-Account, or with your cl_… in it, and add publicKey. To pay from a sub account, also send its acc_… id as sourceAccount.
Response 201, Location: /dapi/v1/payouts/po_7e1b…
Check debit and its operation (Debit contents), sign approval.payload and post the signature to POST /dapi/v1/payouts/{payoutId}/confirm (Signing, Authorize an outgoing transfer). Confirm outcomes are in Retrying a confirm.

Pay a wallet

A wallet contact uses the same payout body, authorization and read. The payout has kind: "onchain".

Save an address as a contact

chain takes a chain code. On a direct payout and on a payout to a HEVN account, amountTo equals amount. An amount with more decimals than the token returns 422 validation_failed.

A routed payout is priced

Routed payout, response 201
The ledger row of a settled wallet payout has isIncome: false and type: "crypto", or internal when the address belongs to another HEVN account (Walk the ledger).

Bank-held balance

Send "sourceAccount": "FDIC_USD" to pay from the balance the partner bank holds for the account. The wallet is not debited, and you sign the payout terms.
Response 201
Check quote and intent, then sign, confirm and poll as for any payout from your account. A client whose holder signs cannot pay from FDIC_USD: the call returns 409 payout_not_fundable with details.reason = "holder_signature_unsupported". The refusals are under sourceAccount on Create an outgoing transfer. To move the balance to your wallet, use Swaps.

When a payout is refused

POST /dapi/v1/payouts returns these codes. A 400 or 422 comes before booking, so the same key works for the corrected request. The other codes, among them 404 contact_not_found, 409 contact_not_payable and 422 contact_payment_details_invalid, are in Errors. To move a booked payout in the sandbox, see Move a payout.

Next: Swaps