Skip to content

Register who is being paid.

POST

Path parameters

  • orgIdstringRequired

    The opaque organization id issued to you, normally CUID-shaped (for example cmsx…). It is not an org_-prefixed alias. Pass it unchanged in every organization-scoped path.

Headers

  • Idempotency-KeystringRequired

    A unique value per logical operation, 1-255 chars of A-Z a-z 0-9 _ . : -.

    More

    Reuse it to retry. Same key with the same body replays the stored response; same key with a different body is a 409, because answering with the first call's result would hand you a receipt for a payout you did not request. A 4xx releases the key, so you can fix the body and reuse it.

    Reuse it; do not generate one per attempt. A key minted per attempt defeats replay entirely: every retry looks like a new request, so every retry pays. We also watch for an identical body arriving under a different key within 15 minutes and refuse it with DUPLICATE_REQUEST_DETECTED.

    Records are kept for 7 days. That is a retention window only: there is no path where an expired key is re-executed.

Body

This endpoint expects a JSON object.

  • typestringRequired

    Whether the recipient is a person or a business.

    Allowed values:individualbusiness
  • namestringRequired

    Recipient legal or commonly used name.

  • emailstring<email>Optional

    Optional. A contact address kept on the recipient for your own records and returned on reads; it plays no part in routing the payout. Omit it and the recipient is stored with email: null. When sent, it must be a valid email address.

  • phonestringOptional

    Optional phone number as text, including any international prefix.

  • countrystringOptional

    ISO-3166 alpha-2.

  • externalIdstringOptional

    Your id for this recipient. Sending it makes creation repeat-safe: the same value returns the existing recipient rather than registering a second bank account.

  • endUserIdstringOptional

    Your id for the person sending. Scopes the recipient to them. Omit it and the recipient is visible to every one of your users.

  • methodone ofRequired
    Show one of 2 shapes
    Fiat bank destination
    • kindstringRequired

      Send the literal string fiat for a bank destination.

    • currencystringRequired

      ISO 4217 payout currency. Matching is case-insensitive.

    • railstringOptional

      Optional. The corridor's payout rail. Omit it and the corridor's default rail is used, which is what almost every integration wants. It has no example, so a generated request does not carry one.

    • recipientDetailsobjectRequired

      The selected corridor's fields, keyed exactly by field id. Values are normally strings; nested objects are accepted where the field definition represents a structured address. Fields in the bank_address group (the recipient's own postal address, on corridors that require one) may be sent flat or nested under bank_address.

    Cryptocurrency destination
    • kindstringRequired

      Send the literal string crypto for a wallet destination.

    • addressstringRequired

      Valid EVM, Solana, or Bitcoin address. Leading and trailing whitespace is ignored.

Behavior

method.recipientDetails carries the corridor's fields, exactly as named by GET /corridors.

Two separate protections, and they do different jobs: Idempotency-Key makes a retry safe; externalId makes a repeat safe by returning the existing recipient instead of registering a second bank account. Send both. The repeat only matches when the account details are the same: an externalId you already used with a different account is 409 BENEFICIARY_EXTERNAL_ID_CONFLICT, and a second account needs a second externalId.

A recipient refused by screening is 422 PAYOUT_REFUSED. The recipient is still stored, blocked, and every payout to it is refused the same way; a repeat with the same externalId returns it with 201. Do not retry the registration.

Responses

201Created, or the existing recipient for this externalId

Body · BeneficiaryRegistration

  • idstringOptional
  • namestringOptional
  • emailstring | nullOptional

    The contact address you supplied, or null when none was sent.

  • countrystring | nullOptional

    ISO 3166-1 alpha-2. Null when none was stored (crypto recipients).

  • externalIdstring | nullOptional

    Your id for the recipient, or null when none was sent.

  • endUserIdstring | nullOptional
  • typestringOptional
    Allowed values:individualbusiness
  • phonestring | nullOptional
  • screeningStatusstring | nullOptional

    Internal compliance state. Returned today but not part of the contract, and it will be removed. Do not read it.

  • screeningReasonstring | nullOptional

    Internal compliance state. Returned today but not part of the contract, and it will be removed. Do not read it.

  • screenedAtstring<date-time> | nullOptional

    Internal compliance state. Returned today but not part of the contract, and it will be removed. Do not read it.

  • deletedAtstring<date-time> | nullOptional

    Always null on a read (deleted recipients are not returned). It will be removed.

  • createdAtstring<date-time>Optional
  • updatedAtstring<date-time>Optional
  • organizationIdstringOptional

    The organization id you authenticate with, the same one you put in the URL, for test and live keys alike.

  • paymentMethodsarray of objectOptional
    Show 10 properties
    • idstringOptional
    • kindstringOptional
      Allowed values:fiatcrypto
    • currencystring | nullOptional
    • last4string | nullOptional
    • statusstringOptional
      Allowed values:activependingfailed
    • destinationAccountIdstring | nullOptional

      Pass this as destinationAccountId when pricing a payout.

    • addressstring | nullOptional

      Crypto methods only. The destination wallet address.

    • chainstring | nullOptional

      Crypto methods only. The network the address is on.

    • labelstring | nullOptional
    • railstring | nullOptional

      An internal routing label. Returned today but not part of the contract, and it will be removed. Do not read it.

  • methodobjectOptional

    The payment method this call registered, or on a repeat the one it matched. Keep method.destinationAccountId. Absent only if the call could not name a single method; then read the recipient again rather than choosing one.

    Show 6 properties
    • idstringOptional
    • kindstringOptional
    • currencystring | nullOptional
    • last4string | nullOptional
    • statusstringOptional
    • destinationAccountIdstring | nullOptional

