Skip to content

Everything that has happened to your payouts, in order.

GET

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.

Query parameters

  • sincestringOptional

    Return events after this sequence. Omit it on the first call (or send 0) to start from the first row; afterwards feed back the page's nextSince.

  • payoutIdstringOptional

    Everything that ever happened to one payout.

  • typestringOptional

    Comma-separated event types to include. Each must be a known type (see PayoutEventType); an unknown one is a 400 VALIDATION_ERROR, never an empty page.

  • limitintegerOptionalDefaults to 100

    Maximum events to return, from 1 to 500. Defaults to 100.

Behavior

Reconcile from this feed. Each event is written once and never changes, carries its own id, and sequence is a total order you cursor on, so "page forward from where I left off" is expressible, which listing payouts cannot do: that is ordered by creation and can never surface a change to one you have already read.

payout.returned is its own type rather than a flavour of payout.failed, because a bank returning a settled payment days later is the one event that reverses something you already booked.

At-least-once: dedupe on id. And the cursor is sequence, not a timestamp: timestamps tie, and a tie is indistinguishable from a boundary.

The row is the webhook body. data is the same object a delivery carries, so the amounts, fee, rate, your reference and endUserId are here, so you can book from the feed alone. id is the delivery's svix-id, so a webhook is the trigger to read GET /events?since= from the right place.

Every family is here, type-discriminated: payout.*, payout_batch.* (with batchId set and payoutId null), payout_approval.*, webhook_endpoint.* and checkout_payment.* (whose data is the checkout payment: fee is a decimal string and there is no payoutId). A reconciler that wants only payouts passes type=; otherwise skip types it does not recognize.

An event becomes readable about two seconds after it happens. That lag is what makes since safe against a write that commits out of order.

Responses

200Events, oldest first.

