Assign a CLABE per user

Give each of your users their own SPEI CLABE: one call, idempotent per user, and every transfer to it is credited to your account.

POST /api/v1/clabe-assignments gives each of your end users their own SPEI CLABE. Any SPEI transfer your user sends to that CLABE is credited to your merchant account.

Call it once per user — for example when they sign up, or the first time they open your deposit screen. The call is idempotent per user: calling it again with the same user_id returns the same CLABE instead of creating a new one. Each user_id maps to exactly one CLABE within your merchant account, and two different user_id values always get two different CLABEs.

The transfers that arrive at an assigned CLABE are the direct transfers described in Frictionless SPEI: the customer pays from their banking app with no checkout, and you confirm each deposit with a webhook.

Base URL

Use the Tonder API domain for your environment and add /deposits before the endpoint path.

EnvironmentBase URLFull endpoint
Sandboxhttps://api-stage.tonder.io/depositshttps://api-stage.tonder.io/deposits/api/v1/clabe-assignments
Productionhttps://api.tonder.io/depositshttps://api.tonder.io/deposits/api/v1/clabe-assignments

If your integration calls an execute-api.amazonaws.com URL today, it still works. Switch to the domains above: they stay the same if Tonder's infrastructure changes.

Authentication

Send your Tonder API key in the Authorization header, prefixed with Token and a space:

Authorization: Token <your-api-key>

Use the same API key you use for the rest of the Tonder API. Tonder identifies your merchant account from the key, so the request carries no merchant id. A missing or invalid key is rejected before the request reaches the endpoint.

Keep the key on your server only. Never call this endpoint from a browser or mobile app.

Step by step

Assign the CLABE

POST /api/v1/clabe-assignments with a JSON body and the headers Authorization: Token <your-api-key> and Content-Type: application/json.

FieldTypeRequiredDescription
user_idstringYesYour own identifier for the end user. Use a value that never changes for that user, such as your internal customer ID.
curl -X POST https://api-stage.tonder.io/deposits/api/v1/clabe-assignments \
  -H "Authorization: Token $TONDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "customer-48213"}'
curl -X POST https://api.tonder.io/deposits/api/v1/clabe-assignments \
  -H "Authorization: Token $TONDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "customer-48213"}'

From your server, in Node.js (18+) or Python — swap the domain to https://api-stage.tonder.io and use your sandbox API key to test:

const res = await fetch(
  "https://api.tonder.io/deposits/api/v1/clabe-assignments",
  {
    method: "POST",
    headers: {
      Authorization: `Token ${process.env.TONDER_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ user_id: "customer-48213" }),
  }
);

if (!res.ok) throw new Error(`CLABE assignment failed: ${res.status}`);
const { clabe, is_new } = await res.json();
import os, requests

res = requests.post(
    "https://api.tonder.io/deposits/api/v1/clabe-assignments",
    headers={"Authorization": f"Token {os.environ['TONDER_API_KEY']}"},
    json={"user_id": "customer-48213"},
    timeout=30,
)
res.raise_for_status()
clabe = res.json()["clabe"]

Show the CLABE to your user

A new CLABE returns 201 Created. If the user already has one, you get 200 OK with the same CLABE and is_new: false. Both cases share the same body:

{
  "assignment_id": "9b2f6c1e-4d3a-4f7b-8a51-2c6e0d9f7a14",
  "clabe": "710969000012345678",
  "merchant_id": "1234",
  "user_id": "customer-48213",
  "provider_type": "Tonder",
  "assigned_at": "2026-10-13T18:22:05.123456+00:00",
  "is_new": true
}
FieldTypeDescription
clabestringThe 18-digit CLABE to show your user. They send SPEI transfers to it.
assignment_idstring (UUID)Tonder's ID for this assignment. Store it for support requests.
user_idstringThe user_id you sent.
merchant_idstringYour merchant ID, resolved from your API key.
provider_typestringAlways Tonder.
assigned_atstring (ISO 8601, UTC)When the CLABE was first assigned. It does not change on repeat calls.
is_newbooleantrue if this call created the CLABE, false if it already existed.

Receive the deposits

Every SPEI transfer to that CLABE is credited to your merchant account. Confirm each deposit with a webhook — the reconciliation keys and the direct-transfer flow are on Frictionless SPEI — or look a deposit up with the deposit-status endpoint.

Errors

Errors from the endpoint return a JSON body with error and message. The two authentication errors come from the gateway and only include message.

HTTP statuserrorWhen it happensWhat to do
400INVALID_PARAMETERuser_id is missing or is not a string.Fix the request body. Do not retry unchanged.
400DOMAIN_ERRORThe CLABE could not be assigned, for example because the bank provider was unavailable.Retry with backoff. Retrying is safe: you never get two CLABEs for the same user_id.
401none ("message": "Unauthorized")The Authorization header is missing.Add the header.
403none ("message": "User is not authorized to access this resource…")The API key is invalid, or the header doesn't use the Token <key> format.Check the key and the Token prefix.
500INTERNAL_ERRORUnexpected error on Tonder's side.Retry with backoff. If it persists, contact Tonder support.
{
  "error": "INVALID_PARAMETER",
  "message": "user_id is required"
}

API reference

POST
/api/v1/clabe-assignments

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

application/json

curl -X POST "https://example.com/api/v1/clabe-assignments" \  -H "Content-Type: application/json" \  -d '{    "user_id": "customer-48213"  }'
{
  "assignment_id": "9b2f6c1e-4d3a-4f7b-8a51-2c6e0d9f7a14",
  "clabe": "710969000012345678",
  "merchant_id": "1234",
  "user_id": "customer-48213",
  "provider_type": "Tonder",
  "assigned_at": "2026-10-13T18:22:05.123456+00:00",
  "is_new": false
}
{
  "assignment_id": "9b2f6c1e-4d3a-4f7b-8a51-2c6e0d9f7a14",
  "clabe": "710969000012345678",
  "merchant_id": "1234",
  "user_id": "customer-48213",
  "provider_type": "Tonder",
  "assigned_at": "2026-10-13T18:22:05.123456+00:00",
  "is_new": true
}
{
  "error": "INVALID_PARAMETER",
  "message": "user_id is required"
}
{
  "message": "Unauthorized"
}
{
  "message": "User is not authorized to access this resource"
}
{
  "error": "INTERNAL_ERROR",
  "message": "Unexpected error"
}

Next steps

Was this page helpful?

On this page