Respawn PayDocs

CashOut Webhook (Withdrawals)

Receive automatic notifications about the status of withdrawal requests.

Endpoint and Authentication

Defined by the customer on the /api/SendWebhook route

The webhook URL is configured by the customer. Example: https://mysite.com/api/webhook/respawn

The URL must use HTTPS, port 443 and a public domain. Private network or local IP addresses are rejected.

Configuration and Security

URL configuration, status selection and origin verification are the same as for the PixIn webhook. See Webhook PixIn, sections How to Configure and How to Verify the Origin.

Headers Sent

Headers
Content-Type: application/json
X-Idempotency-Key: <uuid>
X-Webhook-Event-Id: <uuid> (same value)
X-Webhook-Correlation-Id: <id>
X-Webhook-Sent-At: 2025-11-27T10:12:34Z
X-Webhook-Secret: <secret> (only if you registered a secret on the webhook)

Use X-Idempotency-Key (same value as X-Webhook-Event-Id) to detect repeated deliveries of the same event.

Cashout Webhook Example

Webhook Payload - Successful
{
"object": "withdraw",
"type": "cashout",
"status": "successful",
"companyId": "2f3c1c0e-6a52-4a0f-9d34-6a7b3f6f2b10",
"withdrawId": 7184,
"value": 10,
"valueInCents": 1000,
"currency": "BRL",
"provider": "OnlyUp",
"providerStatus": "successful",
"providerTid": "wld-00007184",
"providerPaymentId": "uuid-provider",
"endToEndId": "E00000000202511271012XXXXXXXXXXX",
"providerAmount": 10,
"providerConfirmedAt": "2025-11-27T10:12:33Z",
"providerDebitedAt": null,
"providerErrorCode": null,
"providerErrorDescription": null,
"providerPayload": "{... JSON text from the provider ...}",
"pixKey": "12345678909",
"pixKeyType": "CPF",
"creditorDocument": "12345678909",
"localInstrument": null,
"transactionType": null,
"creditDebitType": null,
"remittanceInformation": null,
"payer": {
"name": "PAYER NAME (the paying account)",
"document": "xxx",
"ispb": "xxxxx",
"issuer": "xxxx",
"number": "xxxx",
"accountType": null,
"agency": "xxxx",
"account": "xxxx"
},
"receiver": {
"name": "BENEFICIARY NAME",
"document": "xxx",
"ispb": "xxxx",
"issuer": "xxxx",
"number": "xxxx",
"accountType": null,
"agency": "xxxx",
"account": "xxxx"
},
"createdAt": "2025-11-27T00:00:00Z",
"updatedAt": "2025-11-27T00:00:00Z",
"processedAt": "2025-11-27T00:00:00Z",
"metadata": null
}

Field Descriptions

objectstringAlways 'withdraw'
typestringEvent type - always 'cashout'
statusstringWithdrawal status: awaiting, pending, successful, failure or refunded
companyIdstringID of the company that owns the withdrawal (UUID)
withdrawIdnumberInternal withdrawal ID at Respawn Pay
valuenumberWithdrawn amount in reais
valueInCentsnumberWithdrawn amount in cents
currencystringCurrency (always 'BRL')
providerstringProvider that processed the withdrawal (for example 'OnlyUp')
providerStatusstringStatus text reported by the provider (its format depends on the provider)
providerTidstringWithdrawal TID at the provider
providerPaymentIdstringPayment ID at the provider (UUID)
endToEndIdstringUnique PIX code of the withdrawal (E2E). Can be used for Pix Out queries.
providerAmountnumberAmount confirmed by the provider
providerConfirmedAtstringConfirmation date/time by the provider
providerDebitedAtstring|nullAccount debit date/time (if available)
providerErrorCodestring|nullProvider error code, when the withdrawal fails
providerErrorDescriptionstring|nullProvider error description, when the withdrawal fails
providerPayloadstring|nullRaw provider response, as JSON text (parse it if you need inner fields)
pixKeystringDestination PIX key
pixKeyTypestringKey type (CPF, CNPJ, EMAIL, PHONE, EVP)
creditorDocumentstringBeneficiary document
localInstrumentstring|nullPayment instrument reported by the provider (when available)
transactionTypestring|nullTransaction type reported by the provider (when available)
creditDebitTypestring|nullCredit or debit, reported by the provider (when available)
remittanceInformationstring|nullPayment message reported by the provider (when available)
payerobjectPayer data (the paying account): name, document, ispb, issuer, number, accountType, agency, account
receiverobjectReceiver data (the beneficiary): name, document, ispb, issuer, number, accountType, agency, account
createdAtstringWithdrawal creation date/time
updatedAtstringLast update date/time
processedAtstringDate/time the provider processed the withdrawal
metadatastring|nullMetadata sent in the request, returned as JSON text (a string), not as an object; parse it

Important Notes

endToEndId is the unique PIX identifier of the transfer. You can look the withdrawal up by it with GET /api/Withdraw/lookup?q=<endToEndId> and use it to track the PIX with the receiving bank.

value is in reais and valueInCents is in cents.

When Is the Webhook Sent?

The webhook is fired whenever:

  • The withdrawal is confirmed (successful)
  • The withdrawal is refunded (refunded)
  • The withdrawal is declined / failure

The awaiting and pending statuses are also sent, but only if they are enabled in your webhook configuration. You only receive the statuses you enabled.

Possible Statuses

awaitingAwaiting processing
pendingProcessing (sent only if enabled on the webhook)
successfulPaid
failureFailed / rejected / blocked / canceled
refundedRefunded

There are no approved, blocked or failed statuses: blocking, expiration and cancellation arrive as failure.

Automatic Retry

OKUp to 3 consecutive attempts, 1 second and 2 seconds apart, with a 15-second limit per attempt
OKReply with HTTP 2xx to confirm. Any other code, or a body with received, success or ok equal to false, or with status failed, counts as a failure and triggers a new attempt
OKAvoid processing the same event twice by using the X-Idempotency-Key header

Response Example

Response
{ "received": true, "idempotent": false }

Handler Example

Node.js / Express
app.post('/webhook/respawn/cashout', async (req, res) => {
const {
type,
status,
withdrawId,
value,
valueInCents,
endToEndId,
providerConfirmedAt,
receiver
} = req.body;
const idempotencyKey = req.headers['x-idempotency-key'];
// Check idempotency
if (await checkIdempotency(idempotencyKey)) {
return res.status(200).json({ received: true, idempotent: true });
}
if (type === 'cashout') {
switch (status) {
case 'successful':
console.log(`Withdrawal ${withdrawId} confirmed: R$ ${value}`);
console.log(`Amount in cents: ${valueInCents}`);
console.log(`E2E: ${endToEndId}`);
console.log(`Confirmed at: ${providerConfirmedAt}`);
console.log(`Beneficiary: ${receiver.name}`);
await updateWithdrawStatus(withdrawId, 'confirmed');
break;
case 'failure':
console.log(`Withdrawal ${withdrawId} failed`);
await updateWithdrawStatus(withdrawId, 'failed');
// Notify your user about the failure
break;
}
}
await markAsProcessed(idempotencyKey);
res.status(200).json({ received: true, idempotent: false });
});