API Docs
Concepts

Payment requests

Ask a client to pay your team, issue the invoice, and see what paid it.

A payment request asks a payer to pay your team. Talentir issues the invoice in your team's name, gives the payer a page with the bank transfer instructions, and matches the incoming transfer to the request. Manage requests with the /payment-requests endpoints. Reading needs payment-requests:read. Creating, updating, finalizing, sending, cancelling, and deleting need payment-requests:write.

Payment request IDs have the form payment_request_<uuid>. Wherever a path takes {id}, your customId works in its place.

Before you start

Your team can request payments when it:

  • is a business, not an individual account;
  • has completed business verification (KYB);
  • has a complete registered address in the EU, Switzerland, the United Kingdom, the United States, or Hong Kong;
  • has a VAT number, when its country has VAT.

Otherwise POST /payment-requests fails with 422 PAYMENT_REQUESTS_UNAVAILABLE, and details.missing names every missing step. A currency your team cannot receive bank transfers in fails with 422 CURRENCY_NOT_RECEIVABLE, and details.currency names it.

Lifecycle

Every request goes through the same steps, whoever the payer is:

  1. Create a draft. Nothing reaches the payer, and no invoice is issued.
  2. Finalize it. The request becomes open. A counterparty payer gets the invoice now; an email payer gets it when they enter their billing details.
  3. Send it, or deliver paymentUrl yourself.
  4. The payer pays by bank transfer. Talentir matches the deposit and the request becomes paid.

andThen on create runs steps 2 and 3 in the same request, so a request to a counterparty with an email takes one call.

Address the request to a counterparty or to an email address:

Counterparty payerEmail payer
You knowThe payer's billing detailsOnly the payer's email
InvoiceIssued on finalizeIssued when the payer enters their billing details on paymentUrl
sendEmails paymentUrl with the invoice PDF attachedEmails paymentUrl; Talentir emails the invoice once it is issued

1. Create the draft

For a counterparty payer, the counterparty needs identity and a complete address; it does not need a paymentMethod. Create it with POST /counterparties, as in Pay directly. The invoice shows the VAT number from taxIdentity.vatNumber. Add an email if Talentir is to email the invoice.

curl -X POST "$BASE_URL/payment-requests" \
  -H "Authorization: Bearer $TALENTIR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "customId": "INV-2026-042",
    "description": "Campaign management, October",
    "amount": "1000.00",
    "currency": "EUR",
    "payer": { "type": "counterparty", "counterpartyId": "counterparty_7c1d2f30-…" },
    "tags": ["october"]
  }'

counterpartyId takes the ID or your customId. For a payer you know only by email, send "payer": { "type": "email", "email": "billing@example.com" } instead.

The response is the request in status draft, with invoice: null and paymentUrl: null. The payer cannot see a draft. amountDue equals amount, because the VAT is only known once the invoice is issued:

{
  "object": "payment_request",
  "id": "payment_request_0e4ba886-…",
  "customId": "INV-2026-042",
  "status": "draft",
  "amount": "1000.00",
  "amountDue": "1000.00",
  "payer": { "type": "counterparty", "counterpartyId": "counterparty_7c1d2f30-…" },
  "paymentUrl": null,
  "invoice": null,
  "tags": ["october"],
  "sentAt": null,
  "…": "…"
}

A counterparty without a complete address fails with 422 COUNTERPARTY_NOT_INVOICEABLE, and details.missing names address. No request is created. For the payer's name, read the counterparty with GET /counterparties/{id}.

While the request is a draft, PATCH /payment-requests/{id} can change its customId, description, amount, currency, payer, and tags. DELETE /payment-requests/{id} removes a draft; a finalized request is cancelled instead.

To skip the next steps, add "andThen": "finalize" or "andThen": "finalize_and_send" to the body. The response then shows the request as open, with the invoice for a counterparty payer. The create and the finalize are all or nothing: when the finalize fails, no request is created. The email of finalize_and_send goes out after that. If the email fails, the create still succeeds with sentAt: null, and send tries again.

2. Finalize

curl -X POST "$BASE_URL/payment-requests/payment_request_0e4ba886-…/finalize" \
  -H "Authorization: Bearer $TALENTIR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

finalize moves the draft to open and sets paymentUrl. After that, only tags can change, and the request cannot be deleted. Talentir emails nothing.

  • For a counterparty payer, Talentir issues the invoice before it responds. The response carries it in invoice, with the PDF at invoice.url and the VAT in amountDue.
  • For an email payer, invoice stays null. The payer enters their billing address and their VAT number on paymentUrl. Talentir then saves the payer as a counterparty of your team, or reuses the counterparty with the same email, issues the invoice, and emails it to the payer. payer turns into a counterparty payer.

A request that is not a draft fails with 409 PAYMENT_REQUEST_NOT_FINALIZABLE.

3. Send

Nothing has reached the payer yet. Deliver the PDF from invoice.url yourself, or give the payer paymentUrl, which shows the invoice and the bank transfer instructions. You do not need to call send.

To have Talentir email the payer, call send:

