API do Emissor · v1 · em português

Emita documentos fiscais pelo seu sistema

NFS-e, CT-e, MDF-e e, em breve, CIOT — cada um é um módulo independente. Uma credencial, respostas em português e links permanentes de XML e PDF. Escolha abaixo o documento que você vai homologar.

▸Qual documento você vai emitir?

Cada documento tem cota, cadastro e homologação próprios. O que é comum a todos — credencial, empresas, tomadores, numeração, formato de erro — está nos passos 1 e 2. Depois, siga só o bloco do seu documento.

DocumentoO que éEmissãoPrecisa na empresaOnde ler
NFS-eNota de serviço, padrão nacional e prefeiturasPOST /v1/notascertificado A1 (ou procuração), serviços cadastradospassos 3 e 4
CT-eConhecimento de transporte (modelo 57)POST /v1/cteA1, inscrição estadual, CRT, RNTRCbloco CT-e
MDF-eManifesto da viagem (modelo 58)POST /v1/mdfeA1, inscrição estadual, frota (veículos e condutores)bloco MDF-e
CIOTOperação de transporte na ANTTPOST /v1/operacoes (em breve)PSP credenciadabloco CIOT
NF-eNota de produto (modelo 55)pelo painel · API em breveA1, inscrição estadual, CRT, produtos—
A cota de cada documento é contratada à parte e ativada por empresa em Nota Central › Emissor. Sem cota ativa, a emissão responde 403 sem_licenca. GET /v1/empresa devolve cotas por documento. Comece sempre em homologação: para CT-e/MDF-e o ambiente se ajusta pela API em PUT /v1/empresa/transporte (ou no painel, Configuração › Transporte). Integrando com um agente? Cole /docs/guia-transporte.md no prompt: é o fluxo inteiro, em Markdown.
Como funciona em uma frase: você envia um POST com tomador e valor, a nota entra na fila, é autorizada pela Sefin Nacional em segundos, e você consulta o resultado (ou grava os links permanentes de XML/DANFSe que devolvemos).
POST /v1/notas → 202na_filaemitindoemitida ✓

1Pegue sua credencial

No painel do Emissor, abra Empresas → API → Gerar (ou peça à contabilidade). O código nce_… aparece uma única vez — guarde com segurança.

Há dois tipos de credencial:

TipoOnde gerarO que enxerga
Por empresaEmpresas → {empresa} → APISó aquela empresa. Já identifica o emitente — você nunca envia CNPJ nem empresa_id.
Do workspaceIntegração (API) → Credencial do workspaceTodas as empresas do workspace. Liste em /v1/empresas e informe empresa_id ao emitir. É a escolha de ERP e escritório que atende vários clientes.
# Toda chamada leva o header:
Authorization: Bearer nce_SUA_CREDENCIAL
Limite: 120 requisições/minuto por credencial (HTTP 429 ao exceder). Sucesso vem em {"dados": …}; erro em {"erro": "codigo", "mensagem": "…"}.

2Conheça a empresa

Confira o cadastro e descubra os códigos de serviço disponíveis — o codigo_tributacao_nacional que você vai usar na emissão sai daqui.

curl https://emite-api.notacentral.com.br/v1/empresa \
  -H "Authorization: Bearer nce_SUA_CREDENCIAL"

curl https://emite-api.notacentral.com.br/v1/servicos \
  -H "Authorization: Bearer nce_SUA_CREDENCIAL"

Os itens são as descrições prontas que quem emite escolhe no painel — use a descricao deles na nota (e, na equiparação hospitalar, a classificacao_medica):

curl https://emite-api.notacentral.com.br/v1/itens \
  -H "Authorization: Bearer nce_SUA_CREDENCIAL"

Com credencial do workspace, primeiro liste as empresas e depois use o id no caminho:

curl https://emite-api.notacentral.com.br/v1/empresas \
  -H "Authorization: Bearer nce_CREDENCIAL_DO_WORKSPACE"

curl https://emite-api.notacentral.com.br/v1/empresas/{id}/servicos \
  -H "Authorization: Bearer nce_CREDENCIAL_DO_WORKSPACE"

curl https://emite-api.notacentral.com.br/v1/empresas/{id}/itens \
  -H "Authorization: Bearer nce_CREDENCIAL_DO_WORKSPACE"

Com o turbo NC Saúde ativo, a resposta de /v1/empresa (ou /v1/empresas/{id}) inclui o objeto equiparacao_hospitalar com o corpo clínico — use-o para montar a cota_medica.

2½Confira os impostos antes de emitir (dry-run)

Seu sistema não precisa conhecer a regra fiscal. Mande o mesmo JSON da emissão para POST /v1/notas/dry-run: a resposta traz ISS (alíquota, valor, se é retido e por quê), retenções federais (PIS, COFINS, CSLL, IRRF, INSS), IBS/CBS quando a calculadora está ligada, o líquido e a memória de cálculo — inclusive o que não foi retido e o motivo. Nada é gravado: sem rascunho, sem número, sem nota. Mostre para quem confere e, se estiver de acordo, envie o mesmo corpo para POST /v1/notas.

