Withdrawals

Send money to a beneficiary by SPEI or debit card, approve it, and follow it to settlement: how to create it, both status vocabularies, the webhooks and the test data.

Withdrawals (payouts) send money from your balance to a beneficiary's 18-digit CLABE by SPEI, or to a 16-digit debit card. They are available for beneficiaries in Mexico, in MXN. For payouts in Argentina (ARS) to a CBU, CVU or alias, see Argentina; for payouts in Chile (CLP) to a checking or sight account, see Withdrawals in Chile.

This guide is written for the integrator. It covers creating a withdrawal and the rest of the cycle: approval, queries, statuses and webhooks.

Tonder picks the rail. The institution that executes the transfer is resolved by Tonder from your account's configuration. You don't need to know it or build logic on it: it can change without any change to your integration.

AspectSPEIDebit card
Processing timeInstant (seconds)Instant (seconds)
Availability24/724/7
Destination18-digit CLABE16-digit card number
Best forBeneficiaries with a CLABE, larger amountsBeneficiaries who only have a card

Environments and authentication

Withdrawals live on the API Direct host:

ServiceSandboxProduction
API Direct (S2S)https://stage.tonder.io/api/v1/https://app.tonder.io/api/v1/
Hosted Checkouthttps://api-stage.tonder.io/checkout/v1/https://api.tonder.io/checkout/v1/
SPEI deposits (CLABE per user)https://api-stage.tonder.io/deposits/https://api.tonder.io/deposits/
Card tokenizationhttps://token-sandbox.tonder.io/https://token.tonder.io/
Raw card data (PCI L1)https://process-sandbox.tonder.io/https://process.tonder.io/
Dashboardhttps://dashboard-stage.tonder.io/https://dashboard.tonder.io/

Every request carries your public API key. The secret key does not work for this flow.

Authorization: Token <API_KEY>
Content-Type: application/json
CaseResponse
No Authorization header401 · Authentication credentials were not provided.
Unknown token401 · Invalid token.
Token of a disabled user401 · User inactive or deleted.

Create a withdrawal

Create it with POST /api/v1/process/, the same endpoint payments use. What sets a withdrawal apart is operation_type.

curl -X POST "https://stage.tonder.io/api/v1/process/" \
  -H "Authorization: Token YOUR_TEST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "operation_type": "withdrawal",
    "amount": 20.00,
    "currency": "MXN",
    "client_reference": "payout-001",
    "transfer_method": "SPEI",
    "description": "Pago de comisiones",
    "beneficiary": {
      "account": "012969100000000110",
      "name": "Ana Maria Gonzalez",
      "rfc": "GOAN850315AB2",
      "institution": "40012",
      "email": "ana.gonzalez@email.com"
    },
    "metadata": {
      "latitude": "22.8870221",
      "longitude": "-109.911775",
      "order_reference": "ORD-001"
    },
    "fee_model": "01"
  }'
curl -X POST "https://app.tonder.io/api/v1/process/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "operation_type": "withdrawal",
    "amount": 20.00,
    "currency": "MXN",
    "client_reference": "payout-001",
    "transfer_method": "SPEI",
    "description": "Pago de comisiones",
    "beneficiary": {
      "account": "012969100000000110",
      "name": "Ana Maria Gonzalez",
      "rfc": "GOAN850315AB2",
      "institution": "40012",
      "email": "ana.gonzalez@email.com"
    },
    "metadata": {
      "latitude": "22.8870221",
      "longitude": "-109.911775",
      "order_reference": "ORD-001"
    },
    "fee_model": "01"
  }'