curl -X POST "$BASE_URL/payment-requests/payment_request_0e4ba886-…/send" \
  -H "Authorization: Bearer $TALENTIR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

Talentir emails paymentUrl to the payer and sets sentAt. A draft is finalized first. What the email says depends on whether the invoice exists at that moment:

  • With an invoice, the email is the invoice: the subject names the invoice number, the text states amountDue with VAT, and the PDF is attached.
  • Without one, the email is a payment request for amount before VAT, with no attachment. The invoice follows in a separate email once the payer enters their billing details. One reminder follows a week later, unless the payer announced a transfer or started a payout. Calling send again resends the email. Payment is due on receipt.

The email goes to the counterparty's email or to the email payer. A counterparty without an email fails with 422 PAYER_EMAIL_MISSING. A paid or cancelled request fails with 409 PAYMENT_REQUEST_NOT_SENDABLE.

4. Cancel

curl -X POST "$BASE_URL/payment-requests/payment_request_0e4ba886-…/cancel" \
  -H "Authorization: Bearer $TALENTIR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

cancel moves the request to cancelled. paymentUrl then tells the payer that the request is cancelled.

  • A request with an invoice gets a credit note that cancels the invoice in full. The PDF is at invoice.creditNote.url. Talentir emails the credit note only when it emailed the request with send. Otherwise, deliver the credit note yourself, as you did the invoice.
  • A request without an invoice gets no credit note, and Talentir sends no email.

A paid or cancelled request fails with 409 PAYMENT_REQUEST_NOT_CANCELLABLE. A draft can also be deleted with DELETE /payment-requests/{id}; then it is gone from the API, and its customId is free again.

Statuses

StatusMeaning
draftCreated and not finalized yet. The payer cannot see it, and nothing can pay it. Only a draft can be updated with PATCH or deleted.
openFinalized and waits for payment.
paidThe completed settlements cover amountDue. If a settlement stops being completed, the request moves back to open.
cancelledYour team cancelled the request.

status is an open enum: treat a value you do not know as a fallback case. The timestamps tell you more about an open request: sentAt (the last email to the payer), firstViewedAt (the payer opened paymentUrl), and transferAnnouncedAt (the payer said that their transfer is on its way).

customId and tags

customId is your own key for the request, such as the number in your own invoice series. It works in place of the id in every path. A second request with the same customId fails with 409 CUSTOM_ID_TAKEN, and details.id names the request that holds it. A deleted request frees its customId. The format is the one of customId on payouts.

tags are your labels for the request. They can change in every status: a PATCH with only tags works on an open, paid, or cancelled request too. Filter the list with ?tag=october; repeat the parameter to match any of several tags.

Amounts and the invoice

amount is the net amount. The invoice adds VAT, at the rate that applies between your team and the payer: for example, the reverse charge for an EU business with a VAT number. amountDue is what the payer owes: amount plus invoice.vatAmount, or amount while there is no invoice. amountRemaining is amountDue minus the completed settlements.

invoice carries the number, the download url, the issuedAt calendar date, the vatRate in percent as a decimal string such as 19.00, the vatAmount, and the creditNote once the request is cancelled. invoice.number is also the payment reference that the payer quotes on the bank transfer. An issued invoice never changes. To correct one, cancel the request and create a new one.

Payment

The payer pays by bank transfer to your team's account, with the invoice number as reference. Talentir applies a deposit to the request when its reference quotes the invoice number of exactly one open request of your team, and the currency and amount match amountDue exactly. Any other deposit stays a plain deposit to your account. Link it to the request in the dashboard, or mark the request as paid there.

While a request has no invoice, a payer with a Talentir team can also pay it on paymentUrl from the team's balance. The money always arrives on your Talentir account, never at your bank account or PayPal. It is a payment in GET /transactions that names the request in paymentRequestIds.

settlements lists every payment towards the request, oldest first. Each one has a type, a status, an amount, and a createdAt:

typeMeaningAlso carries
bank_transferA bank deposit to your account.transactionId: the deposit transaction, transaction_<uuid>_in
payoutA Talentir payout from the payer's team.payoutId, and transactionId once the payout reached your account
manualA team member marked the request as paid in the dashboard.note: why

transactionId is null while the money has not reached your account, and when Talentir removed the deposit. A settlement is pending until the money is credited to your account, completed once it counts towards amountDue, and failed when it never will.

The deposit is also a deposit in GET /transactions. It names the request in paymentRequestIds and carries the invoice in documents, with type payment_request_invoice.

Webhooks

Subscribe to payment_request.* to follow requests without polling. payment_request.paid fires when the completed settlements cover amountDue, and payment_request.reopened when a paid request moves back to open. payment_request.updated fires when the payer enters their billing details, announces a transfer, or a settlement is recorded. See Set up webhooks for every event. The webhook needs payment-requests:read.

Sandbox

POST /payment-requests/{id}/sandbox-transfer deposits amountDue with the invoice number as reference, as the payer's bank would, and runs it through the real matching. It needs an open request with an invoice, and works only in the sandbox.