Skip to main content

TED Guide

This guide explains how to send and receive TED (Transferência Eletrônica Disponível) through the CorpX API. TED is a BACEN interbank transfer that operates in a specific window and is asynchronous by design — unlike PIX (instant) and internal transfers (same bank).

Overview

TED is an interbank transfer processed by the SPB (Brazilian Payment System), with a send window on business days (06:30–17:00) and same-day settlement when sent within the window.

FeaturePIXTEDInternal Transfer
Window24/7Business days 06:30–17:0024/7
SettlementInstant (less than 10s)~30min after sendInstant
BanksAny (PIX network)Any (SPB network)Same bank
CostVariableVariable (higher than PIX)Typically zero
Min amountR$ 0.01R$ 0.01R$ 0.01
Max amountConfigurableNo BACEN capConfigurable

When to use TED instead of PIX?

  • Very large amounts above the PIX limit configured for the account
  • Legacy systems that still require TED
  • Counterparty that only accepts TED (e.g. some public agreements)
  • Interbank boletos or corporate payroll in some ERPs

For day-to-day (quick payments, less than R$ 1MM, in/out of business hours), PIX is always preferable — instant, 24/7, typically cheaper.

Settlement bank MT Bank (to receive TED)

When someone wants to send a TED to you, instruct the counterparty to use these details:

FieldValue
BankMT Instituição de Pagamentos S.A.
Compe code681
ISPB50871921
Account typePayment account (inform the counterparty)
Branch(your branch at MT)
Account number(your account number at MT)
Holder CPF/CNPJ(the account holder's document)

Code 681 is what the counterparty enters in the "Bank" field of their app/internet banking. Don't confuse it with the ISPB (8 digits) — banks ask for the 3-digit Compe code.

When a TED arrives in your account, you receive the ted.in.received webhook (see Webhooks).

Window and timing

TED follows the BACEN window — outside it, the transaction is scheduled for the next business day.

WindowBehavior
Business days, 06:30–17:00TED sent within the window settles the same business day (~30min after successful send)
Business days, 17:00–17:30Direct interbank window — does not apply to clients via PSP/MT (rejected)
After 17:30 on a business dayScheduled for D+1 business day. Status stays PROCESSING on our side until settled
Weekend / holidayScheduled for the next business day. Defensive polling continues for up to 48h

Server-side defensive polling

To ensure no TED gets "stuck" even if the settlement bank's webhook fails, the TEDOut.Workflow polls the MT statement every 1 minute for up to 48 hours. If the TED doesn't appear as settled in that period, it's marked FAILED (timeout). You always get the final consistent state via GET /v1/accounts/{accountId}/transfers/ted/{tedId} or via the ted.out.failed webhook.

Costs and limits

  • TED OUT (send): fixed fee per operation — see Backoffice → Statement with operation=FEE filter (GET /v1/accounts/{accountId}/statement?operation=FEE)
  • TED IN (receive): receiving fee when applicable
  • Min: R$ 0.01
  • Max: no BACEN cap; CorpX allows up to the account's operational limit (configurable via Policies)

Exact fees vary by contract — check your commercial agreement.

1. Send a TED

Endpoint: POST /v1/accounts/{accountId}/ted/out

curl -X POST "https://tenant.api.corpx.com/v1/accounts/{accountId}/ted/out" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-yourcompany" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ted-001" \
-d '{
"value": 5000.00,
"bankCode": "001",
"branch": "1234",
"account": "56789",
"accountType": "CHECKING",
"taxNumber": "12345678900",
"holderName": "JOAO DA SILVA",
"description": "Supplier payment Invoice 12345",
"identifier": "supplier-acme-2026-05"
}'

Fields

FieldTypeRequiredDescription
valuenumberYesAmount in BRL (positive, max 2 decimals)
bankCodestringYesDestination bank Compe code (3 digits, e.g. 001 Banco do Brasil, 237 Bradesco, 341 Itaú). Also accepts 8-digit ISPB
branchstringYesDestination branch (digits only)
accountstringYesDestination account (digits only, no final check digit)
accountTypestringNoCHECKING (default), SAVINGS, PAYMENT, or SALARY
taxNumberstringYesCPF (11 digits) or CNPJ (14 digits) of the recipient holder
holderNamestringYesRecipient's full legal name
descriptionstringNoFree-form message (e.g. invoice number)
identifierstringNoIntegrator correlation key. Auto-generated if omitted

Response (202 Accepted)

{
"tedId": "ted-supplier-acme-2026-05",
"workflowId": "ted-out-ted-supplier-acme-2026-05",
"runId": "019e1234-...",
"idempotencyKey": "ted-001",
"identifier": "supplier-acme-2026-05",
"status": "PROCESSING",
"amount": 5000.00,
"destination": {
"bankCode": "001",
"branch": "1234",
"account": "56789",
"accountType": "CHECKING",
"taxNumber": "12345678900",
"holderName": "JOAO DA SILVA"
},
"description": "Supplier payment Invoice 12345",
"info": "TED is asynchronous — final status converges via webhook or defensive polling (48h max)."
}

The tedId is CorpX-unique (ted-{identifier}) and is the key to query status and correlate with webhooks.

2. Query status

Endpoint: GET /v1/accounts/{accountId}/transfers/ted/{tedId}

curl "https://tenant.api.corpx.com/v1/accounts/{accountId}/transfers/ted/ted-supplier-acme-2026-05" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-yourcompany"

Response (200)

