Emitir CT-e POST
Emite um Conhecimento de Transporte Eletrônico (modelo 57) -- documento fiscal do transportador, referenciando as NF-e da carga transportada. Hoje só o modal rodoviário é suportado.
Quando utilizar
Sempre que sua transportadora prestar um serviço de transporte de carga (não de pessoas nem de valores -- isso é CT-e OS, modelo 67, fora desta página) e precisar emitir o documento fiscal correspondente, referenciando as NF-e transportadas.
Pré-requisitos
- Contribuinte (transportador) já cadastrado --
POST /v1/contribuintes. - Certificado digital A1 vinculado ao contribuinte.
- RNTRC (Registro Nacional de Transportadores Rodoviários de Carga) do emitente -- obrigatório, sem fallback.
- Chave de acesso das NF-e transportadas (44 dígitos) -- é o único tipo de documento referenciável hoje.
-
Responsável técnico cadastrado na sua conta -- CNPJ, nome, e-mail e
telefone, preenchidos em Área do Cliente → Responsável Técnico (sem
campo equivalente no corpo desta requisição -- resolvido automaticamente pela API).
Bloqueante: sem isso a emissão falha com
status: "ERROR". Ver detalhes na doc de NF-e.
ide.modal hoje não tem efeito. O
motor sempre gera CT-e rodoviário, independente do que você enviar nesse campo (ou mesmo
se omitir) -- não existe erro nem aviso, o valor é silenciosamente ignorado. Aéreo,
aquaviário, ferroviário e dutoviário não são suportados de fato hoje.
Só ICMS é de fato transmitido, com icms.cst roteando pro
grupo certo do XML: 00 (normal), 20 (BC reduzida),
40/41/51 (isento/não tributado/diferido),
60 (substituição tributária) ou 90 (outros). Se o emitente é
do Simples Nacional (crt: "1"), o motor sempre monta ICMSSN e
ignora icms.cst -- ver detalhes no campo icms abaixo.
ICMSOutraUF ainda não tem grupo próprio no XML. PIS/COFINS não
existem no CT-e modelo 57 (não é gap, é o layout nacional mesmo -- esses
tributos são apurados mensalmente pelo prestador, não por documento) -- enviar
impostos.pis/impostos.cofins é rejeitado com erro
400, não descartado silenciosamente.
impostos.ibs_cbs) agora é calculado/transmitido.
Grupo opcional -- diferente da NF-e (onde o grupo é exigido pela SEFAZ mesmo com alíquota
zero durante o período de teste de 2026), não há confirmação de que a mesma regra vale
pro CT-e, então o motor só monta o grupo quando você o envia explicitamente. Quando
enviado, base_calculo é sempre obrigatória (sem fórmula automática) e
aliquota_ibs_uf/aliquota_cbs/valor_ibs_uf/
valor_cbs são opcionais -- omitidos, o motor calcula a partir da
classificacao_tributaria (mesma tabela e mesmo cálculo já usados na NF-e/
NFS-e).
Fluxo da operação
POST já
monta, assina e transmite pra SEFAZ -- a resposta já vem com status final
(AUTHORIZED/REJECTED/ERROR/PROCESSING),
não um "recebido, consulte depois". GET /v1/cte/emissoes/{transmissao_id}
continua disponível pra reconsulta, mas normalmente não é necessário logo após o
POST.
Endpoint
Headers
| Header | Valor | |
|---|---|---|
Authorization | Bearer <sua_api_key> | obrigatório |
Content-Type | application/json | obrigatório |
Idempotency-Key | string livre, definida por você | opcional |
Body
Clique num campo com ▸ pra expandir.
"0""0"1 (Complemento de Valores) exige o objeto complemento no corpo (ver abaixo) -- substitui todo o corpo normal do CT-e, os campos carga/documentos/rodoviario continuam obrigatórios no payload mas são ignorados na montagem do XML. 3 (Substituição) exige o objeto substituicao -- mantém o corpo normal, só anexa a referência ao CT-e original.tipo: "3", vedado quando "1".cst pro subgrupo certo (ICMS00/20/45/60/90). Simples Nacional (emitente.crt: "1") ignora cst e sempre monta ICMSSN."00". Ignorado se o emitente for Simples Nacional.cst for 40/41/51 (o XSD desse grupo não carrega base/alíquota/valor) ou se o emitente for Simples Nacional -- ainda assim precisa ser enviado (contrato exige os 3 campos sempre).base_calculo.base_calculo.cst: "60".pis.icms. Só se aplica a prestação interestadual pra consumidor final não contribuinte do ICMS -- opcional, omita pra não emitir o grupo. Sem cálculo automático: os 7 campos são passthrough puro, calcule antes com POST /v1/tributario/icms/difal e informe os valores prontos.icms. Opcional -- omita pra não emitir o grupo (ver aviso abaixo).classificacao_tributaria (mesmo cálculo da NF-e/NFS-e). Informados, são só transmitidos, nunca recalculados.cobranca da NF-e.ide.tipo_cte: "1" (Complemento de Valores), ignorado nos demais casos. Substitui todo o corpo normal do CT-e (carga/documentos/rodoviario/cobranca/etc do payload são ignorados na montagem do XML quando tipo_cte é "1").ide.tipo_cte: "3" (Substituição), ignorado nos demais casos. Diferente do Complemento, mantém o corpo normal do CT-e -- só anexa a referência ao original.valores.componentes com um item nomeado "SEGURO".Exemplo mínimo
Apenas os campos obrigatórios -- veja o código ao lado.
Resposta de sucesso
200 OK -- já com o resultado final da SEFAZ nesta mesma resposta
(status: "AUTHORIZED" em caso de sucesso). O campo detalhes traz o
cstat/xmotivo reais devolvidos pela SEFAZ, além do protocolo.
Notificação assíncrona
Diferente da NF-e/NFC-e (que ainda não têm isso), cancelamento e Carta de Correção
do CT-e aceitam callback_url opcional. Se enviado, a CentralFiscal faz
um POST pra essa URL assim que o evento terminar na SEFAZ (fire-and-forget,
timeout de 8s -- falha ao entregar o callback vira só um log, nunca afeta a resposta
síncrona original). tipoEvento vem "cancelamento" ou
"carta_correcao", conforme o evento -- veja o corpo do callback ao lado. A
chamada síncrona original já retorna o resultado completo -- o webhook é só uma
conveniência pra quem prefere não deixar a requisição aberta esperando.
Cancelamento
POST /v1/cte/cancelamentos -- mesmo padrão de evento da NF-e: exige
chave_acesso, protocolo (da autorização original) e
justificativa com pelo menos 15 caracteres. Aceita callback_url
opcional -- ver Notificação assíncrona acima.
Carta de Correção Eletrônica (CCe)
POST /v1/cte/cartas-correcao -- evento 110110. Não cancela nem corrige
valores, impostos ou participantes -- só serve para os campos que a legislação
permite corrigir por evento (dados cadastrais, texto de observações etc.). O CT-e original
continua AUTHORIZED em caso de sucesso -- é isso que aparece no campo
status da resposta, não um estado novo. Exige chave_acesso e
correcoes (lista de {grupo_alterado, campo_alterado, valor_alterado},
pelo menos um item). Aceita callback_url opcional.
Consultas
Duas consultas síncronas direto na SEFAZ (não criam evento nem alteram nada em
platform.fiscal_transmission -- são só perguntas):
POST /v1/cte/consultas/protocolo-- reconsulta o resultado de uma transmissão pelachave_acesso. Útil quando a emissão ou o cancelamento voltou comstatus: "INDETERMINATE"e você quer confirmar o desfecho real sem esperar o retry automático.POST /v1/cte/consultas/status-servico-- pergunta se o webservice de autorização da SEFAZ da UF está no ar. Exigeuf(oucodigo_ufdiretamente) -- não depende de nenhum documento.
Outros eventos
Além de Cancelamento/CCe, o CT-e tem outros eventos oficiais -- nenhum deles muda o
status do CT-e (continua AUTHORIZED), cada um só registra algo a
mais no histórico do documento. Todos aceitam callback_url opcional (mesmo
formato de webhook do Cancelamento/CCe).
POST /v1/cte/registros-multimodal-- evento 110160, Registro Multimodal. Só se aplica quando este CT-e presta serviço vinculado a um CT-e multimodal (verservico_vinculadona emissão). Exigechave_acessoeregistro(texto livre, 15-1000 caracteres);numero_documentoé opcional.POST /v1/cte/prestacoes-desacordo-- evento 610110, Prestação do Serviço em Desacordo. Registrado pelo tomador quando o serviço não ocorreu conforme combinado. Exigechave_acessoeobservacao(texto livre, 15-255 caracteres).POST /v1/cte/prestacoes-desacordo/cancelamentos-- evento 610111, cancela um evento de Prestação em Desacordo já registrado. Exigechave_acessoeprotocolo_evento_original(protocolo do evento 610110 a cancelar).POST /v1/cte/vinculacoes-pagamento-- evento 110300 (Reforma Tributária). Diferente deimpostos.pagamento_vinculadona emissão (que vai dentro do XML na hora de emitir): este é um evento registrado depois, referenciando oprotocolode autorização do CT-e. Exigechave_acesso,protocoloepagamento(mesmos 5 campos deimpostos.pagamento_vinculado.pagamentos[]-- ver seção de impostos acima).POST /v1/cte/vinculacoes-pagamento/cancelamentos-- evento 110301, cancela uma Vinculação de Pagamento já registrada. Exigechave_acesso,protocolo(do CT-e) eprotocolo_evento_original(do evento 110300 a cancelar).POST /v1/cte/comprovantes-entrega-- evento 110180, Comprovante de Entrega Eletrônico. Exigechave_acesso,protocolo,data_hora_entrega,documento_recebedor(2-20 caracteres),nome_recebedor(2-60 caracteres),hash_entrega(SHA1+Base64 -- fornecido pronto por quem capturou a assinatura/foto da entrega, a CentralFiscal nunca calcula esse hash) edata_hora_hash_entrega.latitude/longitudeechaves_nfe_entregues[](até 2000 chaves) são opcionais.POST /v1/cte/comprovantes-entrega/cancelamentos-- evento 110181, cancela um Comprovante de Entrega já registrado. Exigechave_acesso,protocoloeprotocolo_evento_original(do evento 110180 a cancelar).POST /v1/cte/insucessos-entrega-- evento 110190, Insucesso na Entrega Eletrônico. Exigechave_acesso,protocolo,data_hora_tentativa_entregaetipo_motivo(1recebedor não encontrado,2recusa do recebedor,3endereço inexistente,4outros -- exigejustificativa_motivojunto, 15-256 caracteres).numero_tentativa,latitude/longitude,hash_tentativa_entrega+data_hora_hash_tentativa_entregaechaves_nfe_com_insucesso[]são opcionais.POST /v1/cte/insucessos-entrega/cancelamentos-- evento 110191, cancela um Insucesso na Entrega já registrado. Exigechave_acesso,protocoloeprotocolo_evento_original(do evento 110190 a cancelar).POST /v1/cte/epec-- evento 110113, EPEC (Emissão Prévia em Contingência). Diferente dos demais: não referencia um protocolo -- é declarado antes da autorização, quando o webservice de autorização da SEFAZ está fora do ar. É um replay dos próprios dados do CT-e: exigechave_acesso,justificativa(15+ caracteres),valor_icms,valor_prestacao,valor_carga,tomador(papel0-4,uf,documento,inscricao_estadualopcional),uf_inicio,uf_fimedata_hora_emissao(do CT-e original).valor_icms_sté opcional.
GET
/v1/cte/registros-multimodal/{id}, GET
/v1/cte/prestacoes-desacordo/{id}, GET
/v1/cte/vinculacoes-pagamento/{id}, GET
/v1/cte/comprovantes-entrega/{id}, GET
/v1/cte/epec/{id} ou GET
/v1/cte/insucessos-entrega/{id} (mesmo transmissao_id devolvido na
resposta de criação).
O que ainda não existe
Único grupo do leiaute oficial (cteTiposBasico_v4.00.xsd, versão RTC da
Reforma Tributária) que o motor ainda não suporta:
IS/ISTot dentro de <imp> -- diferente
da NF-e, que já tem os dois opcionais no próprio XSD (também sem motor). Também não existe
hoje nenhuma tabela oficial de produto/alíquota de IS carregada na CentralFiscal. Sem os
dois, não há como emitir CT-e com IS ainda, independente de reforma no motor.
Próximos passos
- Reconsultar mais tarde, se precisar:
GET /v1/cte/emissoes/{transmissao_id}ouPOST /v1/cte/consultas/protocolo. - Cancelar, se necessário:
POST /v1/cte/cancelamentos. - Corrigir um dado cadastral/observação sem cancelar:
POST /v1/cte/cartas-correcao. - Baixar o DACTE (PDF) de um CT-e autorizado: disponível na Área do Cliente → Transmissões, mesmo padrão do DANFE (NF-e) -- não é exposto como URL na resposta desta API.
- Transporte de pessoas/valores/excesso de bagagem é outro documento -- CT-e OS (modelo 67), fora desta página.