FieldRequiredDescription
operation_typeyesAlways "withdrawal"
amountyesThe amount. Must be greater than zero
currencyyes"MXN". Argentina uses "ARS" — see Argentina; Chile uses "CLP" — see Withdrawals in Chile
transfer_methodyes"SPEI" or "DEBIT_CARD"; "BANK_TRANSFER" in Argentina; "CLP_TRANSFER" in Chile
client_referencerecommendedYour internal reference. Comes back in the response and in the webhooks
descriptionnoPayment concept. Defaults to Retiro de fondos if omitted
beneficiary.accountyes18-digit CLABE for SPEI, 16-digit card number for debit card
beneficiary.nameyesThe holder's name as it appears on the account
beneficiary.rfcyesThe beneficiary's RFC or CURP. If you don't have it, send "ND"
beneficiary.institutionyesBanxico institution code. See Institution codes
beneficiary.emailyesThe beneficiary's email
metadatanoYour own data. Stored and returned as is
fee_modelyes"01"

Debit card. Compared to SPEI, two things change and nothing else: transfer_method becomes "DEBIT_CARD" and beneficiary.account carries the 16-digit card number.

Geolocation. metadata.latitude and metadata.longitude are recommended for operations in Mexico. If your integration already sends them, keep them.

HTTP 201:

{
  "id": "a1e2f918-1851-4988-b9de-36d57f41ed56",
  "withdrawal_id": "ad3069ed-598e-4a1b-82e0-2279d5af292d",
  "operation_type": "withdrawal",
  "status": "Pending",
  "amount": 20.0,
  "currency": "MXN",
  "client_reference": "payout-001",
  "metadata": {
    "latitude": "22.8870221",
    "longitude": "-109.911775",
    "order_reference": "ORD-001"
  },
  "transfer_method": "SPEI",
  "created_at": "2026-10-01T17:33:41.364685Z",
  "status_code": 201
}

Store both identifiers. They are different and not interchangeable.

withdrawal_id is the withdrawal's: approve it, reject it, read its detail. id is the transaction's: check the status of the operation.

Approve

A newly created withdrawal stays pending and does not advance on its own, unless your account has an automatic-approval rule. If your withdrawals stay there, this is the step that is missing.

From the Dashboard. Open the withdrawal in Withdrawals and press Approve.

By API:

curl -X POST "https://stage.tonder.io/api/v1/withdrawals/perform_action/" \
  -H "Authorization: Token YOUR_TEST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "id": "ad3069ed-598e-4a1b-82e0-2279d5af292d", "action": "approve" }'
curl -X POST "https://app.tonder.io/api/v1/withdrawals/perform_action/" \
  -H "Authorization: Token YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "id": "ad3069ed-598e-4a1b-82e0-2279d5af292d", "action": "approve" }'

Mind which identifier you send here. It's the withdrawal_id of the /process/ response, not its id.

Sending the id returns 404 Withdrawal not found: 'Item', which misleads because it sounds as if the withdrawal did not exist.

Actions: approve, reject, cancel, fail, refund.

Idempotency. A second approve on a settled withdrawal answers 409 with Invalid transition from PAID_FULL to PROCESSING. On a withdrawal in a terminal state, 409 with Cannot modify withdrawal in terminal state. Retrying does not duplicate the payment.

A nonexistent action answers 400 with Invalid action.

Query

Transaction status

GET /api/v1/transactions/<id>/

Takes the transaction id: the id field of the /process/ response.

Withdrawal detail

curl "https://stage.tonder.io/api/v1/withdrawals/ad3069ed-598e-4a1b-82e0-2279d5af292d" \
  -H "Authorization: Token YOUR_TEST_API_KEY"
curl "https://app.tonder.io/api/v1/withdrawals/ad3069ed-598e-4a1b-82e0-2279d5af292d" \
  -H "Authorization: Token YOUR_API_KEY"

No trailing slash. With one, it answers 404. An unknown id answers 200 with {"detail": "Withdrawal not found"} and no record: check for detail before reading the fields.

It is the only endpoint that carries the reason for a failure, in status_changes[].reason and action.reason:

{
  "id": "7b57edd2-6594-4ef6-813b-df0d3d091a5c",
  "business_id": "69",
  "status": "FAILED",
  "amount": 1.7,
  "currency": "MXN",
  "transfer_method": "SPEI",
  "tracking_key": "a61c4f05b1de4645a1d2",
  "provider_reference": null,
  "account_data": { "...": "..." },
  "status_changes": [
    { "from_status": "PENDING", "to_status": "PROCESSING",
      "timestamp": "2026-10-13T18:40:23.497368", "reason": null },
    { "from_status": "PROCESSING", "to_status": "FAILED",
      "timestamp": "2026-10-13T18:40:23.497375",
      "reason": "Provider rejected: invalid_institution_id" }
  ],
  "action": { "action": "FAIL", "reason": "Provider rejected: invalid_institution_id" },
  "url_cep": "",
  "created_at": "2026-10-13T02:06:17.772297Z",
  "paid_at": null
}

List

curl "https://stage.tonder.io/api/v1/withdrawals/query/?page=1&page_size=50&start_date=2026-10-01&end_date=2026-10-07" \
  -H "Authorization: Token YOUR_TEST_API_KEY"
curl "https://app.tonder.io/api/v1/withdrawals/query/?page=1&page_size=50&start_date=2026-10-01&end_date=2026-10-07" \
  -H "Authorization: Token YOUR_API_KEY"
Parameter
page, page_sizePagination
start_date, end_dateRange, YYYY-MM-DD

The response is { "count", "results", "search_mode" }, where each item in results is the full withdrawal record of the detail.

The id filter is not supported: it is ignored silently and the full list comes back. For one specific withdrawal use the detail above.

An inverted range, with start_date after end_date, answers 500.

Available balance

curl "https://stage.tonder.io/api/v1/withdrawals/balance" \
  -H "Authorization: Token YOUR_TEST_API_KEY"
curl "https://app.tonder.io/api/v1/withdrawals/balance" \
  -H "Authorization: Token YOUR_API_KEY"
{
  "available": "32894.55",
  "current_balance": "32894.55"
}

GET only. With POST it answers 405.

The shape of the response depends on your account's configuration. It may carry only current_balance, or current_balance together with available. Read it defensively and don't assume both fields exist.

Account activity

curl "https://stage.tonder.io/api/v1/withdrawals/account_activity/query/?page=1&page_size=50&tz=America/Mexico_City&start_date=2026-10-01&end_date=2026-10-02" \
  -H "Authorization: Token YOUR_TEST_API_KEY"
curl "https://app.tonder.io/api/v1/withdrawals/account_activity/query/?page=1&page_size=50&tz=America/Mexico_City&start_date=2026-10-01&end_date=2026-10-02" \
  -H "Authorization: Token YOUR_API_KEY"

Returns the movements of your account, withdrawals and deposits, as { "results", "next_token" }.

The range must span at least two days. With start_date equal to end_date it returns an empty list even if that day has movements. To query a single day, set the next day as end_date.

Movements arrive by two routes: an immediate one, within seconds, and an hourly reconciliation that completes some fields. A movement that was just paid can take up to an hour to show complete.

Statuses

The full cycle, in the order it happens:

StatusTypeMeaning
PENDINGInitialCreated. Waiting for approval
PROCESSINGIntermediateApproved, in progress internally
SENT_TO_PROVIDERIntermediateSent. No confirmation yet
PAID_FULLTerminalSettled
FAILEDTerminalFailed. The detail carries the reason
REJECTEDTerminalRejected, by you or by validation
CANCELEDTerminalCancelled
REFUNDEDTerminalIt was paid, and the receiving bank returned the funds

Two vocabularies

The creation response and the webhooks use readable names, while the query endpoints return the internal names. They are the same status:

In creation and in the webhooksIn the queries
PendingPENDING
ProcessingPROCESSING / SENT_TO_PROVIDER
SuccessPAID_FULL
DeclinedREJECTED
CancelledCANCELED
FailedFAILED
ReturnedREFUNDED

Handle both. If your integration only recognises one of the two sets, it will ignore real events.

When reconciling

PROCESSING and SENT_TO_PROVIDER are intermediate. Settling a withdrawal when you see them produces wrong results. Always wait for a terminal status.

Treat REFUNDED as final and credit the reversal. A returned withdrawal went through PAID_FULL first, so a handler that only reacts to the payment will never see that the money came back.