curl -X POST https://emite-api.notacentral.com.br/v1/notas/dry-run \
  -H "Authorization: Bearer nce_SUA_CREDENCIAL" -H "Content-Type: application/json" \
  -d '{"tomador":{"cpf_cnpj":"46009718000140","nome":"HOSPITAL X"},"valor":25087.80,"competencia":"2026-09","codigo_tributacao_nacional":"040301"}'

# resposta (resumida)
{"dados":{"valor_servico":25087.8,
  "iss":{"aliquota":5,"valor":1254.39,"retido":true,"exigibilidade":"exigivel","explicacao":"…"},
  "retencoes_federais":{"pis":163.07,"cofins":752.63,"csll":250.88,"irrf":376.32,"inss":0,"total":1542.9},
  "valor_liquido":22290.51,
  "memoria_calculo":[{"grupo":"irrf","aplicada":true,"aliquota":1.5,"valor":376.32,"explicacao":"…"}, …]},
 "meta":{"simulacao":true}}
Erros de cadastro aparecem aqui, com os mesmos códigos da emissão (servico_sem_classificacao_fiscal, empresa_sem_regime_tributario…) — é a hora de corrigir, não o último clique.

3Emita a nota

O mínimo indispensável: tomador (CPF/CNPJ + nome), valor e competência. O resto é opcional — omitido, valem os padrões cadastrados da empresa.

curl -X POST https://emite-api.notacentral.com.br/v1/notas \
  -H "Authorization: Bearer nce_SUA_CREDENCIAL" \
  -H "Content-Type: application/json" \
  -d '{
    "tomador":            { "cpf_cnpj": "00000000000191", "nome": "Cliente Exemplo" },
    "valor":              150.00,
    "competencia":        "2026-08",
    "descricao":          "Consultoria em tecnologia",
    "referencia_externa": "pedido-8412"
  }'

# Resposta: HTTP 202
{ "dados": { "id": "f2b41c…", "situacao": "na_fila" } }
Retry sem medo: mande sempre a referencia_externa (o id da venda no SEU sistema). Repetir o mesmo request devolve 200 com a nota original — uma queda de rede nunca duplica nota.
Endereço do tomador: a nota leva só CPF/CNPJ e nome; endereço, inscrição municipal e e-mail vêm do cadastro de tomadores, pelo documento. Em município que exige o domicílio do tomador a emissão recusa com endereco_do_tomador_obrigatorio — cadastre o tomador antes (POST /v1/tomadores).

4Acompanhe até autorizar

A emissão é assíncrona e leva segundos. Consulte a nota até a situação virar emitida (sugestão: a cada 2–3 s, com timeout de 1 minuto).

curl https://emite-api.notacentral.com.br/v1/notas/{id} \
  -H "Authorization: Bearer nce_SUA_CREDENCIAL"

# Autorizada:
{ "dados": {
  "situacao":     "emitida",
  "numero_dps":   93,
  "chave_acesso": "3511508226391706100013800000000000712…",
  "links": {
    "xml":    "https://emite-api.notacentral.com.br/nfse/…/….xml",
    "danfse": "https://emite-api.notacentral.com.br/nfse/…/….pdf"
  }
} }

Nota cancelada tem três documentos, e os três vêm em links: xml (a nota existiu), danfse (o mesmo PDF, já regerado com a marca CANCELADA) e xml_cancelamento — o XML assinado do evento, que é a prova do cancelamento e o que a contabilidade pede.

Os links são permanentes e públicos (URL não-adivinhável): grave no seu sistema, mande por e-mail ao cliente — não expiram e não pedem autenticação. Se a nota for rejeitada, o objeto rejeicao vem com o motivo explicado em português; cancelada, o objeto cancelamento traz motivo e data.

5Cancelar a nota

Cancelar pede motivo — ele vai no evento assinado que mandamos ao órgão e fica registrado na nota. A chamada é síncrona: a resposta só volta depois que o órgão aceitou. O DANFSe é regerado com a marca CANCELADA e os links da nota continuam os mesmos.

curl -X POST https://emite-api.notacentral.com.br/v1/notas/{id}/cancelar \
  -H "Authorization: Bearer nce_SUA_CREDENCIAL" -H "Content-Type: application/json" \
  -d '{"motivo":"Serviço não executado"}'

{ "dados": { "id": "f2b41c…", "situacao": "cancelada", "motivo": "Serviço não executado" } }

# Depois, GET /v1/notas/{id} traz os três documentos:
{ "links": {
  "xml":              "…/nfse/{token}/{chave}.xml",
  "danfse":           "…/nfse/{token}/{chave}.pdf",
  "xml_cancelamento": "…/nfse/{token}/{chave}-cancelamento.xml"
} }
Recusa do órgão não é erro seu nem nosso: fora do prazo, nota já cancelada na prefeitura ou substituída vem como 422 cancelamento_recusado com o motivo do órgão em mensagem — mostre essa frase a quem pediu o cancelamento. Nota que não está emitida (rascunho, na fila, rejeitada, já cancelada aqui) vem como 409 nota_nao_cancelavel; confira a situação em GET /v1/notas/{id} antes de reenviar.

O prazo e as regras são de cada prefeitura. Passado o prazo, o caminho costuma ser substituir a nota ou abrir processo no município.

+Tomadores: cadastro pela API

