# Docs

- API v2: Current version
  - [Introduction](/docs/v2): Pay creators, sellers, and freelancers worldwide from your own product.
  - [Quickstart](/docs/v2/quickstart): Send your first payout from the sandbox in a few minutes.
  - Authentication
    - [Team API keys](/docs/v2/authentication/api-keys): Authenticate server-to-server calls with a key scoped to your own team.
    - [OAuth 2.1 with PKCE](/docs/v2/authentication/oauth): Let your customers connect their Talentir teams to your platform.
  - Guides
    - [Pay with a payout link](/docs/v2/guides/pay-with-payout-link): Create a payout for an email address and let the recipient claim it on a Talentir-hosted page.
    - [Pay directly](/docs/v2/guides/pay-directly): Save the people and companies you pay as counterparties, then push payouts to their bank account, PayPal, or crypto wallet without a claim link.
    - [Approve payouts](/docs/v2/guides/approve-payouts): Move a payout from created to approved in the dashboard, on a hosted screen, or through the API.
    - [Pay on behalf of your customers](/docs/v2/guides/platform-integrations): Connect your customers' Talentir teams through OAuth, walk them through verification and funding, and create their first payout from your product.
    - [Set up webhooks](/docs/v2/guides/webhooks): Receive real-time notifications for payout, counterparty, and transaction events.
    - [Migrate from v1 to v2](/docs/v2/guides/migrate-to-v2): What changes between /api/v1 and /api/v2, and how to move an integration step by step.
  - Concepts
    - [Payout lifecycle](/docs/v2/concepts/payout-lifecycle): The states a payout moves through, and which webhook events they emit.
    - [Transactions](/docs/v2/concepts/transactions): Every movement on your accounts, how they add up to the balance, and the event they emit.
    - [Scopes and permissions](/docs/v2/concepts/scopes-and-permissions): What each API scope grants, and which are restricted.
    - [Idempotency](/docs/v2/concepts/idempotency): Retry any POST safely with an Idempotency-Key, and name payouts with a customId.
    - [Errors and retries](/docs/v2/concepts/errors-and-retries): The error format, common error codes, and how to retry safely.
  - API reference
    - Payouts
      - [List payouts](/docs/v2/reference/payouts/payouts.list): Newest first by `createdAt`, `id` as tie-breaker. Needs `payouts:read`.
      - [Create a payout](/docs/v2/reference/payouts/payouts.create): Creates a payout in status `created`. `andThen` runs approval, and then `send-claim-link` or `pay`, in the same request and fails with their codes. Needs `payouts:write`, plus `payouts:approve` when `andThen` is set.
      - [Create payouts in one request](/docs/v2/reference/payouts/payouts.createBatch): Creates up to 100 payouts. Each item is a `POST /payouts` body, `andThen` included. All or nothing: one failing item fails the request with that item's code and `error.index`, and nothing is applied. Needs `payouts:write`, plus `payouts:approve` when any item sets `andThen`.
      - [Get a payout](/docs/v2/reference/payouts/payouts.get): `{id}` is the payout id or your `customId`. Needs `payouts:read`.
      - [Update a payout](/docs/v2/reference/payouts/payouts.update): Allowed while `status` is `created`. An omitted field is unchanged; `recipient` is replaced as a whole. Needs `payouts:write`.
      - [Delete a payout](/docs/v2/reference/payouts/payouts.delete): Allowed while `status` is `created`, `approved`, or `expired`. A `failed` payout cannot be deleted: its money waits for `pay`. A deleted payout is gone from the API: every endpoint answers 404 `PAYOUT_NOT_FOUND` for it, and lists do not include it. Its `customId` stays taken. Needs `payouts:write`.
      - [Approve a payout](/docs/v2/reference/payouts/payouts.approve): Moves `created` to `approved` and reserves the amount against the team balance. The body is optional. Needs `payouts:approve`, plus `payouts:write` with `andThen: "pay"`.
      - [Send the claim link](/docs/v2/reference/payouts/payouts.sendClaimLink): Talentir emails the claim link to the recipient and sets `recipientNotifications` to `enabled`. One reminder follows 7 days after the latest claim-link email; calling it again resends the email and moves a reminder that has not gone out yet. A locked payout with `recipientNotifications: "disabled"` fails with `PAYOUT_LOCKED`. Needs `payouts:write`.
      - [Pay a counterparty directly](/docs/v2/reference/payouts/payouts.pay): Sends the money to the counterparty's saved payment method. Settlement is asynchronous; `payout.completed` or `payout.failed` follows. A `failed` payout is paid again with the same call. Needs `payouts:write`, plus `payouts:approve` for a `failed` payout: it goes to the counterparty's current payment method, which the approval did not cover.
      - [Approve payouts in one request](/docs/v2/reference/payouts/payouts.approveBatch): Approves up to 100 payouts and reserves their sum against the team balance in one decision. `andThen` runs `send-claim-link` or `pay` for every payout. All or nothing: one failing item fails the request with that item's code and `error.index`, and nothing is applied. Needs `payouts:approve`, plus `payouts:write` with `andThen: "pay"`.
      - [Send claim links in one request](/docs/v2/reference/payouts/payouts.sendClaimLinkBatch): Emails the claim link for up to 100 payouts. Every payout is checked before the first email goes out. All or nothing: one failing item fails the request with that item's code and `error.index`, and nothing is applied. Needs `payouts:write`.
      - [Pay counterparties in one request](/docs/v2/reference/payouts/payouts.payBatch): Requests the transfer for up to 100 counterparty payouts. Every payout moves to `requested` in one transaction; settlement follows per payout as `payout.completed` or `payout.failed`. All or nothing: one failing item fails the request with that item's code and `error.index`, and nothing is applied. Needs `payouts:write`, plus `payouts:approve` when any payout is `failed`.
    - Counterparties
      - [List counterparties](/docs/v2/reference/counterparties/counterparties.list): Newest first by `createdAt`, `id` as tie-breaker. A recipient-managed row that a team-managed row overrides (same email) is not listed. Needs `counterparties:read`.
      - [Create a counterparty](/docs/v2/reference/counterparties/counterparties.create): `taxIdentity` is checked against the rules of [`GET /countries`](https://www.talentir.com/docs/v2/reference/countries/countries.list) for the address country and the identity type. Without `paymentMethod` and `taxIdentity` the counterparty exists, and `missing` names what a direct payment still needs. Needs `counterparties:write`.

> **Warning:** Talentir can change the tax rules, the settlement currencies, and the payout assets at any time, without prior notice. Do not hardcode them. Read the tax fields from [`GET /countries`](https://www.talentir.com/docs/v2/reference/countries/countries.list) and the currencies and assets from [`GET /payment-method-types`](https://www.talentir.com/docs/v2/reference/payment-method-types/payment-method-types.list) when you build the form.
      - [Get a counterparty](/docs/v2/reference/counterparties/counterparties.get): `{id}` is the counterparty id or your `customId`. Needs `counterparties:read`.
      - [Update a counterparty](/docs/v2/reference/counterparties/counterparties.update): An omitted field is unchanged; a nested object is replaced as a whole and `null` clears it. A change to the address, payment method, or tax data moves every `approved` payout to this counterparty back to `created`. Needs `counterparties:write`.
      - [Delete a counterparty](/docs/v2/reference/counterparties/counterparties.delete): Refused while a payout to it is `created`, `approved`, `requested`, or `failed`. A deleted counterparty is gone from the API: every endpoint answers 404 `COUNTERPARTY_NOT_FOUND` for it, and its `customId` is free again. Payouts to it keep its id in `recipient.counterpartyId`. Needs `counterparties:write`.
    - Countries
      - [List countries](/docs/v2/reference/countries/countries.list): Every country a counterparty can live in, with the tax data it needs. Ordered by `id`. Never paged. Needs `counterparties:read` or `counterparties:write`.
    - Payment method types
      - [List payment method types](/docs/v2/reference/payment-method-types/payment-method-types.list): Every payment method type a counterparty can save, with the currencies or assets it settles in right now. Currencies and assets may be added or removed without a new API version, so build your form from this list. Never paged. Needs `counterparties:read` or `counterparties:write`.
    - Webhooks
      - [List webhooks](/docs/v2/reference/webhooks/webhooks.list): Only v2 subscriptions. Newest first. Needs `webhooks:read`.
      - [Create a webhook](/docs/v2/reference/webhooks/webhooks.create): Subscribes a URL to events. The response carries the signing `secret` once. A subscription created here receives v2 bodies. Needs `webhooks:write`, plus `payouts:read` to receive payout events, `counterparties:read` to receive counterparty events, and `transactions:read` to receive transaction events. The webhook receives events only while the credential that created or last updated it can read them.
      - [Get a webhook](/docs/v2/reference/webhooks/webhooks.get): Needs `webhooks:read`.
      - [Update a webhook](/docs/v2/reference/webhooks/webhooks.update): An omitted field is unchanged. Needs `webhooks:write`, plus the read scopes of the events the webhook then receives: `payouts:read` for payout events, `counterparties:read` for counterparty events, `transactions:read` for transaction events. The caller's credential becomes the webhook's credential.
      - [Delete a webhook](/docs/v2/reference/webhooks/webhooks.delete): Needs `webhooks:write`.
      - [Rotate the signing secret](/docs/v2/reference/webhooks/webhooks.rotateSecret): Replaces the secret. The response carries the new `secret` once. For 24 hours, deliveries carry a signature with the old secret and one with the new, so you can deploy the new secret without dropping events. Needs `webhooks:write`.
      - [Send a test event](/docs/v2/reference/webhooks/webhooks.test): Sends a `webhook.ping` event, with the webhook as `data`, and returns the delivery. Needs `webhooks:write`.
      - [List deliveries](/docs/v2/reference/webhooks/webhooks.listDeliveries): Recent delivery attempts, newest first. Needs `webhooks:read`.
    - Sessions
      - [Create a session](/docs/v2/reference/sessions/sessions.create): Mints a signed Talentir URL for a hosted screen. `type` selects the screen and its audience. A session has no `GET`; the id is embedded in the URL. Needs `sessions:write`.
    - Team
      - [Get the team](/docs/v2/reference/team/team.get): Returns the authenticated team. Needs `team:read`.
      - [List accounts](/docs/v2/reference/team/team.listAccounts): One account per settlement currency, with its balance and deposit instructions. Never paged. Needs `team:read`.
      - [List team members](/docs/v2/reference/team/team.listMembers): Owners first, then by `joinedAt`. Needs `team:read`.
      - [Deposit test money](/docs/v2/reference/team/team.sandboxDeposit): Sandbox only. Adds `amount` to the balance of the account, as a bank deposit would, and returns the account. Outside the sandbox the request fails with `SANDBOX_ONLY`. The team needs a wallet first; without one the request fails with `VERIFICATION_REQUIRED`. Needs no scope.
    - Transactions
      - [List transactions](/docs/v2/reference/transactions/transactions.list): Every movement on the team's accounts, newest first by `createdAt`, `id` as tie-breaker. Needs `transactions:read`.
      - [Get a transaction](/docs/v2/reference/transactions/transactions.get): Needs `transactions:read`.
- API v1: Previous version
  - [Introduction](/docs/v1): Integrate with the Talentir platform to pay creators, sellers, and freelancers worldwide.
  - [Quickstart](/docs/v1/quickstart): Send your first payout from the sandbox in a few minutes.
  - Authentication
    - [Team API keys](/docs/v1/authentication/api-keys): Authenticate server-to-server calls with a key scoped to your own team.
    - [OAuth 2.1 with PKCE](/docs/v1/authentication/oauth): Let your customers connect their Talentir teams to your platform.
  - Guides
    - [Create a payout](/docs/v1/guides/create-a-payout): Send a payment to a creator identified by handle, email, or wallet address.
    - [Create hosted sessions](/docs/v1/guides/hosted-sessions): Mint Talentir-hosted URLs for claiming, approval, KYB, and allowance flows.
    - [Approve and execute payouts](/docs/v1/guides/approve-and-execute-payouts): Move payouts from pending to paid, with a human or programmatic approval step.
    - [Set up webhooks](/docs/v1/guides/webhooks): Receive real-time notifications for payout lifecycle events.
  - Concepts
    - [Payout lifecycle](/docs/v1/concepts/payout-lifecycle): The states a payout moves through, and which webhook events they emit.
    - [Scopes and permissions](/docs/v1/concepts/scopes-and-permissions): What each API scope grants, and which are restricted.
    - [Idempotency](/docs/v1/concepts/idempotency): Retry payout creation safely with customId upserts.
    - [Errors and retries](/docs/v1/concepts/errors-and-retries): The error format, common error codes, and how to retry safely.
    - [Breaking changes](/docs/v1/concepts/breaking-changes): Scheduled removals and deprecated fields.
  - API reference
    - Payouts
      - [Create](/docs/v1/reference/payouts/payout.create): Create or update a new payout for team members.

For teams with balance enforcement enabled (the default), pre-approved payouts (`preApproved: true`) are rejected with HTTP 422 and error code `INSUFFICIENT_BALANCE` when the total of all open (approved but not yet paid out) payouts would exceed the team wallet balance. The error `data` contains `walletBalance`, `totalOpenAmount`, and `currency`.
      - [Get](/docs/v1/reference/payouts/payout.get): Retrieve a specific payout by ID or custom ID.

By default, the endpoint expects an ID. To query by custom ID instead, add the query parameter `id_type=custom_id`.

Examples:
- Get by ID: `GET /payout/{id}`
- Get by custom ID: `GET /payout/{custom_id}?id_type=custom_id`
      - [Delete](/docs/v1/reference/payouts/payout.delete): Delete a payout that has not been requested yet.

Only payouts with status `created`, `approved` or `expired` can be deleted. Once the recipient has requested the payout (status `requested`) or it is `completed`, the request fails with HTTP 409. Deleting an already deleted payout succeeds and returns it unchanged. A deleted payout emits a webhook event with status `deleted`.

By default, the endpoint expects an ID. To delete by custom ID instead, add the query parameter `id_type=custom_id`.

Examples:
- Delete by ID: `DELETE /payout/{id}`
- Delete by custom ID: `DELETE /payout/{custom_id}?id_type=custom_id`
      - [List](/docs/v1/reference/payouts/payout.list): Retrieve a list of payouts for the authenticated team.
    - Sessions
      - [Payout](/docs/v1/reference/sessions/session.payout): Audience: the payout RECIPIENT — the creator/rightsholder being paid, who is not a member of the authenticated team. Validate a payout for the authenticated team and return a Talentir URL to send to that recipient: they sign in or sign up with their own email (inferred from the payout) and claim the payout. No team membership is required.
      - [Approval](/docs/v1/reference/sessions/session.approval): Audience: a MEMBER OF THE AUTHENTICATED TEAM (the team the token authorizes — with OAuth this can be a customer's team, not your own). Validate pending payouts for that team and return a Talentir URL where a team member reviews and approves them. The screen requires the visitor to sign in and be a member of that team; the sign-in code is pre-sent to the session creator's email.
      - [Kyb](/docs/v1/reference/sessions/session.kyb): Audience: a MEMBER OF THE AUTHENTICATED TEAM (the team the token authorizes — with OAuth this can be a customer's team, not your own). Validate the authenticated team and return a Talentir URL where a team member completes KYB (Know Your Business) verification. The screen requires the visitor to sign in and be a member of that team; the sign-in code is pre-sent to the session creator's email.
      - [Allowance](/docs/v1/reference/sessions/session.allowance): Audience: the OWNER of the authenticated team (the team the token authorizes — with OAuth this can be a customer's team, not your own). Returns a Talentir URL where the team owner sets or edits the daily spending allowance for automatic payouts. The screen requires the visitor to sign in and be the team owner; the sign-in code is pre-sent to the session creator's email.
    - Team Management
      - [Get](/docs/v1/reference/team-management/team.get): Retrieve information for the authenticated team: name, KYB status, total converted wallet balance, balances, bank deposit instructions per currency, and the team's members with their roles (owners first). The per-balance 'depositInfo' field is deprecated in favor of the top-level 'deposits' array and will be removed on 2026-09-23.
    - Webhooks
      - [List](/docs/v1/reference/webhooks/webhook.list): List all webhooks for your team. Webhooks are per environment: a webhook registered on the sandbox only fires for sandbox events, one registered on production only fires for production events.
      - [Create](/docs/v1/reference/webhooks/webhook.create): Create a new webhook to receive event notifications. Webhooks live in the environment they were created in: register on sandbox.talentir.com to receive sandbox events, and on www.talentir.com to receive production events.
      - [Delete](/docs/v1/reference/webhooks/webhook.delete): Delete a webhook