# Guia de integração — CT-e e MDF-e pela API do Emissor · Nota Central

Este guia cobre a integração completa dos documentos de transporte. Leia junto com a referência técnica `https://emite-api.notacentral.com.br/openapi.yaml` (grupos **CT-e** e **MDF-e**). Base da API: `https://emite-api.notacentral.com.br`. Todas as respostas são JSON em português no envelope `{"dados": …, "meta": …}`; erros vêm como `{"erro": "codigo", "mensagem": "…", "campos": [...]}`.

## 0. Resumo do fluxo

1. Obter a credencial (`nce_…`) da empresa ou do workspace.
2. `GET /v1/empresa` — conferir `cotas` (cte/mdfe ativas) e `transporte.prontidao` (o que falta no cadastro).
3. `PUT /v1/empresa/transporte` — ambiente (homologação/produção), séries, tipo de emitente, IE, CRT, RNTRC.
4. `PUT /v1/numeracao` com `documento: cte` e `mdfe` — próximo número (obrigatório na migração de outro emissor).
5. `POST /v1/tomadores` — remetentes e destinatários com endereço completo (CT-e).
6. `PUT /v1/veiculos` e `PUT /v1/condutores` — frota (MDF-e).
7. `POST /v1/cte` → `GET /v1/cte/{id}` até `emitida`.
8. `POST /v1/mdfe` (com as chaves dos CT-e/NF-e) → `GET /v1/mdfe/{id}` até `emitida` → `POST /v1/mdfe/{id}/encerrar` no destino.
9. Eventos: carta de correção (CT-e), inclusão de condutor (MDF-e), cancelamento (`POST /v1/notas/{id}/cancelar`).

## 1. Credencial e escopo

- Header em toda chamada: `Authorization: Bearer nce_SUA_CREDENCIAL`.
- Credencial **por empresa**: já identifica o emitente; nunca envie `empresa_id`.
- Credencial **de workspace** (integradora com várias transportadoras): envie `empresa_id` no corpo (POST/PUT) ou na query (GET). Liste as empresas em `GET /v1/empresas`.
- Limite: 120 requisições/minuto por credencial (HTTP 429). Faça polling a cada 2–3 s com timeout de 1 minuto.

## 2. Pré-requisitos da empresa (uma vez por CNPJ)

| Item | CT-e | MDF-e | Como resolver |
|---|---|---|---|
| Cota ativa (`cotas.cte` / `cotas.mdfe`) | sim | sim | Contratada com o Nota Central e ativada em *Nota Central › Emissor* |
| Certificado A1 | sim | sim | Enviado pelo painel ou pelo link de onboarding |
| Inscrição estadual | sim | sim | `PUT /v1/empresa/transporte` `{"inscricao_estadual": "…"}` |
| CRT (1 Simples · 2 Simples excesso · 3 Regime normal · 4 MEI) | sim | não | `PUT /v1/empresa/transporte` `{"crt": 3}` |
| RNTRC (8 dígitos) | sim | se `tipo_emitente` = 1 | `PUT /v1/empresa/transporte` `{"rntrc": "12345678"}` |
| Endereço completo (logradouro, bairro, município IBGE, UF) | sim | sim | Cadastro da empresa no Nota Central |

`GET /v1/empresa` devolve `transporte.prontidao.cte.falta` e `transporte.prontidao.mdfe.falta` com exatamente o que está faltando (`inscricao_estadual`, `crt`, `rntrc`, `endereco`). Só emita quando `pronto` for `true`.

## 3. Ambiente: homologação antes de produção

```json
PUT /v1/empresa/transporte
{"ambiente": "homologacao", "serie_cte": 1, "serie_mdfe": 1, "tipo_emitente": 1}
```

- `ambiente` vale para CT-e e MDF-e da empresa. Em homologação a SEFAZ autoriza documentos **sem valor fiscal** e a resposta traz `chave_acesso`, XML e PDF iguais aos de produção.
- `tipo_emitente`: 1 prestador de serviço de transporte (transportadora, exige RNTRC), 2 transportador de carga própria, 3 prestador com CT-e globalizado.
- Troque para `producao` só depois de autorizar em homologação. Lembre-se de ajustar a numeração de produção (passo 4).

## 4. Numeração (migração de outro emissor)

Cada documento e série tem a própria sequência. Quem vem de outro emissor precisa informar o próximo número **antes** da primeira emissão, senão o documento sai com o número 1 e a SEFAZ recusa por duplicidade.