The five terminal statuses are PAID_FULL, FAILED, REJECTED, CANCELED and REFUNDED. Reconcile against all five.

Webhooks

Two are emitted per withdrawal: one when it is created, with the pending status, and one when it reaches a terminal status. If the funds are returned after being paid, a third one arrives.

There are two payload formats, and which one you receive depends on how your account is configured. Confirm it with us before writing the handler. Both carry the same essential information: status, method, amount and your references.

Flat format

{
  "id": "a1e2f918-1851-4988-b9de-36d57f41ed56",
  "operation_type": "withdrawal",
  "amount": "20",
  "currency": "MXN",
  "client_reference": "payout-001",
  "status": "Pending",
  "transfer_method_type": "SPEI",
  "created": "2026-05-21T19:15:32.029134Z",
  "metadata": {
    "latitude": "22.8870221",
    "longitude": "-109.911775",
    "external_id": "payout-001"
  },
  "event_type": "withdrawal_Pending",
  "action": "MODIFY"
}
Field
idThe transaction id. It repeats on every event of the same withdrawal: correlate with it
operation_type"withdrawal"
statusThe status reached
transfer_method_typeSPEI or DEBIT_CARD
event_typewithdrawal_ plus the status
client_referenceYour reference, as you sent it
metadataWhat you sent, plus external_id
action"MODIFY"

The payload can carry other fields that identify the institution that executed the transfer and its reference. Don't build logic on them: they depend on your account's configuration and can change.

Extended format

Nests everything under withdrawal and adds the status history, the fees and the transfer's detail. The status travels in the internal names of the Statuses section.

{
  "withdrawal": {
    "id": "ad3069ed-598e-4a1b-82e0-2279d5af292d",
    "business_id": "69",
    "status": "PAID_FULL",
    "business_id_status": "69#PAID_FULL",
    "monetary_amount": { "amount": "20.00", "currency": "MXN" },
    "transfer_method": "SPEI",
    "tracking_key": "2da0310418da4be18419",
    "provider_reference": "ref_2da0310418da4be1",
    "account_data": {
      "nombre_beneficiario": "Ana Maria Gonzalez",
      "cuenta_beneficiario": "012969100000000110",
      "institucion_contraparte": "40012",
      "tipo_cuenta_beneficiario": "40",
      "rfc_curp_beneficiario": "GOAN850315AB2",
      "concepto_pago": "Pago de comisiones",
      "email": "ana.gonzalez@email.com"
    },
    "status_changes": [
      { "from_status": "PENDING", "to_status": "PROCESSING",
        "timestamp": "2026-09-15T19:33:20.112", "reason": null },
      { "from_status": "PROCESSING", "to_status": "PAID_FULL",
        "timestamp": "2026-09-15T19:35:52.912", "reason": "succeeded" }
    ],
    "metadata": { "order_reference": "ORD-001" },
    "fee_model": "01",
    "created_at": "2026-09-15T19:33:14.262113+00:00",
    "modified_at": "2026-09-15T19:35:52.989243+00:00",
    "paid_at": "2026-09-15T19:35:52.989260+00:00"
  }
}

It also carries a block with the raw notification from the institution that executed the transfer.

Inside that block the amount is in centavos, unlike monetary_amount, which is in pesos. It can also carry a tracking key different from the top-level one: that second one is the real SPEI key before Banxico, the one that traces the payment on its portal. The beneficiary's data arrives masked.

The five events

withdrawal_Pending — the withdrawal was created and awaits approval.

{ "status": "Pending", "event_type": "withdrawal_Pending", "...": "..." }

withdrawal_Success — settled. The money went out.

{ "status": "Success", "event_type": "withdrawal_Success", "...": "..." }

withdrawal_Declined — rejected, usually because of the beneficiary's data.

{ "status": "Declined", "event_type": "withdrawal_Declined", "...": "..." }

withdrawal_Failed — it failed when sent.

{ "status": "Failed", "event_type": "withdrawal_Failed", "...": "..." }

