TF Fiscal
Documentation

CT-e

CT-e issuance on behalf of carriers (model 57, road modal): onboarding flow, endpoints, webhook payloads, error model, scope and integration checklist.

Overview

The CT-e API issues electronic transport documents (CT-e, model 57, road modal) on behalf of carriers, queries their status, cancels them and registers post-authorization events (correction letter, delivery receipt, delivery failure, service disagreement). Company registration, certificate association and webhook registration are shared with NF-e and only referenced here.

Path convention: the resource segment is the document category cte; every document-level operation lives under /openapi/v2/empresas/{empresaId}/cte/{cteId}, where cteId is the id you sent at issuance.

Onboarding flow

StepAPINotes
1 Register companyRegister companySame as NF-e; a carrier is a company like any other
2 Link certificateLink certificateSame as NF-e
3 Register webhookRegister webhookSame as NF-e; CT-e results reuse the same callback URL
4 IssueIssue CT-eAccepted immediately; authorized asynchronously with SEFAZ
5 QueryQuery CT-eStatus, document data, XML / DACTE download links, event list
6 CancelCancel CT-eWithin 168 hours after authorization
7 Eventssee the endpoint table belowCorrection letter / delivery receipt / delivery failure / service disagreement and their cancellations
8 Event listList eventsAll registered events

Prerequisites

  • The company must be approved with a usable certificate, and its CNPJ must be enabled for CT-e at the state tax authority (IE registered as a transport service provider and CT-e accreditation completed). Without it SEFAZ returns 230 - IE do emitente não cadastrada; this is a tax registration matter on the company side that the platform cannot resolve.
  • The company must have a CT-e number series (model 57). If none is configured, or several are enabled and the request does not pick one, the API returns 10017007.
  • Phase one supports the road modal (Rodoviario) only; other modals are rejected at acceptance (10017018).
  • ambienteEmissao must match the current environment of the company (10017010), see Environments.

Authentication

Identical to NF-e: headers token / timestamp / sign, with sign = MD5(token + path + body + timestamp) as lowercase hex; path includes the /openapi prefix and path variables and excludes the query string; GET / DELETE without a body use an empty string; a DELETE with a body (cancellation) signs the raw JSON with CR/LF removed. Algorithm details, reference implementations and troubleshooting are in Authentication.

Endpoints

All paths are relative to /openapi/v2/empresas/{empresaId}/cte.

MethodPathEndpointEvent
POST``Issue CT-eAsynchronous authorization
GET/{cteId}Query CT-e
DELETE/{cteId}Cancel CT-e110111
POST/{cteId}/carta-correcaoCorrection letter110110
POST/{cteId}/comprovante-entregaDelivery receipt110180
DELETE/{cteId}/comprovante-entrega/{protocoloEvento}Cancel delivery receipt110181
POST/{cteId}/insucesso-entregaDelivery failure110190
DELETE/{cteId}/insucesso-entrega/{protocoloEvento}Cancel delivery failure110191
POST/{chaveAcesso}/desacordoService disagreement610110
DELETE/{chaveAcesso}/desacordo/{protocoloEvento}Cancel service disagreement610111
GET/{cteId}/eventosList events

Every event is sent synchronously and, on success, returns the event object (chaveAcesso, tipo, codigo, sequencia, status, motivo, protocolo, data, linkXml). Text fields are sanitized (accents stripped, whitespace collapsed) before length validation; coordinates are registered with six decimals.

Note: the service disagreement endpoints are the only ones addressed by the access key of a CT-e issued by someone else: this company acts as receiver / taker of that document, and the event is routed to the state of that document.

Webhook payload

Webhook registration and signature headers are shared with NF-e, see Webhooks. Four event codes are emitted for CT-e:

Event codeTriggercteStatus
cte.authorizedAuthorization 100Autorizada
cte.rejectedSEFAZ rejection (cStat other than 100)Negada (cteMotivoStatus is cStat - reason); a terminal task failure (Falha) sends no callback, use the query API
cte.canceledCancellation 135Cancelada
cte.event.registeredAny other event registeredPlatform envelope; data carries event_code / n_seq / protocolo

cte.authorized, cte.rejected, cte.canceled

The three document-result events use the compatibility payload (tipo="CT-e", fixed field order), parallel to the NF-e nfe* fields:

json
{ "tipo": "CT-e", "empresaId": "1934811222334455", "cteId": "CTE-ORD-1", "cteStatus": "Autorizada", "cteMotivoStatus": null,
"cteLinkDacte": "https://.../openapi/files/dacte/3526...?token=...", "cteLinkXml": "https://.../openapi/files/xml/7?token=...", "cteNumero": "1", "cteSerie": "1",
"cteChaveAcesso": "3526...", "cteDataEmissao": "2026-09-06T12:00:00Z", "cteDataAutorizacao": "2026-09-06T12:00:03Z",
"cteNumeroProtocolo": "135260000000001", "cteDigestValue": "..." }
FieldTypeDescription
tipostringAlways CT-e
empresaIdstringCompany identifier
cteIdstringThe id sent at issuance
cteStatusstringAutorizada / Negada / Cancelada
cteMotivoStatusstringcStat - xMotivo for Negada; null otherwise
cteLinkDactestringDACTE PDF download link (rendered on the first download)
cteLinkXmlstringAuthorized XML (cteProc) download link
cteNumerostringCT-e number
cteSeriestringCT-e series
cteChaveAcessostring44-digit access key
cteDataEmissaostringIssue date, ISO-8601 UTC
cteDataAutorizacaostringAuthorization date, ISO-8601 UTC
cteNumeroProtocolostringSEFAZ authorization protocol
cteDigestValuestringDigestValue of the XML signature