```json
GET /v1/numeracao?documento=cte
PUT /v1/numeracao
{"documento": "cte", "serie": "1", "proximo_numero": 4581}

PUT /v1/numeracao
{"documento": "mdfe", "serie": "1", "proximo_numero": 912}
```

Retrocesso sobre número já usado aqui responde `409 numero_ja_utilizado`. Homologação e produção compartilham a sequência: ajuste ao virar para produção.

## 5. Cadastros

### Tomadores (partes do CT-e)

Remetente, destinatário, expedidor e recebedor do CT-e vêm com endereço completo no corpo do pedido. Você pode manter o cadastro em `POST /v1/tomadores` e reaproveitar, mas o CT-e aceita os dados inline (`remetente`, `destinatario`, `expedidor`, `recebedor`, `tomador_outros`).

### Frota (MDF-e)

```json
PUT /v1/veiculos
{"placa": "ABC1D23", "tipo": "tracao", "tara_kg": 8000, "capacidade_kg": 20000, "tipo_rodado": "03", "tipo_carroceria": "02", "uf": "SP", "renavam": "12345678901"}

PUT /v1/veiculos
{"placa": "XYZ9876", "tipo": "reboque", "tara_kg": 6000, "capacidade_kg": 25000, "tipo_carroceria": "02", "uf": "SP"}

PUT /v1/condutores
{"nome": "JOAO MOTORISTA", "cpf": "52998224725"}
```

- `tipo_rodado`: 01 truck · 02 toco · 03 cavalo mecânico · 04 van · 05 utilitário · 06 outros (só tração).
- `tipo_carroceria`: 00 não aplicável · 01 aberta · 02 fechada/baú · 03 graneleira · 04 porta-contêiner · 05 sider.
- Veículo de terceiro/agregado: envie `cpf_cnpj_proprietario`, `nome_proprietario`, `rntrc_proprietario`, `ie_proprietario` (ou ISENTO), `uf_proprietario`, `tipo_proprietario` (0 TAC agregado · 1 TAC independente · 2 outros).
- O MDF-e também aceita o veículo inline em `rodoviario.tracao` — a frota é conveniência, não obrigação.

## 6. CT-e

```json
POST /v1/cte
{
  "referencia_externa": "FRETE-2026-000123",
  "tipo_servico": 0,
  "cfop": "6353",
  "natureza_operacao": "PRESTACAO DE SERVICO DE TRANSPORTE",
  "inicio": {"codigo": "3550308", "nome": "Sao Paulo", "uf": "SP"},
  "fim":    {"codigo": "3304557", "nome": "Rio de Janeiro", "uf": "RJ"},
  "tomador": 0,
  "indicador_ie_tomador": 1,
  "remetente":    {"cpf_cnpj": "98765432000100", "inscricao_estadual": "987654321098", "nome": "EMBARCADOR SA",
                   "endereco": {"logradouro": "Rua A", "numero": "10", "bairro": "Centro", "codigo_municipio": "3550308", "municipio": "Sao Paulo", "uf": "SP", "cep": "01001000"}},
  "destinatario": {"cpf_cnpj": "11222333000181", "inscricao_estadual": "ISENTO", "nome": "LOJA DO RIO LTDA",
                   "endereco": {"logradouro": "Av. B", "numero": "200", "bairro": "Centro", "codigo_municipio": "3304557", "municipio": "Rio de Janeiro", "uf": "RJ"}},
  "valores":  {"total": 1500.00, "componentes": [{"nome": "FRETE PESO", "valor": 1400.00}, {"nome": "PEDAGIO", "valor": 100.00}]},
  "impostos": {"icms": {"cst": "00", "base": 1500.00, "aliquota": 12, "valor": 180.00}},
  "carga":    {"valor": 150000.00, "produto": "Equipamentos eletronicos",
               "medidas": [{"unidade": "01", "medida": "PESO BRUTO", "quantidade": 1250.5}, {"unidade": "03", "medida": "VOLUMES", "quantidade": 40}]},
  "documentos": {"chaves_nfe": ["35260998765432000100550010000001231000001236"]},
  "observacoes": "Entrega em horario comercial"
}
```

Resposta `202`:

```json
{"dados": {"id": "2f0c…", "documento": "cte", "situacao": "na_fila", "numero_dps": 4581, "serie_dps": "1", "valor": 1500}}
```

`GET /v1/cte/{id}` quando autorizado:

```json
{"dados": {"id": "2f0c…", "documento": "cte", "situacao": "emitida", "chave_acesso": "35260912345678000195570010000045811000045810", "emitida_em": "2026-09-24T10:12:03-03:00",
  "links": {"xml": "https://emite-api.notacentral.com.br/nfse/…/….xml", "pdf": "https://…/….pdf", "dacte": "https://…/….pdf", "danfse": "https://…/….pdf"}}}
```

Regras que valem sempre:

- `tomador`: 0 remetente · 1 expedidor · 2 recebedor · 3 destinatário · 4 outros (aí envie `tomador_outros`). A parte apontada precisa existir no corpo.
- `indicador_ie_tomador`: 1 contribuinte · 2 isento · 9 não contribuinte.
- `cfop` em branco: 5353 na mesma UF, 6353 interestadual. `natureza_operacao` em branco: "PRESTACAO DE SERVICO DE TRANSPORTE".
- ICMS: `cst` 00 (normal), 20 (redução de base: envie `reducao_base`), 40/41/51 (sem valores), 60 (ST retido: `base_st_retido`, `valor_st_retido`, `aliquota_st_retido`), 90 (outros). Empresa do Simples (CRT 1) usa o grupo do Simples automaticamente; para forçar, `"simples_nacional": true`. ICMS devido à UF de término: `"outra_uf": true` com `base`, `aliquota`, `valor`.
- `carga.medidas`: pelo menos uma. `unidade` 00 M3 · 01 KG · 02 TON · 03 unidade · 04 litros · 05 MMBTU.
- `documentos`: `chaves_nfe` (44 dígitos) e/ou `outros` (`tipo` 00 declaração · 10 dutoviário · 59 CF-e SAT · 65 NFC-e · 99 outros).
- Complemento de valores: `"tipo": 1` + `chaves_complementadas`. Substituição: `"tipo": 3` + `chave_substituida`.
- `referencia_externa`: repetir o mesmo pedido devolve `200` com o CT-e original (`meta.repetida: true`). Use o id do frete no seu sistema.

Carta de correção (só campos que não mudam valor, partes ou datas):

```json
POST /v1/cte/{id}/carta-correcao
{"correcoes": [{"grupo": "compl", "campo": "xObs", "valor": "Entrega em horario comercial, portaria 2"}]}
```

## 7. MDF-e

```json
POST /v1/mdfe
{
  "referencia_externa": "VIAGEM-2026-000045",
  "viagem": {"uf_inicio": "SP", "uf_fim": "RJ", "municipios_carregamento": [{"codigo": "3550308", "nome": "Sao Paulo"}], "ufs_percurso": ["MG"]},
  "rodoviario": {
    "ciots": [{"codigo": "123456789012", "cpf_cnpj": "12345678000195"}],
    "tracao": {"placa": "ABC1D23", "tara_kg": 8000, "capacidade_kg": 20000, "tipo_rodado": "03", "tipo_carroceria": "02", "uf": "SP",
               "condutores": [{"nome": "JOAO MOTORISTA", "cpf": "52998224725"}]},
    "reboques": [{"placa": "XYZ9876", "tara_kg": 6000, "capacidade_kg": 25000, "tipo_carroceria": "02", "uf": "SP"}],
    "pagamentos": [{"nome": "JOAO MOTORISTA", "cpf_cnpj": "52998224725", "componentes": [{"tipo": "99", "valor": 2500, "descricao": "Frete"}], "valor_contrato": 2500, "prazo": 0, "banco": {"pix": "joao@pix.com"}}]
  },
  "descargas": [{"municipio_descarga": {"codigo": "3304557", "nome": "Rio de Janeiro"},
                 "chaves_cte": ["35260912345678000195570010000045811000045810"]}],
  "produto": {"tipo_carga": "05", "descricao": "Equipamentos eletronicos"},
  "totais": {"valor_carga": 150000.00, "unidade": "01", "peso_carga": 12500.5}
}
```

