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
| Step | API | Notes |
|---|---|---|
| 1 Register company | Register company | Same as NF-e; a carrier is a company like any other |
| 2 Link certificate | Link certificate | Same as NF-e |
| 3 Register webhook | Register webhook | Same as NF-e; CT-e results reuse the same callback URL |
| 4 Issue | Issue CT-e | Accepted immediately; authorized asynchronously with SEFAZ |
| 5 Query | Query CT-e | Status, document data, XML / DACTE download links, event list |
| 6 Cancel | Cancel CT-e | Within 168 hours after authorization |
| 7 Events | see the endpoint table below | Correction letter / delivery receipt / delivery failure / service disagreement and their cancellations |
| 8 Event list | List events | All 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). ambienteEmissaomust 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.
| Method | Path | Endpoint | Event |
|---|---|---|---|
| POST | `` | Issue CT-e | Asynchronous authorization |
| GET | /{cteId} | Query CT-e | |
| DELETE | /{cteId} | Cancel CT-e | 110111 |
| POST | /{cteId}/carta-correcao | Correction letter | 110110 |
| POST | /{cteId}/comprovante-entrega | Delivery receipt | 110180 |
| DELETE | /{cteId}/comprovante-entrega/{protocoloEvento} | Cancel delivery receipt | 110181 |
| POST | /{cteId}/insucesso-entrega | Delivery failure | 110190 |
| DELETE | /{cteId}/insucesso-entrega/{protocoloEvento} | Cancel delivery failure | 110191 |
| POST | /{chaveAcesso}/desacordo | Service disagreement | 610110 |
| DELETE | /{chaveAcesso}/desacordo/{protocoloEvento} | Cancel service disagreement | 610111 |
| GET | /{cteId}/eventos | List 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 code | Trigger | cteStatus |
|---|---|---|
cte.authorized | Authorization 100 | Autorizada |
cte.rejected | SEFAZ rejection (cStat other than 100) | Negada (cteMotivoStatus is cStat - reason); a terminal task failure (Falha) sends no callback, use the query API |
cte.canceled | Cancellation 135 | Cancelada |
cte.event.registered | Any other event registered | Platform 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:
{ "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": "..." }
| Field | Type | Description |
|---|---|---|
tipo | string | Always CT-e |
empresaId | string | Company identifier |
cteId | string | The id sent at issuance |
cteStatus | string | Autorizada / Negada / Cancelada |
cteMotivoStatus | string | cStat - xMotivo for Negada; null otherwise |
cteLinkDacte | string | DACTE PDF download link (rendered on the first download) |
cteLinkXml | string | Authorized XML (cteProc) download link |
cteNumero | string | CT-e number |
cteSerie | string | CT-e series |
cteChaveAcesso | string | 44-digit access key |
cteDataEmissao | string | Issue date, ISO-8601 UTC |
cteDataAutorizacao | string | Authorization date, ISO-8601 UTC |
cteNumeroProtocolo | string | SEFAZ authorization protocol |
cteDigestValue | string | DigestValue 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):
{"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"}}
| Field | Type | Description |
|---|---|---|
version | string | Payload version, 1.0 |
event_id | string | Event identifier; identical across retries, use it for deduplication |
event_type | string | cte.event.registered |
occurred_at | string | Registration time, ISO-8601 UTC |
data.cte_id | string | Internal document identifier on the platform |
data.chave | string | 44-digit access key |
data.external_ref | string | The id sent at issuance |
data.event_code | string | SEFAZ event code (110110, 110180, 110181, 110190, 110191, 610110, 610111) |
data.n_seq | integer | Event sequence number |
data.protocolo | string | Event 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).
| codigo | Scenario | Action |
|---|---|---|
| CTe0001 | cteId not found or not owned by the company | Check id and empresaId |
| 10003000 | empresaId not found | Check empresaId |
| 10017004 | Company cannot issue (not approved / certificate not ready) | Wait for approval / link the certificate |
| 10017005 / 10017006 | Concurrent duplicate request / too many pending tasks for the CNPJ | Retry later |
| 10017007 | Number series unresolved (none configured, or several enabled without a choice) | Configure a model 57 series |
| 10017010 | ambienteEmissao differs from the environment of the company | Submit for the company environment |
| 10017011 | Municipality IBGE code not found | Check codigoIbge |
| 10017012 / 10017013 | Party missing / taker inconsistent with the IE indicator | Add the party or change indicadorIeTomador |
| 10017014 | Invalid document references (missing, bad check digit, mixed groups, previous documents inconsistent with the service type) | Adjust per the issuance field table |
| 10017015 | Document type inconsistent with references (complementary / substitute) | Send ctesComplementados / cteSubstituido per tipo |
| 10017016 | Components do not sum to the total, or aReceber > total | Fix the amounts |
| 10017017 / 10017018 / 10017019 | Invalid RNTRC / unsupported modal / invalid enum or format (mensagem names the field) | Fix per mensagem |
| 10017020 / 10017021 / 10017022 / 10017023 / 10017024 / 10017025 | Tax parameter missing / not allowed / regime mismatch / icmsUfFim required / rate table row missing / unsupported CST | See the tax parameters section of Issue CT-e |
| 10017030 | Same id with a different message | Use a new id or resend the original message |
| 10017031 | Production: an active / authorized document already exists for the id | Query the original |
| 10017040 / 10017041 / 10017042 / 10017043 / 10017044 / 10017045 | Status does not allow the event / cancellation window exceeded / invalid event text / SEFAZ rejected the event / correction sequence limit / referenced event not found | See the cancellation and event endpoints |
| 10017048 / 10017049 | Cancellation blocked by a registered correction letter / correction letter outside the 720-hour window | See the cancellation and correction letter endpoints |
| 10001001 | Request 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;
tipoEmissaoin 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
- In the certification environment: company registered, certificate linked, CT-e number series configured.
- Issue a minimal CT-e (the example on Issue CT-e), query it as
Autorizada, download the XML and the DACTE. - Resend the same
idonce and confirm HTTP 200 with no second document created. - Register one correction letter and one delivery receipt, see them in the event list, then cancel the delivery receipt.
- Cancel the document, query it as
Cancelada, receive thecte.canceledcallback. - Send deliberate errors (modal
Aereo, component sum mismatch) and confirm the 400 error array.