O cadastro de tomadores é o mesmo do painel e é do workspace: qualquer credencial da conta enxerga e altera o mesmo registro. A emissão enriquece a nota a partir dele pelo CPF/CNPJ — endereço (obrigatório em municípios que ancoram o ISS no domicílio do tomador), inscrição municipal (em São Paulo decide se o ISS pode ser retido) e e-mail.

# cria ou atualiza pelo documento — um único verbo; campos omitidos ficam como estão
curl -X POST https://emite-api.notacentral.com.br/v1/tomadores \
  -H "Authorization: Bearer nce_SUA_CREDENCIAL" -H "Content-Type: application/json" \
  -d '{"cpf_cnpj":"46009718000140","nome":"HOSPITAL X LTDA","email":"fiscal@hospitalx.com.br",
       "inscricao_municipal":"12345678",
       "endereco":{"logradouro":"Av. Paulista","numero":"1000","bairro":"Bela Vista",
                   "municipio":"São Paulo","codigo_municipio":"3550308","uf":"SP","cep":"01310100"}}'
# 201 criado · 200 já existia e foi atualizado (meta.criado diz qual)

curl https://emite-api.notacentral.com.br/v1/tomadores/46009718000140 -H "Authorization: Bearer nce_…"
curl "https://emite-api.notacentral.com.br/v1/tomadores?busca=hospital" -H "Authorization: Bearer nce_…"

Na resposta, endereco_completo diz se há código IBGE + CEP — o mínimo que a emissão exige quando o município pede o domicílio do tomador. Alíquotas de retenção por tomador e o marcador de substituto tributário ficam no painel (escritório de contabilidade).

#Numeração: empresa que veio de outro emissor

A numeração de DPS/RPS é por empresa e por série, e começa em 1. Se a empresa já emitia por outro sistema, a prefeitura já tem números usados nessa série. O emissor tolera isso até 5 números seguidos na mesma emissão (salta e tenta o próximo) e depois para: a nota fica rejeitada com rejeicao.codigo = "dps_number_collision". É de propósito — continuar tentando queimaria numeração na prefeitura sem limite. Nada é emitido nesse caso.

O jeito certo é posicionar a série antes da primeira nota. A API mostra onde ela está e de onde deveria continuar, com base nas notas que a captura do Nota Central já viu para o CNPJ:

curl https://emite-api.notacentral.com.br/v1/numeracao -H "Authorization: Bearer nce_SUA_CREDENCIAL"

{"dados":{"serie_padrao":"1",
  "series":[{"serie":"1","proximo_numero":95}],
  "sugestao":{"disponivel":true,"serie":"1","proximo_numero":101,"maior_numero_capturado":100,
              "notas_capturadas":100,"ultima_nota_em":"2026-09-14T16:40:00Z","estimativa":false,
              "explicacao":"Baseado na nota mais recente capturada: a próxima livre é esta."},
  "teto_de_saltos":5}}

# ajusta: a próxima nota da série sai com este número
curl -X PUT https://emite-api.notacentral.com.br/v1/numeracao \
  -H "Authorization: Bearer nce_SUA_CREDENCIAL" -H "Content-Type: application/json" \
  -d '{"serie":"1","proximo_numero":101}'
SituaçãoO que fazer
sugestao.disponivel = true, estimativa = falseUse proximo_numero da sugestão no PUT.
estimativa = trueO dado da captura está velho e o número inclui margem. Confirme o último número no sistema anterior antes de gravar.
motivo = empresa_novaNunca emitiu: começar em 1 está certo, não precisa ajustar.
motivo = captura_desligada · empresa_sem_capturaNão sabemos o histórico. Pegue o último número no sistema anterior e grave último + 1.
motivo = serie_sem_historicoHá notas em outra série (outras_series). Confira se a série configurada está certa.
PUT devolve 409 numero_ja_utilizadoEste emissor já usou um número igual ou maior nessa série; informe um acima.

Cada documento tem a própria numeração. Sem documento a chamada é da NFS-e; para CT-e e MDF-e envie ?documento=cte no GET e "documento": "cte" no PUT (a série padrão vem do bloco Transporte da empresa). A sugestão da captura existe só para NFS-e.

Credencial do workspace: /v1/empresas/{id}/numeracao ou empresa_id no corpo/query. Todo ajuste fica na trilha de auditoria com a credencial como autora.

+Conta Azul: cada nota vira conta a receber

Com a integração ligada, toda NFS-e emitida pela empresa vira uma conta a receber no Conta Azul da própria empresa, pelo valor líquido, com o tomador como cliente e os links permanentes do PDF e do XML na observação. Tudo pela API, sem abrir o painel. São três passos:

# 1. gere o link e mande o CLIENTE abrir (o login no Conta Azul é dele)
curl -X POST https://emite-api.notacentral.com.br/v1/conta-azul/conectar \
  -H "Authorization: Bearer nce_SUA_CREDENCIAL" -H "Content-Type: application/json" \
  -d '{"url_retorno":"https://seu-sistema.com/conta-azul/retorno"}'

{"dados":{"url_autorizacao":"https://login.contaazul.com/#/oauth/authorize?…","expira_em":"2026-10-01T18:10:00Z"}}