Body

  • dataarray of objectRequired
    Show 11 properties
    • idstringRequired

      Stable. Dedupe on this, because the feed is at-least-once. Equals the webhook svix-id.

    • sequencestringRequired

      The cursor, as a decimal string. A 64-bit sequence past 2^53 is not representable as a JSON number, and silently losing precision on a cursor is unrecoverable.

    • typestringRequired

      Every event the feed and the webhooks can carry. New types are added without a major version. Ignore ones you do not handle, and return 2xx for them on a webhook.

      Allowed values:payout.pendingpayout.processingpayout.completedpayout.failed
      Show 19 more valuespayout.returnedpayout.canceledpayout_batch.awaiting_confirmationpayout_batch.completedpayout_batch.canceledpayout_batch.failedpayout_approval.pendingpayout_approval.approvedpayout_approval.rejectedpayout_approval.expiredpayout_approval.executedpayout_approval.execution_failedwebhook_endpoint.disabledcheckout_payment.paidcheckout_payment.failedcheckout_payment.refundedcheckout_payment.reversedcheckout_payment.partially_refundeddeposit.completed
    • payoutIdstring | nullRequired

      The payout this event is about. Also set on payout_approval.executed, naming the payout the approval became, so ?payoutId= returns that event too. Null on the other batch, approval, endpoint and checkout events; a checkout payment is identified by data.paymentId.

    • batchIdstring | nullRequired

      Set on payout_batch.* rows and on a batch approval.

    • statusstringRequired

      The resource's status after this transition, a payout status on payout.*, a batch status on payout_batch.*, an approval status on payout_approval.*.

    • failureCodestringOptional

      New codes may be added; treat an unknown one as execution_failed.

      Allowed values:quote_expiredinsufficient_fundslimit_exceededaccount_invalid
      Show 6 more valuesaccount_cannot_receivecompliance_rejectedauthorization_not_completedreturned_by_bankexecution_failedunknown
    • fundsReturnedbooleanOptional
    • createdAtstring<date-time>Required
    • apiVersionintegerRequired

      The data shape version. Same value as the Avvio-Webhook-Version header on a delivery.

    • dataone ofRequired

      The body, built once when the event was recorded and never rebuilt. Discriminate on the row's type: payout.* carries a WebhookPayout, payout_batch.* a PayoutBatch, payout_approval.* a PayoutApprovalEvent, webhook_endpoint.* a WebhookEndpointDisabled, checkout_payment.* a WebhookCheckoutPayment, documented in the Checkout spec (partner-checkout.openapi.yaml), not in this file.

      Show one of 4 shapes
      WebhookPayout

      The payout inside a webhook body has a different shape from Payout. Here the amounts are flat decimal strings beside separate currency fields; on the REST surface they are Money objects. Code written against the wrong one throws on the first delivery, which is why they are two schemas rather than one.

      • payoutIdstringOptional
      • statusstringOptional

        A payout moves only along these transitions:

        More
        pending    -> processing | completed | failed | canceled
        processing -> completed | failed
        completed  -> failed                  (returned by the recipient's bank)
        
        • pending: accepted, reserved, not sent. The only cancelable state.
        • processing: handed to the payment network. Committed.
        • completed: the recipient was paid. Not absolutely final.
        • failed: not paid, or paid and then returned. Branch on failureCode.
        • canceled: you ended it before it was sent. It is not a failure, so it carries no failureCode; fundsReturned is true because the money never left.

        completed can still become failed. A receiving bank can return a payment days after settlement, giving failureCode: returned_by_bank and fundsReturned: true. Do not write a ledger that treats completed as immutable, and keep processing webhooks for a payout after it completes.

        Allowed values:pendingprocessingcompletedfailed
        Show 1 more valuecanceled
      • requiresFundingbooleanOptional

        Present and true when this payout is waiting on you to fund it from your own wallet, right now. pending alone cannot tell you this. On a routing that settles from a held balance the same word means the network is working on it.

        More

        This is the delivery that matters for a hosted payout link: the worker fills in their details, the payout is created, and you are the only party who can release it. Absent once the funds are on their way, and absent entirely on routings where it cannot happen.

      • stagestringOptional
      • failureCodestringOptional

        New codes may be added; treat an unknown one as execution_failed.

        Allowed values:quote_expiredinsufficient_fundslimit_exceededaccount_invalid
        Show 6 more valuesaccount_cannot_receivecompliance_rejectedauthorization_not_completedreturned_by_bankexecution_failedunknown
      • fundsReturnedbooleanOptional
      • referencestring | nullOptional

        Your own reference, echoed on every delivery. This is the field a ledger joins on.

      • sourceCurrencystring | nullOptional
      • sourceAmountstring | nullOptional
      • destinationCurrencystring | nullOptional
      • destinationAmountstring | nullOptional
      • destinationAccountIdstring | nullOptional
      • ratestring | nullOptional

        Same value and precision as Payout.rate (destinationAmount / sourceAmount, six decimal places), not the pre-fee market rate from GET /rates.

      • feeobject | nullOptional

        The rail's fee for this payout, enough to book the movement from the delivery alone. Null until the rail reports one. currency falls back to sourceCurrency when the rail did not name one.

        Show 2 properties
        • currencystringRequired
        • amountstringRequired

          Decimal string, as the rail reported it.

      • endUserobject | nullOptional

        Your own customer this payout is sent for: the party sending through your platform, never the recipient. In payroll the employer is the end user and the worker is the recipient; omit the object when you are the sender yourself. Attribution and the per-end-user daily cap key on id; it is not forwarded to the payment network and does not change the sender of record, which stays your organization. Echoed on the payout and in every webhook, so a support question is answerable without your own id map.

        Show 3 properties
        • idstringOptional

          Your stable identifier for the sending customer (not the recipient).

        • namestringOptional

          Person's display or legal name.

        • emailstring<email>Optional

          Person's email address in standard email format.

      • endUserIdstring | nullOptional

        Your id for the end user this payout was for, the same value as endUser.id. Null when you sent none.

      • createdAtstring<date-time>Optional
      • completedAtstring<date-time> | nullOptional
      PayoutBatch
      • batchIdstringRequired
      • externalReferenceIdstring | nullRequired

        Your own run id, echoed back.

      • statusstringRequired

        A batch moves received -> validating -> either creating (autoCommit, zero errors) or awaiting_confirmation (anything else) -> creating -> completed. canceled is reachable until creation starts; failed means the run broke, not a line. The batch tracks creation; payouts settle on their own lifecycle afterwards.

        Allowed values:receivedvalidatingawaiting_confirmationcreating
        Show 3 more valuescompletedcanceledfailed
      • autoCommitbooleanRequired
      • countsobjectRequired

        Lines by status. The values sum to the number of lines submitted.

        Show 8 properties
        • receivedintegerRequired
        • invalidintegerRequired
        • validatedintegerRequired
        • creatingintegerRequired
        • createdintegerRequired
        • create_failedintegerRequired
        • canceledintegerRequired
        • requires_reviewintegerRequired
      • estimatedSourceTotalstring | nullRequired

        Advisory. What the valid lines will draw from your balance, set when validation finishes; null while validation is running and when any line locks the destination side (no rate is consulted at validation time). Compare against GET /balance before confirming. Half a paid payroll is worse than none.

      • errorobjectOptional

        Present only when status is failed, with the run-level reason.

      • createdAtstring<date-time>Required
      • updatedAtstring<date-time>Required
      • completedAtstring<date-time> | nullRequired
      PayoutApprovalEvent

      The data of a payout_approval.* event.

      • approvalobjectRequired

        One request for M-of-N human approval of an API payout or a batch run. Not a payout status: the payout does not exist until this executes.

        Show 14 properties
        • idstringRequired
        • kindstringRequired
          Allowed values:payoutpayout_batch
        • statusstringRequired

          The lifecycle of an approval, a pre-payout resource. executing and execution_unknown are visible on the resource but emit no event.

          Allowed values:pendingapprovedrejectedexpired
          Show 4 more valuesexecutingexecutedexecution_failedexecution_unknown
        • requiredApprovalsintegerRequired

          M, snapshotted when the request was created.

        • approvalsintegerRequired

          Approve votes so far.

        • payoutIdstringOptional

          Present once a payout approval is executed, naming the payout it became.

        • batchIdstringOptional

          Present on payout_batch approvals.

        • amountstring | nullRequired

          Source-currency amount; for a batch, the run's estimated total.

        • currencystring | nullRequired
        • destinationAccountIdstringOptional
        • errorobject | nullOptional

          Present on execution_failed and execution_unknown: why the approved payout could not be sent, or why its outcome is unknown.

          Show 2 properties
          • codestringOptional

            The error type the send answered with, when there was one (PAYOUT_OUTCOME_UNKNOWN on execution_unknown).

          • messagestringRequired
        • createdAtstring<date-time>Required
        • expiresAtstring<date-time> | nullRequired

          A pending request expires 24 hours after creation.

        • updatedAtstring<date-time>Required
      • payoutIdstringOptional

        On payout_approval.executed, the payout the approval became.

      WebhookEndpointDisabled

      The data of webhook_endpoint.disabled, delivered to your other endpoints that subscribe to every type (an empty events list).

      • endpointIdstringRequired
      • urlstring<uri>Required
      • reasonstringRequired
      • consecutiveFailuresintegerRequired
      • lastSuccessAtstring<date-time> | nullRequired
      • disabledAtstring<date-time>Required
  • hasMorebooleanRequired
  • nextSincestring | nullOptional

Errors

  • 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 call. Nothing ran.

    • FORBIDDEN: the key belongs to a different organization.
    • ACCOUNT_BLOCKED: API access for your organization is suspended, and every key is refused until we lift it. Contact support.
  • 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.

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 · Events · operation listEvents

Try it: List events

GET https://api.avvio.xyz/business/api/v1/payments/organizations/{orgId}/events

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?