{
"tedId": "ted-supplier-acme-2026-05",
"accountId": "773107de-...",
"status": "COMPLETED",
"amount": 5000.00,
"identifier": "supplier-acme-2026-05",
"description": "Supplier payment Invoice 12345",
"partnerId": "supplier-acme-2026-05",
"createdAt": "2026-05-23T09:00:00Z",
"updatedAt": "2026-05-23T09:32:15Z"
}

States

StatusMeaning
PROCESSINGTED accepted by the settlement bank; awaiting BACEN settlement
COMPLETEDTED settled at the destination bank (terminal)
FAILEDTED rejected, expired, or 48h timeout (terminal)

TED Webhooks

The recommended way to track TEDs is to subscribe to webhooks — you're notified in real time without polling.

Available events

EventWhen
ted.out.requestedImmediately after the POST is accepted (PROCESSING status)
ted.out.confirmedSettlement confirmed by the settlement bank (terminal — success)
ted.out.failedSettlement rejected/expired or 48h timeout (terminal — failure)
ted.in.receivedTED received in your account (originated by a third party)
ted.paymentDEPRECATED — alias for ted.out.confirmed. Will be removed in v3.0

Payload ted.out.requested

{
"eventType": "ted.out.requested",
"eventId": "ted-supplier-acme-2026-05-requested",
"data": {
"tedId": "ted-supplier-acme-2026-05",
"tenantId": "tenant-yourcompany",
"accountId": "773107de-...",
"partnerId": "",
"amount": 5000.00,
"destination": {
"bankCode": "001",
"branch": "1234",
"account": "56789",
"accountType": "CHECKING",
"taxNumber": "12345678900",
"holderName": "JOAO DA SILVA"
},
"description": "Supplier payment Invoice 12345"
}
}

Payload ted.out.confirmed

{
"eventType": "ted.out.confirmed",
"eventId": "ted-supplier-acme-2026-05-confirmed",
"data": {
"tedId": "ted-supplier-acme-2026-05",
"tenantId": "tenant-yourcompany",
"accountId": "773107de-...",
"partnerId": "supplier-acme-2026-05",
"amount": 5000.00,
"destination": { ... },
"description": "Supplier payment Invoice 12345"
}
}

Payload ted.out.failed

{
"eventType": "ted.out.failed",
"eventId": "ted-supplier-acme-2026-05-failed",
"data": {
"tedId": "ted-supplier-acme-2026-05",
"tenantId": "tenant-yourcompany",
"accountId": "773107de-...",
"partnerId": "supplier-acme-2026-05",
"amount": 5000.00,
"destination": { ... },
"description": "Supplier payment Invoice 12345",
"errorReason": "invalid_bank_code",
"error": "invalid_bank_code"
}
}

Payload ted.in.received

{
"eventType": "ted.in.received",
"eventId": "ted-in-abc123def",
"data": {
"transactionId": "abc123def",
"identifier": "TED-MT-9876",
"partnerTxId": "abc123def",
"accountId": "773107de-...",
"tenantId": "tenant-yourcompany",
"amount": 1200.00,
"description": "Payment received",
"receivedAt": "2026-05-23T14:15:22Z",
"payer": {
"name": "EMPRESA XYZ LTDA",
"document": "98765432000110",
"bankCode": "237",
"bankIspb": "60746948",
"branch": "0001",
"account": "123456",
"accountNumber": "123456"
}
}
}

Dedup

Every webhook has a unique deterministic eventId. Use the eventId in your store to dedupe in case of re-delivery (happens on retries of our dispatcher when your endpoint takes long to respond 2xx).

Common errors

HTTP codeerrorCodeWhen
400invalid_bank_codebankCode is not a valid Compe (3 digits) or ISPB (8 digits)
400invalid_tax_numbertaxNumber has neither 11 (CPF) nor 14 (CNPJ) digits
400invalid_account_typeaccountType outside CHECKING|SAVINGS|PAYMENT|SALARY
400invalid_identifieridentifier with non-ASCII chars or invalid size
400missing_fieldsvalue, branch, account, holderName, or taxNumber missing
403forbiddenUser has no role on the account's tenant
503temporal_unavailableInternal orchestrator unavailable (rare; wait and retry)
503partner_unavailableSettlement bank unavailable
404not_foundtedId not found in the GET status call

Workflow errors (final FAILED status)

errorReasonWhen
insufficient_fundsInsufficient balance on source account
invalid_bank_codeDestination bank does not exist in the SPB
outside_banking_hoursTED attempt outside the settlement bank's accepted window
bank_unreachableTransient error at destination bank
limit_exceededOperational limit reached
timeout aguardando confirmação do parceiro (>48h)Defensive polling expired without settlement

Reconciliation

CorpX runs defensive polling every minute for up to 48h after sending a TED, even when the settlement bank's webhook arrives normally. This guarantees that internal state and bank's real state are always aligned.

To reconcile on your side:

  • Real time: subscribe to webhooks ted.out.{requested,confirmed,failed} and ted.in.received
  • Point lookup: GET /v1/accounts/{accountId}/transfers/ted/{tedId}
  • Statement: GET /v1/accounts/{accountId}/statement (TEDs appear with operation=TED)
  • Detailed timeline: GET /v1/accounts/{accountId}/transactions/timeline?tedId={tedId}

ted.payment deprecation

The ted.payment event (v1 legacy catalog) is kept as an alias for ted.out.confirmed for compatibility. Both are dispatched together on the same terminal.

  • New integrators: subscribe to ted.out.confirmed (more descriptive, aligned with boleto.paid, pix.out.completed)
  • Legacy integrators: can keep ted.payment until v3.0 (date TBA)
  • Migration: unsubscribe ted.payment + subscribe ted.out.confirmed — payloads are identical