# 2. depois que ele autorizar: escolha a conta financeira e ligue
curl https://emite-api.notacentral.com.br/v1/conta-azul/contas-financeiras -H "Authorization: Bearer nce_…"
curl -X PUT https://emite-api.notacentral.com.br/v1/conta-azul \
  -H "Authorization: Bearer nce_…" -H "Content-Type: application/json" \
  -d '{"conta_financeira_id":"c1d2…","vencimento_dias":15,"ligado":true}'

# 3. acompanhe
curl "https://emite-api.notacentral.com.br/v1/conta-azul/lancamentos?situacao=falhou" -H "Authorization: Bearer nce_…"
curl https://emite-api.notacentral.com.br/v1/notas/{id}/conta-azul -H "Authorization: Bearer nce_…"
RotaPara quê
GET /v1/conta-azulSituação: conectado, ligado, configuração e lançamentos por situação.
POST /v1/conta-azul/conectarLink de autorização (10 min). Volta para url_retorno com ?conta_azul=conectado|erro.
GET …/contas-financeiras · GET …/categoriasOnde lançar e em qual categoria de receita.
PUT /v1/conta-azulConfigura (e liga com "ligado": true).
POST …/ligar · POST …/desligar · DELETE /v1/conta-azulLiga, desliga, desconecta.
POST …/aceitar-outro-cnpjA conta do Conta Azul é de outro CNPJ de propósito (grupo, holding).
GET …/lancamentos · POST …/lancamentos/{id}/reenviarAcompanha e reenvia o que falhou. Situações: pendente, enviando, lancado, falhou, aguardando_reconexao, ignorado.
POST …/lancar-notas-emitidas{"desde":"2026-09-01"}: lança o que foi emitido antes de ligar.

Credencial do workspace: os mesmos caminhos sob /v1/empresas/{id}/conta-azul. O Conta Azul não aceita anexos pela API dele, por isso o PDF e o XML vão como links permanentes na observação do lançamento.

+Equiparação hospitalar (NC Saúde)

Clínica no lucro presumido com equiparação hospitalar apura IRPJ/CSLL com base reduzida (8% / 12% em vez de 32%) sobre os serviços hospitalares. Para isso a nota precisa dizer quanto de cada valor é de qual médico — a cota médica. O Nota Central grava a cota na nota e monta os relatórios de segregação e apuração a partir dela.

Pré-requisitos (uma vez por empresa)

O quêOndeComo conferir pela API
Recurso Cota médica (NC Saúde) ligadoPainel → Empresa → Recursos extras (ou app NC → Onboarding de emissão)GET /v1/empresa traz "nc_saude" em turbos e o objeto equiparacao_hospitalar
Médicos cadastrados (nome, CPF, CRM, % padrão)Pela API (abaixo) ou no painel/appGET /v1/medicos
Itens classificados como consulta ou procedimentoPainel/app → Itens da empresaGET /v1/itens → classificacao_medica

Cadastro de médicos pela API

É o mesmo cadastro do painel e do app: o que você cria aqui aparece lá. O id devolvido é o doctor_id da cota. O percentual_padrao só pré-preenche o rateio — a cota de cada nota é quem emite que decide.

# cadastrar
curl -X POST https://emite-api.notacentral.com.br/v1/medicos \
  -H "Authorization: Bearer nce_SUA_CREDENCIAL" -H "Content-Type: application/json" \
  -d '{"nome":"Dra. Ana Souza","cpf":"52998224725","crm":"123456-SP","percentual_padrao":60}'
# → 201 {"dados":{"id":"0d2f…","nome":"Dra. Ana Souza","cpf":"52998224725","crm":"123456-SP","percentual_padrao":60,"ativo":true}}

# listar (meta diz se a equiparação está ligada e quanto somam os % padrão)
curl https://emite-api.notacentral.com.br/v1/medicos -H "Authorization: Bearer nce_SUA_CREDENCIAL"

# alterar (campos omitidos ficam como estão) · remover (some das próximas notas)
curl -X PATCH  …/v1/medicos/{id} -d '{"percentual_padrao":40}'
curl -X DELETE …/v1/medicos/{id}

Credencial do workspace: use /v1/empresas/{id}/medicos ou mande empresa_id no corpo.

Emitindo com cota médica

No POST /v1/notas (e no dry-run), mande cota_medica: uma lista com uma linha por médico, em reais. Informe o doctor_id e o sistema completa nome, CPF e CRM do cadastro. A soma das linhas deve ser o valor da nota (ou a parte dela que é serviço médico).

{
  "tomador": {"cpf_cnpj": "46009718000140", "nome": "HOSPITAL X"},
  "valor": 10000.00,
  "competencia": "2026-09",
  "codigo_tributacao_nacional": "040301",
  "descricao": "Procedimentos cirúrgicos — setembro/2026",
  "cota_medica": [
    {"doctor_id": "0d2f1a3c-…", "amount": 6000.00},
    {"doctor_id": "1e3a2b4d-…", "amount": 4000.00}
  ],
  "referencia_externa": "fat-2026-09-0412"
}
Campo da linhaObrigatórioO que é
doctor_idrecomendadoO id de /v1/medicos. Com ele, nome/CPF/CRM vêm do cadastro.
doctor_name · cpf · crmsem doctor_idIdentificação do médico quando não há cadastro (o relatório agrupa por nome + CPF).
amountsimValor em reais da parte desse médico.
percent—Informativo (o valor manda).
O que acontece com a cota: ela não vai para o XML da NFS-e (a prefeitura não a recebe). Fica gravada na nota, e cada linha vira um registro por médico com valor, percentual e a economia da equiparação (base 32% × 8%/12%) — é daí que saem o relatório por médico e a apuração. A gravação acontece sempre; o recurso NC Saúde ligado é o que libera os relatórios de equiparação no painel e as presunções configuradas da empresa.

