Skip to content

Authentication

Your API key goes in Authorization: Bearer <key>: tuc_live_… in production, tuc_test_… in the sandbox (https://api.tucapi.app/sandbox).

Scope Allows
payins:crear create, confirm and request a code
payouts:crear create payouts
operaciones:leer read operations and events
saldos:leer GET /v2/balances
webhooks:configurar register the notification URL

The catalog (capabilities, methods, banks) can be read with any valid key.

Scope names are part of the contract and stay as they are (in Spanish) in every language.

Every route requires a scope, or any valid key for the catalog:

Scope Routes
operaciones:leer GET /v2/events, GET /v2/payins/{id}, GET /v2/payouts/{id}, GET /v2/transactions/{id}
payins:crear POST /v2/payins, POST /v2/payins/{id}/cancel, POST /v2/payins/{id}/confirm, POST /v2/payins/{id}/resend-code
payouts:crear POST /v2/payouts, POST /v2/payouts/{id}/cancel
saldos:leer GET /v2/balances
webhooks:configurar POST /v2/webhook-endpoints
any valid key GET /v2/banks, GET /v2/capabilities, GET /v2/methods

A key without the scope gets 403 scope_missing. A missing or invalid key gets 401 unauthorized. Both are configuration errors, not network errors: do not retry them.

Base URL Key
Production https://api.tucapi.app tuc_live_…
Sandbox https://api.tucapi.app/sandbox tuc_test_…

The same contract works in both environments: only the key and the base URL change. A test key against production, or a production key against the sandbox, gets 401 unauthorized. In the SDKs the base URL is a client option (baseUrl, base_url, WithBaseURL); in the MCP server, the TUCAPI_API_URL variable.

In the sandbox no money moves: the providers are doubles that respond like the real ones, with the same states, failure codes, timings, signed webhooks and events. The outcome of each operation is decided by the payer’s or beneficiary’s document:

document.number Outcome
00000001 failed, with an invalid-account failure.code
00000002 pending on create; confirmed on the first lookup
00000004 failed because the payer has insufficient funds
00000022 failed because there is no direct-debit enrollment (direct_debit only)
anything else confirmed

In a one-time-code pay-in (debit_otp) the valid code is always 123456; any other code leaves the pay-in failed with failure.code = code_rejected, just like in production, and to try again you create a new pay-in. Bank references are sequential 8-digit numbers, like the production ones. Test keys are issued by TuCapi together with the production keys, with the same scopes.