withdrawal_Returned — the receiving bank returned the funds after a successful payment. It is the third webhook of that withdrawal, and arrives minutes or hours after the Success.

{ "status": "Returned", "event_type": "withdrawal_Returned", "...": "..." }

With Webhooks 2.0, a cancelled withdrawal also sends withdrawal_Canceled — spelled with one L.

Recommendations

Be idempotent. The same event can arrive more than once. With Webhooks 2.0, deduplicate on the webhook-id header; without it, use id together with event_type as the key. metadata.external_id repeats on every event of the withdrawal, so it correlates but cannot tell Pending from Success.

Don't assume order. The terminal event can arrive before the pending one.

Some fields identify who executed the transfer and with which reference. Don't build logic on those values: they depend on your account's configuration and can change. To react, use status, event_type and your own identifiers.

Answer 2xx fast and process afterwards. Reconcile anything your endpoint missed with the withdrawal detail; how deliveries are retried and resent is in Delivery and retries.

Institution codes

beneficiary.institution is the code of the beneficiary's bank in Banxico's catalogue, four or five digits. The non-bank participants of the catalogue work too. The full list is in the Banking reference.

The institution code and the CLABE must belong to the same bank. The system does not check that correspondence when the withdrawal is created, but a mismatch can cause a rejection when it is sent.

Test data

Valid only in Sandbox, and always with institution 40012: two CLABEs that pay, one that fails, one whose funds come back minutes to an hour after paying — the way to exercise the third webhook, withdrawal_Returned — and one debit card that pays. The accounts and how to force each terminal state are in Test cases — Withdrawals.

If this data is rejected, write to us before going on: your test account may need a different configuration.

Payment receipt (CEP)

Settled withdrawals deliver a receipt in the url_cep field, which points to Banxico's portal with the payment's data.

It takes between 4 and 30 minutes to appear after settlement. Reading it right after approving returns empty without that meaning it is missing. Don't conclude anything before half an hour.

A REFUNDED withdrawal keeps its receipt: the transfer happened and was returned afterwards.

Errors

ResponseWhat happened
400 · Amount must be greater than 0Zero or negative amount
400 · Transfer method must be SPEI or DEBIT_CARDUnknown method
400 · beneficiary.account: This field is requiredThe destination account is missing
400 · Invalid actionThe action sent does not exist
401 · Invalid tokenWrong API key
401 · User inactive or deletedThe user of that key is disabled
404 · Withdrawal not found: 'Item'You sent the transaction id where the withdrawal_id belongs
200 · {"detail": "Withdrawal not found"}The id in the detail URL does not exist (the detail endpoint answers 200, not 404)
405 · Method not allowedThe balance endpoint only accepts GET
409 · Invalid transitionThe withdrawal is already in a terminal state
Provider rejected: invalid_institution_idThe institution code does not correspond

The generic HTTP codes are in Codes.

Before going to production

The amount is not validated against your balance at creation. A withdrawal above the available balance is accepted and stays pending. The validation happens at settlement, and that is where it fails.

The balance is not reserved while the withdrawal is pending. It is deducted when paid. If you accumulate many pending withdrawals, the available balance does not reflect that commitment.

The beneficiary's name has a practical limit of 40 characters. Longer names can be rejected when sent, not when created. Validate it on your side first. A frequent case is a surname the end user typed twice.

A pending withdrawal is dispatched with the configuration in force when it is approved, not the one it had when created.

The amount limit is set by the institution that executes the transfer, not by Tonder.

Questions

If something in this guide does not match what you observe, write to support with the withdrawal_id, the transaction id and the approximate time. With that we can trace the whole case.

API reference

You create a withdrawal with Process Transaction. The rest of the cycle:

POST
/withdrawals/perform_action/

Authorization

Authorization
Authorization<token>