Depois de emitida, a nota entra na Segregação (consulta × procedimento, pela classificação do item) e na Apuração (IRPJ/CSLL com e sem equiparação) da competência — os relatórios ficam no painel, em Equiparação.

Conferindo o rateio de uma nota

O que você mandou em cota_medica volta em GET /v1/notas/{id}, já com o valor e o percentual de cada médico e a economia da equiparação:

curl https://emite-api.notacentral.com.br/v1/notas/{id} -H "Authorization: Bearer nce_…"

{ "dados": { "situacao": "emitida", "valor": 10000.00,
  "cota_medica": [
    {"medico": "Dra. Ana Souza", "cpf": "52998224725", "crm": "123456-SP",
     "valor": 6000.00, "percentual": 60, "equiparacao": true, "economia": 240.00},
    {"medico": "Dr. Bruno Lima", "valor": 4000.00, "percentual": 40, "equiparacao": false}
  ] } }

Vem só na consulta de uma nota, não na listagem: são linhas de outra tabela, e anexá-las a cada item de uma página de 50 notas seriam 50 consultas extras. Para indicador, use o agregado abaixo.

Produção por médico (para indicadores)

Quanto cada médico fez no período, já somado — o mesmo número da tela de Apuração:

curl "https://emite-api.notacentral.com.br/v1/medicos/cotas?de=2026-07&ate=2026-09" \
  -H "Authorization: Bearer nce_…"

{ "dados": [
    {"medico": "Dra. Ana Souza", "crm": "123456-SP", "notas": 12, "valor": 36000.00, "economia": 1440.00},
    {"medico": "Dr. Bruno Lima", "notas": 5, "valor": 12500.00, "economia": 0}
  ],
  "meta": {"de": "2026-07", "ate": "2026-09", "medicos": 2, "notas": 17,
           "valor_total": 48500.00, "economia_total": 1440.00} }
Duas regras que fazem o número bater com a contabilidade: conta só nota emitida (cancelada sai da conta) e o período é por competência (de/ate em AAAA-MM), não por data de emissão. Sem de/ate, o mês corrente. Com credencial do workspace, informe empresa_id ou use /v1/empresas/{id}/medicos/cotas.

CTCT-e: conhecimento de transporte pela API

Fluxo: PUT /v1/tomadores para remetente e destinatário (com endereço completo) → POST /v1/cte → GET /v1/cte/{id} até emitida. Cancelamento pelo mesmo POST /v1/notas/{id}/cancelar; carta de correção em POST /v1/cte/{id}/carta-correcao. O emitente (CNPJ, IE, CRT, endereço, RNTRC, série e ambiente) vem do cadastro da empresa: não vai no corpo.

Pré-requisitos (uma vez por empresa)

O quêComo conferirComo ajustar pela API
Cota CT-e ativaGET /v1/empresa → cotas.cteContratada e ativada em Nota Central › Emissor
IE, CRT, RNTRC, endereço completoGET /v1/empresa → transporte.prontidao.cte.faltaPUT /v1/empresa/transporte {"inscricao_estadual":"…","crt":3,"rntrc":"12345678"}
Ambiente (homologação → produção) e sérietransporte.ambiente, transporte.serie_ctePUT /v1/empresa/transporte {"ambiente":"producao","serie_cte":1}
Próximo número (migração de outro emissor)GET /v1/numeracao?documento=ctePUT /v1/numeracao {"documento":"cte","serie":"1","proximo_numero":4581}

Nos links da resposta, o PDF do CT-e vem como dacte (e também pdf); o XML autorizado em xml.

Pedido mínimo

POST /v1/cte
{
  "referencia_externa": "FRETE-2026-000123",
  "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}]},
  "documentos": {"chaves_nfe": ["35260998765432000100550010000001231000001236"]}
}

Resposta 202 com situacao: na_fila; ao autorizar, chave_acesso e links (XML e DACTE). O que faltar volta em 422 dados_incompletos com a lista campos em português, antes de gastar número.

ICMS: cst 00, 20, 40/41/51, 60 ou 90; simples_nacional: true para empresa do Simples (automático quando o CRT da empresa é 1); outra_uf: true quando o imposto é devido à UF de término. Autorizador: escolhido pela UF da empresa (SEFAZ própria em MT, MS, MG, PR e SP; SVRS e SVSP para as demais).

MDMDF-e: manifesto da viagem pela API

Fluxo: cadastre a frota uma vez (PUT /v1/veiculos, PUT /v1/condutores) → POST /v1/mdfe com a viagem, o veículo, os condutores e as chaves dos CT-e/NF-e por município de descarga → GET /v1/mdfe/{id} até emitida → no destino, POST /v1/mdfe/{id}/encerrar. Condutor a mais no caminho: POST /v1/mdfe/{id}/condutores. Cancelamento: POST /v1/notas/{id}/cancelar (só até o encerramento, dentro do prazo da SEFAZ).

