API Docs
Concepts

Payout lifecycle

The states a payout moves through, and which webhook events they emit.

Every payout moves through a small state machine. Each transition emits a webhook event named after it, with the payout as GET /payouts/{id} returns it in data.

created ──approve──▶ approved ──send-claim-link, then the claim──▶ requested ──▶ completed
                        │      ──pay────────────────────────────▶      │
                        │                                              └──▶ failed ──pay──▶ requested
                        └──▶ expired

States

StatusMeaningEvent
createdThe payout exists and waits for approval by the sending team.payout.created
approvedThe sending team approved the payout. The amount is reserved against the team balance. The payout waits for the next step: a claim link and the recipient's claim, or pay. approvedAt says when.payout.approved
requestedThe transfer was requested from the payment provider, by the recipient's claim or by POST /payouts/{id}/pay.payout.requested
completedThe transfer settled. Terminal.payout.completed
failedThe provider rejected the transfer. failureCode and failureReason say why. Fix the counterparty, then call pay again.payout.failed
expiredThe payout expired unclaimed. Terminal. While a payout is created or approved, expiresAt says when this happens.payout.expired

The happy path is created → approved → requested → completed. status is an open enum: treat a value you do not know as a fallback case.

Retrying a failed payout

failed is the status that asks the sender to act. A push payout to a counterparty you entered that the provider returns becomes failed as soon as the return is processed. The payout keeps its approval, so no second approval is needed. Correct the counterparty with PATCH /counterparties/{id} and call POST /payouts/{id}/pay again; the payout returns to requested, and payout.completed or another payout.failed follows.

A claimed payout that the provider returns does not become failed, because the recipient owns the payment details. Talentir parks the funds for them and sends them a retry link where they re-claim with fresh details. From your side the payout reads completed once the funds are parked, since your obligation is settled.

Notes

  • PATCH /payouts/{id} is allowed only while the status is created. A locked payout refuses PATCH altogether.
  • DELETE /payouts/{id} is allowed while the status is created, approved, failed, or expired. A requested or completed payout cannot be deleted (409 PAYOUT_NOT_DELETABLE). A deleted payout is gone from the API: every endpoint answers 404 PAYOUT_NOT_FOUND for it, and lists do not include it. The payout.deleted event carries what DELETE returns: { object, id, deleted: true }.
  • availableOn delays the claim and the payment, not creation: the payout exists immediately but cannot be claimed or paid before that UTC day.
  • A counterparty change (PATCH /counterparties/{id} on the address, payment method, or tax identity) moves every approved payout to that counterparty back to created, because the sender now pays a different destination. Each such payout emits payout.updated.
  • From requested on, paymentMethod names the rail and settlement currency, and recipientInvoiceSource says who wrote the document behind recipientInvoiceUrl: self_billing (Talentir issued it in the recipient's name) or recipient_upload (the recipient uploaded their own invoice while claiming).