Your public API key, with the word Token and a space in front of it. Example: Token 6534bc0a7e1f4d2b9c8e3a5f7b1d2c4e6f8a9b0c — that whole value is the header. Sending the key alone returns 401 'Authentication credentials were not provided'. In this playground you may paste just the key; the prefix is added for you.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/withdrawals/perform_action/" \  -H "Content-Type: application/json" \  -d '{    "id": "ad3069ed-598e-4a1b-82e0-2279d5af292d",    "action": "approve"  }'
{
  "id": "ad3069ed-598e-4a1b-82e0-2279d5af292d",
  "business_id": "69",
  "status": "PROCESSING",
  "amount": 20,
  "currency": "MXN",
  "transfer_method": "SPEI",
  "status_changes": [
    {
      "from_status": "PENDING",
      "to_status": "PROCESSING",
      "timestamp": "2026-10-01T17:35:02.118402",
      "reason": null
    }
  ],
  "created_at": "2026-10-01T17:33:41.364685Z",
  "modified_at": "2026-10-01T17:35:02.201173Z",
  "paid_at": null
}
{
  "error": "Invalid action"
}
{
  "detail": "Invalid token."
}
{
  "error": "Withdrawal not found: 'Item'"
}
{
  "detail": "Cannot modify withdrawal in terminal state"
}
GET
/withdrawals/{withdrawal_id}

Authorization

Authorization
Authorization<token>

Your public API key, with the word Token and a space in front of it. Example: Token 6534bc0a7e1f4d2b9c8e3a5f7b1d2c4e6f8a9b0c — that whole value is the header. Sending the key alone returns 401 'Authentication credentials were not provided'. In this playground you may paste just the key; the prefix is added for you.

In: header

Path Parameters

withdrawal_id*string

The withdrawal id: withdrawal_id from POST /process/.

Response Body

application/json

application/json

curl -X GET "https://example.com/withdrawals/7b57edd2-6594-4ef6-813b-df0d3d091a5c"
{
  "id": "7b57edd2-6594-4ef6-813b-df0d3d091a5c",
  "business_id": "69",
  "status": "FAILED",
  "amount": 1.7,
  "currency": "MXN",
  "transfer_method": "SPEI",
  "tracking_key": "a61c4f05b1de4645a1d2",
  "provider_reference": null,
  "account_data": {
    "nombre_beneficiario": "Ana Maria Gonzalez",
    "cuenta_beneficiario": "012969100000000013",
    "institucion_contraparte": "40012",
    "tipo_cuenta_beneficiario": 40,
    "rfc_curp_beneficiario": "GOAN850315AB2",
    "concepto_pago": "Pago de comisiones",
    "email": "ana.gonzalez@email.com"
  },
  "metadata": {
    "order_reference": "ORD-001"
  },
  "status_changes": [
    {
      "from_status": "PENDING",
      "to_status": "PROCESSING",
      "timestamp": "2026-10-13T18:40:23.497368",
      "reason": null
    },
    {
      "from_status": "PROCESSING",
      "to_status": "FAILED",
      "timestamp": "2026-10-13T18:40:23.497375",
      "reason": "Provider rejected: invalid_institution_id"
    }
  ],
  "action": {
    "action": "FAIL",
    "reason": "Provider rejected: invalid_institution_id"
  },
  "url_cep": "",
  "created_at": "2026-10-13T02:06:17.772297Z",
  "modified_at": "2026-10-13T18:40:23.512117Z",
  "paid_at": null
}
{
  "detail": "Invalid token."
}
Empty
GET
/withdrawals/query/

Authorization

Authorization
Authorization<token>

Your public API key, with the word Token and a space in front of it. Example: Token 6534bc0a7e1f4d2b9c8e3a5f7b1d2c4e6f8a9b0c — that whole value is the header. Sending the key alone returns 401 'Authentication credentials were not provided'. In this playground you may paste just the key; the prefix is added for you.

In: header

Query Parameters

page?integer

Page number, starting at 1.

page_size?integer

Items per page.

start_date?string

First creation date to include, YYYY-MM-DD.

end_date?string

Last creation date to include, YYYY-MM-DD. Must not precede start_date.

Response Body

application/json

application/json

application/json

