Referência completa — NF-e e NFC-e
Todos os campos que POST /v1/nfe e POST /v1/nfce aceitam hoje, com exemplo real de cada um.
Os dois endpoints usam exatamente o mesmo formato de payload — o que muda é só a URL
(e a numeração/série, que são independentes por modelo). Se você é iniciante, comece pelo
guia passo a passo antes desta página — aqui é a
referência técnica de cada campo, não o tutorial de cadastro.
1. Payload básico
O menor payload válido — uma NFC-e de balcão, consumidor não identificado, um item, Simples Nacional, à vista em dinheiro:
POST /v1/nfce
Authorization: Bearer sk_test_xxxxxxxxxxxxxxxx
Content-Type: application/json
Idempotency-Key: venda-00123
{
"company_id": "emp_xxxxxxxxxxxx",
"items": [
{
"description": "Pão francês",
"ncm": "19059090",
"cfop": "5102",
"unit": "KG",
"quantity": 2,
"unit_price_cents": 1290,
"csosn": "102",
"cst_pis": "07",
"cst_cofins": "07"
}
]
}
Resposta imediata (a emissão continua em segundo plano):
{ "id": "nf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "tipo": "nfce", "status": "processando" }
| Campo | Obrigatório? | O que é |
|---|---|---|
| company_id | obrigatório | ID da empresa (CNPJ) cadastrada na sua conta — veja em Minha conta → Empresas. |
| items | obrigatório | Lista de itens da venda, não pode ser vazia. |
| items[].description | obrigatório | Descrição do produto/serviço, texto livre. |
| items[].ncm | obrigatório | NCM do produto, 8 dígitos. Consulte na tabela oficial se não souber o do seu produto. |
| items[].cfop | obrigatório | CFOP da operação, 4 dígitos começando em 1-7 (ex.: 5102 venda dentro do estado, 6102 venda pra outro estado). |
| items[].unit | obrigatório | Unidade comercial (até 6 caracteres): UN, KG, CX, L, etc. |
| items[].quantity | obrigatório | Quantidade vendida — aceita decimal (ex.: 2.5 kg). |
| items[].unit_price_cents | obrigatório | Sempre em centavos, inteiro. R$ 12,90 = 1290. Nunca mande 12.90. |
| items[].csosn ou cst_icms | um dos dois | csosn se a empresa é Simples Nacional (CRT 1); cst_icms se é Regime Normal (CRT 3). Nunca os dois juntos. |
| items[].cst_pis | obrigatório | CST do PIS, 2 dígitos (ex.: 07 = isento, comum em Simples Nacional). |
| items[].cst_cofins | obrigatório | CST do COFINS, 2 dígitos (mesma lógica do PIS). |
| items[].origem_mercadoria | opcional, padrão 0 | 0=nacional, 1/2/3/6/7/8=variações de importado (Tabela de Origem da SEFAZ). Só afeta o cálculo do imposto aproximado (item 4), não o CST/CSOSN. |
| items[].cest | opcional | Código CEST, 7 dígitos — obrigatório na prática pra alguns CSOSN de substituição tributária (ex.: 500). |
A API não decide CST/CSOSN/CFOP por você — ela só monta o XML e valida o formato. Quem calcula qual código usar é o seu sistema (ou seu contador), igual você já faz hoje no seu emissor atual.
2. Destinatário
Opcional pra NFC-e (venda de balcão sem cliente identificado é normal e válida). Recomendado sempre pra NF-e (venda entre empresas).
Simples — só CPF/CNPJ
{
"company_id": "emp_xxxxxxxxxxxx",
"destinatario": {
"documento": "11122233396",
"nome": "Cliente Exemplo"
},
"items": [ ... ]
}
documento: CPF (11 dígitos) ou CNPJ (14 dígitos), só números. nome é opcional — se vazio, usa "CONSUMIDOR".
Completo — com endereço e Inscrição Estadual (recomendado pra NF-e)
{
"destinatario": {
"documento": "18088119000123",
"nome": "Empresa Cliente LTDA",
"inscricao_estadual": "123456789",
"endereco": {
"logradouro": "Rua Exemplo",
"numero": "100",
"complemento": null,
"bairro": "Centro",
"codigo_municipio": "2104404",
"municipio_nome": "Presidente Dutra",
"uf": "MA",
"cep": "65775000"
}
}
}
codigo_municipio é o código IBGE de 7 dígitos (não o nome da cidade) — consulte no
site do IBGE.
Quando o destinatário tem CNPJ e você informa inscricao_estadual, a API já monta
indIEDest=1 (contribuinte) automaticamente — mande "ISENTO" nesse campo se for isento
(vira indIEDest=2). Sem endereço, a nota ainda sai válida, mas o DANFE de NF-e fica sem o
"canhoto" de entrega completo.
Achado real testado em produção: a API calcula sozinha se a operação é interna ou
interestadual (idDest) comparando a UF da sua empresa com a UF do endereço do destinatário — não
precisa informar isso.
3. Pagamento (único e dividido)
Uma forma de pagamento
{
"payment_method": "pix"
}
Valores aceitos: dinheiro (padrão se omitido), cheque, cartao_credito,
cartao_debito, credito_loja, vale_alimentacao, vale_refeicao,
vale_presente, vale_combustivel, boleto, deposito_bancario,
pix, transferencia, sem_pagamento, outros.
pix gera tPag=99 ("Outros") + xPag="PIX", não o código oficial 17 —
de propósito, é assim que o PDV do sysvelox já emite em produção. Cartão de crédito/débito sempre inclui
tpIntegra=2+tBand=99 no XML (exigido pela SEFAZ mesmo sem dados reais de maquininha).
Pagamento dividido (metade dinheiro, metade cartão, por exemplo)
{
"payments": [
{ "method": "dinheiro", "amount_cents": 1500 },
{ "method": "cartao_credito", "amount_cents": 1500 }
]
}
Quando payments é enviado, ele substitui payment_method — a API monta
uma tag <detPag> por entrada da lista. Testado em produção com venda real dividida
dinheiro+cartão, autorizada normalmente.
Troco
{
"payment_method": "dinheiro",
"change_cents": 500
}
change_cents (troco) só faz sentido com pagamento em dinheiro maior que o total da venda —
vira a tag vTroco. Fica de fora do XML automaticamente quando é 0 ou omitido.
4. Desconto, frete, seguro, outras despesas
{
"discount_cents": 500,
"freight_cents": 300,
"insurance_cents": 0,
"other_expenses_cents": 200,
"items": [ ... ]
}
| Campo | O que faz |
|---|---|
| discount_cents | Desconto total da venda, em centavos. Rateado automaticamente entre os itens (proporcional ao valor bruto de cada um) — item com discount_cents próprio usa o valor dele, o resto recebe o rateio. |
| freight_cents | Frete, em centavos — soma no total da nota (vNF). |
| insurance_cents | Seguro, em centavos. |
| other_expenses_cents | Outras despesas/taxas (ex.: taxa de entrega), em centavos. |
Todos os quatro são opcionais e independentes — pode usar só o que precisar. Todos sempre em centavos, nunca em reais.
5. ICMS regime normal (valores reais)
Só se aplica quando o item usa cst_icms (Regime Normal, CRT 3) — Simples Nacional (CSOSN) não destaca ICMS próprio, então este campo não se aplica com csosn.
{
"items": [
{
"description": "Produto com ICMS destacado",
"ncm": "12345678",
"cfop": "5102",
"unit": "UN",
"quantity": 1,
"unit_price_cents": 10000,
"cst_icms": "00",
"icms": {
"base_cents": 10000,
"aliquota": 18.0,
"valor_cents": 1800
},
"cst_pis": "01",
"cst_cofins": "01"
}
]
}
Sem o objeto icms, o regime normal sai com base/alíquota/valor tudo zerado (só o CST é
informado). A API não recalcula — os três valores (base_cents, aliquota,
valor_cents) são exatamente o que você mandar.
Atenção com o CRT da empresa: se a empresa é Simples Nacional (CRT 1), a SEFAZ
rejeita qualquer cst_icms com "Informado CST para emissor do Simples Nacional" — confirmado em
teste real. Regime normal só funciona pra empresa CRT 3.
6. IPI
{
"items": [
{
...,
"ipi": {
"cst": "50",
"enquadramento": "999",
"base_cents": 10000,
"aliquota": 5.0,
"valor_cents": 500
}
}
]
}
Opcional — sem ele, o item sai com IPI "não tributado" (CST 53, tudo zerado), igual ao
padrão de quem não trabalha com produto industrializado.
Só para NF-e (modelo 55). A SEFAZ rejeita o
grupo IPI inteiro em NFC-e (modelo 65) — mesmo "não tributado" — com o erro "NFC-e com grupo do IPI". Achado
real, testado em produção: a API já sabe disso e nunca monta a tag IPI quando o documento é NFC-e, mesmo que
você mande o campo ipi no payload (ele é ignorado silenciosamente pra NFC-e).
7. PIS/COFINS com valores reais
{
"items": [
{
...,
"cst_pis": "01",
"pis": { "base_cents": 10000, "aliquota": 1.65, "valor_cents": 165 },
"cst_cofins": "01",
"cofins": { "base_cents": 10000, "aliquota": 7.6, "valor_cents": 760 }
}
]
}
Mesma lógica do ICMS/IPI: sem os objetos pis/cofins, os valores saem
zerados (comum com CST 07 isento ou 99 outros). Informe só quando o CST exigir base e
alíquota reais (tipicamente 01/02).
8. IBS/CBS (Reforma Tributária)
Grupo opcional da Reforma Tributária (transição 2026-2032). Só entra no XML quando os três campos abaixo vêm juntos por item:
{
"items": [
{
...,
"cst_ibs_cbs": "000",
"cclass_trib": "000001",
"ibs_cbs": {
"base_cents": 10000,
"ibs_uf_aliquota": 0.1,
"ibs_uf_valor_cents": 10,
"ibs_mun_aliquota": 0.0,
"ibs_mun_valor_cents": 0,
"ibs_valor_cents": 10,
"cbs_aliquota": 0.9,
"cbs_valor_cents": 90
}
}
]
}
A API não calcula as alíquotas de transição por você (elas mudam ano a ano por lei) — você calcula por fora e manda os valores prontos, igual todo o resto desta referência.
9. Transportadora, veículo e volumes
Opcional — normalmente só usado quando há transporte de carga por terceiro (NF-e), não em venda de balcão.
{
"modalidade_frete": 1,
"transportadora": {
"documento": "18088119000123",
"nome": "Transportes ABC LTDA",
"inscricao_estadual": "123456789",
"endereco": "Rua Transportadora, 500",
"municipio_nome": "São Luís",
"uf": "MA"
},
"veiculo_transporte": {
"placa": "ABC1234",
"uf": "MA",
"rntc": null
},
"volumes": {
"quantidade": 2,
"especie": "Caixa",
"marca": "Fragil",
"numeracao": "1/2",
"peso_liquido_kg": 5.0,
"peso_bruto_kg": 6.0
}
}
modalidade_frete: 0=emitente, 1=destinatário, 2=terceiros, 3=próprio emitente, 4=próprio
destinatário, 9=sem transporte (padrão). Se você mandar transportadora sem informar
modalidade_frete, a API assume 0 (emitente) — mandar transportadora com "sem
transporte" (9) é inconsistente e a SEFAZ pode rejeitar.
10. Devolução
NF-e de devolução referencia a chave da nota original e tem finalidade/indicadores próprios:
{
"company_id": "emp_xxxxxxxxxxxx",
"documento_referenciado": "35260545920661000173550040000008201880873311",
"finalidade": 4,
"nat_op": "Devolucao de mercadoria",
"ind_final": 0,
"ind_pres": 9,
"payment_method": "sem_pagamento",
"destinatario": { "documento": "...", "nome": "Fornecedor Original", "endereco": { ... } },
"items": [
{
...,
"ipi_devol": { "valor_cents": 500, "percentual_devolvido": 100.0 }
}
]
}
| Campo | O que é |
|---|---|
| documento_referenciado | Chave de acesso (44 dígitos) da nota original sendo devolvida. Obrigatório quando finalidade=4. |
| finalidade | 1=normal (padrão), 2=complementar, 3=ajuste, 4=devolução. |
| nat_op | Natureza da operação (texto livre) — padrão "Venda de mercadoria", ou "Devolucao de mercadoria" automaticamente quando finalidade=4 e você não informar. |
| ind_final | 0=não é consumidor final (padrão em devolução), 1=consumidor final (padrão geral). |
| ind_pres | Indicador de presença — 9 (não se aplica) é comum em devolução. |
| items[].ipi_devol | Crédito de IPI devolvido (grupo separado do IPI normal), só quando o produto tinha IPI destacado na compra original. |
Achado real testado em produção: pagamento em devolução precisa ser
sem_pagamento (tPag=90) — mandar qualquer outro método com valor gera rejeição da SEFAZ ("Informado
indevidamente campo valor de pagamento"). A API já calcula sozinha se a operação é interna ou interestadual
comparando a UF da empresa com a do destinatário (fornecedor original).
11. Consultar, baixar e cancelar
# Status
GET /v1/notas/{id}
Authorization: Bearer sk_live_...
# XML autorizado
GET /v1/notas/{id}/xml
# PDF (DANFE/DANFCE)
GET /v1/notas/{id}/danfe?tipo=a4 # ou ?tipo=termica
# Cancelar (justificativa exige 15+ caracteres, exigência da SEFAZ)
POST /v1/notas/{id}/cancelamento
Content-Type: application/json
{ "justificativa": "Erro de digitação no valor total da venda" }
Cancelamento é síncrono (diferente da emissão) — a resposta já vem com o resultado
final, sem precisar consultar depois. Só funciona pra documento com status authorized.
12. Tabela de todos os campos do payload
| Campo | Nível | Tipo |
|---|---|---|
| company_id | raiz | string, obrigatório |
| items | raiz | lista, obrigatório |
| payment_method | raiz | string, opcional (padrão dinheiro) |
| payments | raiz | lista, opcional — substitui payment_method |
| change_cents | raiz | int (centavos), opcional |
| discount_cents | raiz | int (centavos), opcional |
| freight_cents / insurance_cents / other_expenses_cents | raiz | int (centavos), opcional |
| destinatario | raiz | objeto, opcional |
| transportadora / veiculo_transporte / volumes | raiz | objetos, opcionais |
| modalidade_frete | raiz | int 0-4 ou 9, opcional |
| documento_referenciado / finalidade / nat_op / ind_final / ind_pres | raiz | devolução, opcionais |
| description / ncm / cfop / unit / quantity / unit_price_cents | item | obrigatórios |
| origem_mercadoria / cest / discount_cents | item | opcionais |
| csosn ou cst_icms + icms | item | um dos dois obrigatório |
| ipi / ipi_devol | item | opcionais (ipi só NF-e) |
| cst_pis + pis / cst_cofins + cofins | item | cst_* obrigatórios, objetos opcionais |
| cst_ibs_cbs / cclass_trib / ibs_cbs | item | opcionais, os três juntos |
Pronto pra ver isso em código?
Todos os campos desta página, comentados, prontos pra copiar e adaptar.
Ver modelos de código