Pré-requisitos (uma vez por empresa)

O quêComo conferirComo ajustar pela API
Cota MDF-e ativaGET /v1/empresa → cotas.mdfeContratada e ativada em Nota Central › Emissor
IE, endereço e (transportadora) RNTRCtransporte.prontidao.mdfe.faltaPUT /v1/empresa/transporte {"inscricao_estadual":"…","rntrc":"12345678","tipo_emitente":1}
Ambiente e sérietransporte.ambiente, transporte.serie_mdfePUT /v1/empresa/transporte {"ambiente":"homologacao","serie_mdfe":1}
Próximo número (migração)GET /v1/numeracao?documento=mdfePUT /v1/numeracao {"documento":"mdfe","proximo_numero":912}

Nos links da resposta, o PDF do MDF-e vem como damdfe (e também pdf).

Pedido mínimo

POST /v1/mdfe
{
  "referencia_externa": "VIAGEM-2026-000045",
  "viagem": {"uf_inicio": "SP", "uf_fim": "RJ", "municipios_carregamento": [{"codigo": "3550308", "nome": "Sao Paulo"}]},
  "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"}]}
  },
  "descargas": [{"municipio_descarga": {"codigo": "3304557", "nome": "Rio de Janeiro"},
                 "chaves_cte": ["35260912345678000195570010000000771000007719"]}],
  "produto": {"tipo_carga": "05", "descricao": "Equipamentos eletronicos"},
  "totais": {"valor_carga": 150000.00, "unidade": "01", "peso_carga": 12500.5}
}

Emitente: transportadora (tipo_emitente 1, exige RNTRC) ou carga própria (2). Padrão no cadastro da empresa. Pagamento do frete (rodoviario.pagamentos) é obrigatório quando você contrata autônomo (TAC). CIOT vai em rodoviario.ciots. São duas exigências que se somam. ANTT: obrigatório desde 24/05/2026 em toda contratação de TAC (Resolução 6.078/2026) e, desde 18/09/2026, em toda operação remunerada de transporte rodoviário de cargas (Resolução 6.090/2026); multa de R$ 10.500. SEFAZ: a NT 2026.001 do MDF-e rejeita com 684 o transporte remunerado de carga de terceiros sem o grupo — em homologação desde 21/09/2026 e em produção a partir de 23/11/2026. Com tipo_emitente 1 ou 3, o pré-voo já barra o pedido sem CIOT quando a regra vale para o ambiente. Autorizador: SVRS para o país inteiro.

Encerrar

POST /v1/mdfe/{id}/encerrar
{"data": "2026-09-25", "uf": "RJ", "codigo_municipio": "3304557"}   # tudo opcional: padrão = fim da viagem

CICIOT: em breve nesta API

O Código Identificador da Operação de Transporte é gerado por instituição de pagamento credenciada pela ANTT, não pela SEFAZ. A rota POST /v1/operacoes está reservada e responde 501 até a integração com a PSP entrar. Até lá, obtenha o CIOT na sua PSP e informe o número em rodoviario.ciots do MDF-e.

✓Campos da emissão

CampoObrigatórioO que é
empresa_idworkspaceObrigatório só com credencial do workspace — o id de /v1/empresas. Com credencial por empresa, omita.
tomador.cpf_cnpjsimSó dígitos. Endereço, inscrição municipal e e-mail saem do cadastro de tomadores (busca por documento).
tomador.nomesimNome ou razão social.
valorsimValor do serviço em reais (número, ponto decimal).
competenciasim"2026-08" ou "2026-08-01".
descricao—Discriminação do serviço. Omitida, usa o padrão da empresa.
codigo_tributacao_nacional—Código LC 116 (6 dígitos) — os válidos vêm de /v1/servicos.
informacoes_adicionais—Texto livre impresso na nota (pedido, contrato…).
referencia_externa—Id da venda no seu sistema — liga a idempotência. Recomendado sempre.
municipio_prestacao—IBGE 7 dígitos, quando o serviço foi prestado fora do município da empresa.
codigo_municipal · codigo_nbs · indicador_operacao—Detalhes tributários — normalmente os padrões da empresa resolvem.
cota_medica—Rateio por médico (NC Saúde) — ver Equiparação hospitalar.

Situações da nota

na_filaemitindoemitidarejeitadacanceladasubstituida

!Erros: um formato, um catálogo

Todo erro da API vem no mesmo envelope. O erro é um código estável — é por ele que o seu sistema decide o que fazer; a mensagem é para gente ler e pode mudar de redação. campos aponta o que corrigir no corpo; detalhes traz contexto (o id de um rascunho, o código do órgão…).

{
  "erro":     "campos_invalidos",
  "mensagem": "Campos obrigatórios ausentes ou inválidos.",
  "campos":   ["tomador.cpf_cnpj", "valor"],
  "detalhes": {"nota_id": "f2b4…"}          // opcional
}

Status HTTP por família: 400 requisição mal formada · 401 credencial · 403 licença · 404 não existe ou não é seu (indistinguíveis de propósito) · 422 a requisição é válida, mas o cadastro ou a regra fiscal não deixa · 429 limite · 500 falha nossa (tente de novo) · 501 ainda não existe. Um código tem sempre o mesmo status.