curl -X GET "https://example.com/withdrawals/query/"
{
  "count": 1,
  "results": [
    {
      "id": "ea6ac67d-b577-481a-9b99-3c3c275ae527",
      "business_id": "69",
      "status": "PAID_FULL",
      "amount": 20,
      "currency": "MXN",
      "transfer_method": "SPEI",
      "tracking_key": "2da0310418da4be18419",
      "account_data": {
        "nombre_beneficiario": "Ana Maria Gonzalez",
        "cuenta_beneficiario": "012969100000000110",
        "institucion_contraparte": "40012",
        "tipo_cuenta_beneficiario": 40,
        "rfc_curp_beneficiario": "GOAN850315AB2",
        "concepto_pago": "Pago de comisiones",
        "email": "ana.gonzalez@email.com"
      },
      "metadata": {
        "order_reference": "ORD-001"
      },
      "status_changes": [
        {
          "from_status": "PENDING",
          "to_status": "PROCESSING",
          "timestamp": "2026-10-01T17:35:02.118402",
          "reason": null
        },
        {
          "from_status": "PROCESSING",
          "to_status": "PAID_FULL",
          "timestamp": "2026-10-01T17:37:41.902188",
          "reason": "succeeded"
        }
      ],
      "url_cep": "https://www.banxico.org.mx/cep/",
      "created_at": "2026-10-01T17:33:41.364685Z",
      "modified_at": "2026-10-01T17:37:41.998211Z",
      "paid_at": "2026-10-01T17:37:41.998227Z"
    }
  ],
  "search_mode": "date_range"
}
{
  "detail": "Invalid token."
}
{
  "error": "Failed to fetch withdrawals"
}
GET
/withdrawals/balance

Authorization

Authorization
Authorization<token>

Your public API key, with the word Token and a space in front of it. Example: Token 6534bc0a7e1f4d2b9c8e3a5f7b1d2c4e6f8a9b0c — that whole value is the header. Sending the key alone returns 401 'Authentication credentials were not provided'. In this playground you may paste just the key; the prefix is added for you.

In: header

Response Body

application/json

application/json

application/json

curl -X GET "https://example.com/withdrawals/balance"
{
  "available": "32894.55",
  "current_balance": "32894.55"
}
{
  "detail": "Invalid token."
}
{
  "detail": "Method \"POST\" not allowed."
}
GET
/withdrawals/account_activity/query/

Authorization

Authorization
Authorization<token>

Your public API key, with the word Token and a space in front of it. Example: Token 6534bc0a7e1f4d2b9c8e3a5f7b1d2c4e6f8a9b0c — that whole value is the header. Sending the key alone returns 401 'Authentication credentials were not provided'. In this playground you may paste just the key; the prefix is added for you.

In: header

Query Parameters

page?integer

Page number, starting at 1.

page_size?integer

Items per page.

tz?string

IANA time zone the dates are interpreted in.

start_date?string

First day to include, YYYY-MM-DD.

end_date?string

Last day to include, YYYY-MM-DD. Must be at least one day after start_date.

Response Body

application/json

application/json

curl -X GET "https://example.com/withdrawals/account_activity/query/"
{
  "results": [
    {
      "id": "9c1d7f32-5b0e-4a7d-9f2e-1c8a4b6d2e10",
      "type": "withdrawal",
      "amount": "20.00",
      "business_id": "69",
      "status": "succeeded",
      "operation_date": "2026-10-01T17:37:41Z",
      "created_at": "2026-10-01T17:37:48.668244Z",
      "metadata": {
        "tonder_withdrawal_id": "ea6ac67d-b577-481a-9b99-3c3c275ae527",
        "beneficiary_account": "012969******0110",
        "tracking_key": "2da0310418da4be18419",
        "currency": "MXN"
      },
      "raw_json": {
        "amount": 2000,
        "currency": "MXN",
        "status": "succeeded",
        "tracking_key": "2da0310418da4be18419"
      }
    }
  ],
  "next_token": null
}
{
  "detail": "Invalid token."
}

Next steps

Was this page helpful?

On this page