Errors

  • 400

    Validation failed, or a corridor field is missing

  • 401

    The key was refused. Nothing ran.

    • UNAUTHORIZED: missing, invalid or revoked, or a key on a route that does not accept one.
    • KEY_EXPIRED: the key passed the expiry it was issued with. Issue a new one; an expired key cannot be rotated.
    • KEY_IP_NOT_ALLOWED: the key is pinned to source addresses and this request came from another.
  • 403

    A valid key that may not make this write. Nothing was changed.

    • FORBIDDEN: the key belongs to a different organization.
    • ACCOUNT_BLOCKED: API access for your organization is suspended.
    • LIVE_KEY_ORG_NOT_APPROVED: a live key, before we have approved your business verification. Use a test key until then.
    • INSUFFICIENT_SCOPE: a read-only key. Issue one with the write scope.
  • 409

    BANK_ACCOUNT_ALREADY_LINKED: this bank account is already saved on another recipient (existingRecipientId, existingMethodId). BENEFICIARY_EXTERNAL_ID_CONFLICT: this externalId already names a recipient with different account details; nothing was changed. Or an idempotency conflict (IDEMPOTENCY_KEY_CONFLICT, IDEMPOTENCY_KEY_REQUEST_IN_PROGRESS).

  • 422

    PAYOUT_REFUSED: this payout cannot be sent to this recipient. Nothing was sent. Do not retry; contact us with the requestId if you believe it is wrong. The response never says why.

  • 429

    Too many requests. The default ceiling is 100 requests per minute per API credential on a 60-second window. High-volume payout and reconciliation routes declare a 600/minute override, and batch submission a 30/minute ceiling. A separate 2,000/minute per-source-IP abuse ceiling always applies.

    Obey Retry-After; it is in seconds and is authoritative. A 429 means the request was refused before the handler ran. Retry reads normally; retry an idempotent mutation with its same Idempotency-Key.

  • 503

    Provider registration is temporarily unavailable; retry safely.

Error body · Error
  • typestringRequired

    Stable machine-readable code.

  • detailstringRequired

    What went wrong, in a sentence. Always a string, so detail.toLowerCase() is safe.

    More

    This is the field to read on BAD_REQUEST and PROVIDER_REJECTED, where the type alone does not name the condition.

  • messagestringRequired

    The same text as detail, kept for integrations written before detail existed. Read detail.

  • resolutionstringOptional

    What to do about it, when there is a specific answer. It is not on every error (it is absent on BAD_REQUEST, NOT_FOUND, PAYOUT_NOT_CANCELABLE and DESTINATION_ACCOUNT_NOT_FOUND), so treat it as optional and fall back to detail.

  • statusintegerRequired

    HTTP status, repeated in the body.

  • statusCodeintegerRequired

    The same value as status, kept for integrations written before status existed. Read status.

  • requestIdstringRequired

    Quote this to support and we can find the exact request. Also sent as the x-request-id response header, which is the only place it appears on a successful response. Success bodies do not carry it. Send your own x-request-id on the request and we use it, so your trace and ours share one identifier; otherwise we mint one.

  • errorsarray of stringOptional

    Present on VALIDATION_ERROR; names each field that failed.

  • originalIdempotencyKeystringOptional

    On DUPLICATE_REQUEST_DETECTED only. Send the request again with this to receive the original payout instead of making a second one. Without it there is no way to recover except by risking a double payment.

  • originalPayoutIdstringOptional

    On DUPLICATE_REQUEST_DETECTED only. The payout the first request created.

  • originalBatchIdstringOptional

    On a batch DUPLICATE_REQUEST_DETECTED. The run the first request created.

  • originalRequestIdstringOptional

    On a 409 PAYOUT_OUTCOME_UNKNOWN replay. The requestId of the call whose outcome is unknown; quote it to support.

  • existingRecipientIdstringOptional

    On BANK_ACCOUNT_ALREADY_LINKED. The recipient in your organization that already holds this account.

  • existingMethodIdstringOptional

    On BANK_ACCOUNT_ALREADY_LINKED. The payment method on that recipient.

Branch on type, never on the status or the message. Every error type is listed with what to do about it.

Avvio Partner Payouts · Recipients · operation createBeneficiary

Try it: Create a recipient

POST https://api.avvio.xyz/business/api/v1/recipients/{orgId}

Test keys only. Sent as x-api-key through this site's proxy to the Avvio API, never saved, and cleared when you close this dialog.

Was this page helpful?