HTTPCódigoQuando aconteceO que fazer
400corpo_invalidoO corpo não é JSON válido.Corrija o JSON e reenvie.
400empresa_invalidaempresa_id não é UUID.Use o id de GET /v1/empresas.
400empresa_obrigatoriaCredencial do workspace sem informar a empresa.Informe empresa_id (corpo/query) ou use /v1/empresas/{id}/....
400id_invalidoUm id no caminho não é UUID.Use o id como veio da API.
401credencial_invalidaCredencial desconhecida ou revogada.Gere uma nova no painel e substitua.
401nao_autorizadoSem Authorization: Bearer nce_... ou credencial sem escopo.Envie a credencial gerada no painel.
403empresa_sem_licencaA empresa não tem vaga ativa na licença do emissor.Ative a empresa no painel (ou peça ao gestor da conta).
403sem_licencaA empresa não tem a cota do documento (CT-e/MDF-e) ativa.Ative em Nota Central › Emissor ou contrate a cota.
404condutor_nao_encontradoCondutor inexistente ou já removido.Liste em GET /v1/condutores.
404documento_nao_encontradoMDF-e/CT-e inexistente, de outro documento ou fora do escopo da credencial.Confira o id devolvido no POST.
404empresa_nao_encontradaEmpresa inexistente, de outro workspace ou fora do escopo da credencial.Liste em GET /v1/empresas e use um id de lá.
404lancamento_nao_encontradoLançamento inexistente ou de outra empresa.Use o id devolvido em GET …/conta-azul/lancamentos.
404medico_nao_encontradoMédico inexistente ou de empresa fora do escopo.Liste em GET /v1/medicos.
404nota_nao_encontradaNota inexistente ou de empresa fora do escopo da credencial.Confira o id devolvido no POST /v1/notas.
404tomador_nao_encontradoCPF/CNPJ não está no cadastro de tomadores do workspace.Cadastre com POST /v1/tomadores.
404veiculo_nao_encontradoVeículo inexistente ou já removido.Liste em GET /v1/veiculos.
409conta_azul_nao_conectadoA empresa ainda não conectou a conta do Conta Azul.Gere o link em POST …/conta-azul/conectar e peça ao cliente para autorizar.
409conta_azul_outro_cnpjA conta autorizada no Conta Azul é de outro CNPJ.Se for de propósito (grupo, holding), confirme em POST …/conta-azul/aceitar-outro-cnpj; senão, conecte a conta certa.
409conta_azul_reconectarA autorização no Conta Azul expirou ou foi revogada pelo cliente.Gere um novo link em POST …/conta-azul/conectar.
409ja_encerradoO MDF-e já foi encerrado.Nada a fazer; emita outro manifesto para a próxima viagem.
409lancamento_nao_reenviavelO lançamento já foi lançado ou está sendo enviado agora.Nada a fazer; consulte de novo em instantes.
409nao_emitidoO documento ainda não foi autorizado.Aguarde situacao: emitida antes do evento.
409nao_permitidoEvento não cabe no estado do documento (ex.: condutor em MDF-e encerrado).Confira a situação em GET.
409nota_nao_cancelavelA nota não está emitida (rascunho, na fila, rejeitada, já cancelada).Consulte a situação em GET /v1/notas/{id}.
409numero_ja_utilizadoproximo_numero é igual ou menor que um número já usado nesta série pelo emissor.Consulte GET /v1/numeracao e informe um número acima do último usado.
409referencia_ja_usadaA referencia_externa pertence a uma nota REJEITADA (número já consumido, registro não apagável).Reenvie o pedido corrigido com uma referência nova.
422ambiente_invalidoambiente não é homologacao nem producao.Use homologacao ou producao.
422campos_invalidosCampos obrigatórios ausentes ou inválidos.Veja campos e corrija cada um.
422cancelamento_nao_suportadoO órgão emissor da nota não cancela por integração.Cancele no portal da prefeitura.
422cancelamento_recusadoO órgão recusou o cancelamento (fora do prazo, nota já cancelada ou substituída).Leia mensagem e detalhes.codigo; fora do prazo, só substituição ou processo na prefeitura.
422competencia_invalidacompetencia fora de AAAA-MM ou AAAA-MM-DD.Ex.: "2026-08".
422condutor_invalidoCondutor sem nome ou com CPF fora de 11 dígitos.Corrija nome e CPF.
422configuracao_invalidaConfiguração do lançamento fora do aceito (ex.: vencimento negativo).Corrija o campo indicado na mensagem.
422conta_financeira_obrigatoriaLigar a integração ou configurar sem informar a conta financeira.Liste em GET …/conta-azul/contas-financeiras e envie conta_financeira_id.
422correcoes_obrigatoriasCarta de correção sem itens.Envie correcoes com grupo, campo e valor.
422cota_medica_invalidacota_medica não é uma lista válida ou as linhas não fecham.Uma linha por médico com amount > 0; veja campos.
422cpf_invalidoCPF do médico com dígito verificador errado.Confira o CPF (11 dígitos).
422crt_invalidocrt fora de 1..4.1 Simples, 2 Simples excesso, 3 regime normal, 4 MEI.
422dados_incompletosO manifesto ou o CT-e não fecha (campo faltando ou inválido).Corrija o que campos lista e reenvie; nada foi gravado.
422data_invalidadata fora do formato AAAA-MM-DD.Envie a data no formato ISO.
422documento_invalidodocumento não é nfse, nfe, cte nem mdfe.Use um dos quatro (padrão: nfse).
422emissao_recusadaO emissor recusou antes de enviar ao órgão (validação de leiaute ou de cadastro).Leia mensagem e detalhes.codigo; corrija e reenvie.
422empresa_sem_regime_tributarioEmpresa sem regime tributário no cadastro.Preencha o regime em Dados fiscais.
422endereco_do_tomador_obrigatorioO município exige endereço do tomador e o cadastro não tem.Cadastre o tomador com endereço (POST /v1/tomadores, ou no painel).
422endereco_invalidoEndereço do tomador com uf, cep ou codigo_municipio fora do formato.uf com 2 letras, cep com 8 dígitos, codigo_municipio com 7 dígitos (IBGE); veja campos.
422motivo_obrigatorioCancelamento sem motivo.Informe o motivo — ele vai no evento enviado ao órgão.
422municipio_fora_do_ambiente_nacionalO município da empresa não emite pelo padrão nacional nem tem rota própria.Fale com o suporte para habilitar o município.
422nbs_obrigatorioO serviço exige código NBS e ele não foi informado nem está no cadastro.Informe codigo_nbs ou cadastre no serviço.
422nome_obrigatorioMédico ou tomador sem nome.Informe nome.
422numero_invalidoproximo_numero ausente ou menor que 1.Informe o próximo número da série (inteiro ≥ 1).
422percentual_invalidopercentual_padrao fora de 0–100.Use um número entre 0 e 100.
422periodo_invalidode/ate fora de AAAA-MM, ou fim anterior ao início.Use competências no formato AAAA-MM (ex.: 2026-09).
422placa_obrigatoriaVeículo sem placa.Informe placa.
422regime_tributario_nao_suportadoRegime não coberto pelo cálculo de retenção federal.Fale com o suporte.
422rntrc_invalidorntrc não tem 8 dígitos.Informe o RNTRC da ANTT com 8 dígitos (ou vazio para limpar).
422sefaz_recusouA SEFAZ recusou o evento (cStat na mensagem).Leia a mensagem: é regra fiscal, não falha técnica.
422sem_certificadoA empresa não tem certificado A1 para assinar o evento.Cadastre o A1 no Nota Central.
422serie_invalidaserie_cte/serie_mdfe menor que 1.Informe a série como inteiro a partir de 1.
422servico_sem_classificacao_fiscalServiço sem classificação de retenção federal; bloqueia emissão a tomador PJ.Classifique o serviço no catálogo (ou marque sem retenção). PF continua funcionando.
422simples_sem_aliquota_efetivaSimples com ISS retido pelo tomador sem anexo/RBT12 no cadastro.Cadastre o anexo do serviço e a receita dos 12 meses.
422situacao_invalidaFiltro situacao fora dos valores conhecidos.Use rascunho, na_fila, emitida, rejeitada, cancelada.
422situacao_lancamento_invalidaFiltro situacao dos lançamentos fora dos valores conhecidos.Use pendente, enviando, lancado, falhou, aguardando_reconexao, ignorado.
422suspensao_iss_sem_processoExigibilidade suspensa sem número de processo.Informe o processo no cadastro fiscal ou na nota.
422tipo_invalidotipo do veículo não é tracao nem reboque.Use tracao ou reboque.
422tomador_invalidotomador.cpf_cnpj (ou cpf_cnpj do tomador) não é um CPF (11) ou CNPJ (14 dígitos) válido.Só dígitos, com dígitos verificadores corretos.
422turbo_falhouUm recurso extra (ex.: calculadora IBS/CBS) falhou ao enriquecer a nota.Veja detalhes.recurso; tente de novo ou desligue o recurso.
422url_retorno_invalidaurl_retorno não é uma URL https completa.Envie uma URL https (até 500 caracteres) ou omita para voltar ao Nota Central.
422valor_invalidovalor ausente ou não positivo.Informe o valor do serviço maior que zero.
429limite_excedidoMais de 120 requisições/minuto na credencial (ou 240 por IP).Aguarde e reenvie com backoff.
500erro_internoFalha nossa, não da requisição.Tente de novo; se persistir, fale com o suporte com o horário.
501indisponivelRecurso ainda não disponível nesta versão.Aguarde a próxima versão.
502conta_azul_recusouO Conta Azul recusou a chamada.Leia a mensagem (vem do Conta Azul) e tente de novo; se persistir, fale com o suporte.
502sefaz_indisponivelA SEFAZ não respondeu ou falhou.Tente de novo em alguns minutos.
503conta_azul_indisponivelA integração com o Conta Azul não está disponível neste ambiente.Fale com o suporte.

Casos que não são erro: HTTP 200 com meta.repetida (mesma referencia_externa, devolve a nota original); nota rejeitada pelo órgão vem como situação da nota, com o objeto rejeicao explicado em português — corrija e emita de novo. O catálogo em JSON: /docs/erros.json.