- `tipo_emitente` e `tipo_transportador` em branco caem no padrão da empresa (`PUT /v1/empresa/transporte`).
- `rodoviario.rntrc` em branco = RNTRC da empresa.
- `rodoviario.pagamentos` (pagamento do frete ao transportador) é obrigatório quando você contrata TAC/autônomo. `banco`: `pix`, ou `codigo_banco` + `agencia`, ou `cnpj_ipef`.
- `ciots`: o CIOT vem de duas exigências que se somam. **ANTT**: a Resolução 6.078/2026 o tornou obrigatório desde 24/05/2026 em toda contratação de TAC (motorista autônomo) e a 6.090/2026 estendeu o registro a TODA operação remunerada de transporte rodoviário de cargas desde 18/09/2026 — sem TAC, quem registra é a ETC que realiza o transporte; a multa é de R$ 10.500 por contratação sem CIOT. **SEFAZ**: a NT 2026.001 do MDF-e criou a rejeição **684** para o transporte remunerado de carga de terceiros sem o grupo — já em vigor na HOMOLOGAÇÃO desde 21/09/2026 e em PRODUÇÃO a partir de **23/11/2026**. Obtenha o CIOT na sua PSP e informe aqui (12 dígitos + CPF/CNPJ do responsável). Quem emite com `tipo_emitente` 1 ou 3 já é barrado no pré-voo quando a data da regra vale para o ambiente: o pedido volta com `dados_incompletos` em vez de queimar número numa rejeição certa. Carga própria (`tipo_emitente` 2) não precisa.
- Ao menos um município de carregamento, um de descarga e um documento vinculado (`chaves_cte`, `chaves_nfe` ou `chaves_mdfe`, 44 dígitos).
- Placa no padrão Mercosul (`ABC1D23`) ou antigo (`ABC1234`), sem hífen. Até 3 reboques, 1 a 10 condutores.
- `totais.unidade`: 01 KG (padrão) · 02 TON. `produto.tipo_carga`: 01 granel sólido · 02 granel líquido · 03 frigorificada · 04 conteinerizada · 05 carga geral · 06 neogranel · 07–11 perigosa.
- Só pode haver **um** MDF-e em aberto por veículo: encerre o anterior antes do próximo (rejeição 620/641).

Encerramento no destino (tudo opcional — padrão é a UF de fim e o último município de descarga):

```json
POST /v1/mdfe/{id}/encerrar
{"data": "2026-09-25", "uf": "RJ", "codigo_municipio": "3304557"}
```

Inclusão de condutor no caminho: `POST /v1/mdfe/{id}/condutores {"nome": "…", "cpf": "…"}`. Trilha: `GET /v1/mdfe/{id}/eventos`. Cancelamento (só até o encerramento e dentro do prazo da SEFAZ): `POST /v1/notas/{id}/cancelar {"motivo": "…15 a 255 caracteres…"}`.

## 8. Acompanhamento

`situacao`: `na_fila` → `emitindo` → `emitida` · `rejeitada` · `cancelada`. Quando `rejeitada`, o objeto `rejeicao` traz `codigo` (ex.: `SEFAZ_229`), `mensagem` (em português, dizendo o que fazer) e `mensagem_tecnica` (o xMotivo da SEFAZ). Corrija e envie um **novo** pedido (o número rejeitado não é reaproveitado).

## 9. Erros que você vai ver

| Código | Status | O que fazer |
|---|---|---|
| `dados_incompletos` | 422 | `campos` lista o que falta; nada foi gravado |
| `sem_licenca` | 403 | Cota do documento não ativa para a empresa |
| `documento_nao_encontrado` | 404 | Id errado, outro documento ou fora do escopo da credencial |
| `numero_ja_utilizado` | 409 | Ajuste de numeração abaixo de número já usado |
| `nao_emitido` / `ja_encerrado` / `nao_permitido` | 409 | Evento não cabe no estado atual |
| `sefaz_recusou` | 422 | Regra fiscal recusou o evento; leia a mensagem |
| `sefaz_indisponivel` | 502 | Autorizador fora; tente de novo em minutos |
| `limite_excedido` | 429 | 120 req/min por credencial |

Catálogo completo: `GET /docs/erros.json`.

## 10. Checklist de homologação

1. `GET /v1/empresa`: `cotas.cte` e `cotas.mdfe` = true; `transporte.prontidao.*.pronto` = true.
2. `PUT /v1/empresa/transporte` com `ambiente: homologacao`.
3. `PUT /v1/numeracao` para `cte` e `mdfe` (mesmo em homologação, para não colidir com números antigos).
4. Cadastrar veículo (tração), condutor e dois tomadores.
5. Emitir 1 CT-e; conferir `emitida`, chave, XML e DACTE.
6. Registrar 1 carta de correção; conferir em `GET /v1/cte/{id}/eventos`.
7. Emitir 1 MDF-e vinculando o CT-e; conferir `emitida`, XML e DAMDFE.
8. Encerrar o MDF-e; conferir `encerrada_em` e o evento.
9. Cancelar um CT-e de teste; conferir `cancelada` e `links.xml_cancelamento`.
10. Repetir um POST com a mesma `referencia_externa`; conferir `200` + `meta.repetida`.
11. Virar `ambiente: producao`, ajustar a numeração de produção e emitir o primeiro documento real.