cteLinkDacte and cteLinkXml are usable as soon as the authorization callback arrives (the DACTE is rendered on the first download); links need no signature headers, redirect with 302, and their validity and error codes are described in File download.

cte.event.registered

Emitted when any post-authorization event other than cancellation is registered (correction letter, delivery receipt, delivery failure, service disagreement and their cancellations). It uses the platform envelope (version / event_id / event_type / occurred_at / data):

json
{
"version": "1.0",
"event_id": "7312345678901234567",
"event_type": "cte.event.registered",
"occurred_at": "2026-09-06T13:00:00Z",
"data": {
"cte_id": "1001",
"chave": "35260940673061000134570010000000011000000010",
"external_ref": "CTE-ORD-1",
"event_code": "110110",
"n_seq": 1,
"protocolo": "135260000000099"
}
}
FieldTypeDescription
versionstringPayload version, 1.0
event_idstringEvent identifier; identical across retries, use it for deduplication
event_typestringcte.event.registered
occurred_atstringRegistration time, ISO-8601 UTC
data.cte_idstringInternal document identifier on the platform
data.chavestring44-digit access key
data.external_refstringThe id sent at issuance
data.event_codestringSEFAZ event code (110110, 110180, 110181, 110190, 110191, 610110, 610111)
data.n_seqintegerEvent sequence number
data.protocolostringEvent protocol number

Error model

Same shapes as NF-e: business errors are [{ "codigo", "mensagem" }] (HTTP 400; a missing document / task is HTTP 404 with codigo CTe0001); authentication-layer errors use the platform envelope (401 / 403 / 429, see Authentication).

codigoScenarioAction
CTe0001cteId not found or not owned by the companyCheck id and empresaId
10003000empresaId not foundCheck empresaId
10017004Company cannot issue (not approved / certificate not ready)Wait for approval / link the certificate
10017005 / 10017006Concurrent duplicate request / too many pending tasks for the CNPJRetry later
10017007Number series unresolved (none configured, or several enabled without a choice)Configure a model 57 series
10017010ambienteEmissao differs from the environment of the companySubmit for the company environment
10017011Municipality IBGE code not foundCheck codigoIbge
10017012 / 10017013Party missing / taker inconsistent with the IE indicatorAdd the party or change indicadorIeTomador
10017014Invalid document references (missing, bad check digit, mixed groups, previous documents inconsistent with the service type)Adjust per the issuance field table
10017015Document type inconsistent with references (complementary / substitute)Send ctesComplementados / cteSubstituido per tipo
10017016Components do not sum to the total, or aReceber > totalFix the amounts
10017017 / 10017018 / 10017019Invalid RNTRC / unsupported modal / invalid enum or format (mensagem names the field)Fix per mensagem
10017020 / 10017021 / 10017022 / 10017023 / 10017024 / 10017025Tax parameter missing / not allowed / regime mismatch / icmsUfFim required / rate table row missing / unsupported CSTSee the tax parameters section of Issue CT-e
10017030Same id with a different messageUse a new id or resend the original message
10017031Production: an active / authorized document already exists for the idQuery the original
10017040 / 10017041 / 10017042 / 10017043 / 10017044 / 10017045Status does not allow the event / cancellation window exceeded / invalid event text / SEFAZ rejected the event / correction sequence limit / referenced event not foundSee the cancellation and event endpoints
10017048 / 10017049Cancellation blocked by a registered correction letter / correction letter outside the 720-hour windowSee the cancellation and correction letter endpoints
10001001Request field validation failed (one entry per field)Fix per mensagem

SEFAZ rejections during issuance are not HTTP errors: they surface as query status Negada and the cte.rejected webhook.

Scope and limitations

  • Model 57 CT-e 4.00, road modal; normal / complementary / substitute documents; all five service types.
  • Tax groups ICMS 00 / 20 / 40 / 41 / 51 / 60 / 90 / OutraUF / SN + ICMSUFFim + vTotTrib; IBS/CBS in phase two.
  • Contingency: SVC (SVC-RS / SVC-SP) and EPEC are switched by the platform per state, transparently to integrators; tipoEmissao in the query shows it. Events for documents authorized under contingency are still sent to the regular authorizer of the state.
  • Not supported: other modals, multimodal, GTV, CT-e OS (model 67), inbound document distribution (DistDFe).

Integration checklist

  1. In the certification environment: company registered, certificate linked, CT-e number series configured.
  2. Issue a minimal CT-e (the example on Issue CT-e), query it as Autorizada, download the XML and the DACTE.
  3. Resend the same id once and confirm HTTP 200 with no second document created.
  4. Register one correction letter and one delivery receipt, see them in the event list, then cancel the delivery receipt.
  5. Cancel the document, query it as Cancelada, receive the cte.canceled callback.
  6. Send deliberate errors (modal Aereo, component sum mismatch) and confirm the 400 error array.