● Ambiente sandbox · e-docs

Manual de integração - Brasil

Guia prático de ponta a ponta para quem vai integrar NFS-e, NFCom e NF-e via API no sandbox: cadastro, empresa, certificado, chave de API, webhook, envio de documentos fiscais e leitura da resposta.

Antes de tudo

💡 Proposta — ideia aberta para conversa

Seu ERP não precisa reconstruir a gestão fiscal inteira

O resto deste manual mostra como consumir a API para emitir, cancelar e receber eventos por webhook — a operação do dia a dia. Mas isso não precisa ser tudo. Para o que vem depois — lote, correções, relatórios, o que a reforma tributária vai exigir — a sugestão é diferente: deixar o e-docs assumir essa parte, e dar ao usuário do ERP um link de acesso direto para quando ele precisar de mais.

Seu ERP

Operação básica, via API — o que este manual cobre

  • Emitir documentos fiscais
  • Cancelar quando necessário
  • Escutar eventos por webhook

e-docs

Gestão fiscal completa, direto pelo painel

  • Operações e correções em lote
  • Gráficos e relatórios fiscais
  • Codinel — inteligência fiscal para análise de rejeições
  • Armazenamento de XML pelo prazo decadencial
  • Acesso somente leitura para contadores e outros membros da empresa — a mesma visão que o workspace já tem sobre todas as empresas, só que restrita
  • Auditoria completa de toda ação fiscal e de acesso
  • Reforma tributária (IBS/CBS)
    Futuro: apuração assistida de créditos, cashback, split payment

Antes de começar

Visão geral do site

Depois de logado, o workspace tem uma faixa fixa no topo identificando o ambiente sandbox, uma barra lateral com a navegação e o conteúdo principal. Esta estrutura se repete em toda tela autenticada.

Dashboard do workspace no sandbox, com a faixa de ambiente sandbox no topo e o resumo de atividades do mês

A faixa sandbox só aparece depois do login — na tela de acesso, antes de autenticar, ela mostra só o aviso de ambiente, sem seletor de cenário (isso é o que garante que ninguém troque um cenário de teste sem ter um workspace associado).

Menu Documentos lista os modelos fiscais disponíveis no workspace: NFS-e, NFCom, ARCA, DIAN, NF-e e SIFEN (NFC-e e MDF-e aparecem desabilitados nesta build). O SIFEN, do Paraguai, oferece homologação oficial e produção para contribuintes habilitados na DNIT, com certificado, timbrado e CSC próprios. O simulador permanece na plataforma sandbox. Menu Configurações → Integrações concentra chaves de API, webhooks e os logs de cada um.

Como o sandbox decide o desfecho

Cenários de teste

O sandbox não fala com nenhum autorizador fiscal real — ele simula a resposta. Você escolhe o desfecho pelo painel, não pelo seu código de integração: assim o payload que você envia por API fica idêntico ao que vai usar em produção, sem nada para remover na hora de migrar.

Diálogo Cenários de teste, com a opção Autorizar selecionada
O padrão é sempre "Autorizar" Sem trocar o cenário no painel, todo envio — por API ou pela tela — é autorizado normalmente. O cenário escolhido fica gravado no documento, e toda consulta ou cancelamento posterior reproduz o mesmo resultado, de forma determinística. O mesmo controle central vale para qualquer modelo fiscal do workspace.

Passo 1

Cadastro e criação do workspace

O sandbox tem um cadastro público — sem depender de convite ou de conta corporativa. Em 5 passos você tem um workspace pronto para configurar empresa, certificado e integração.

  1. Acesse a tela de login e clique em "Criar acesso no sandbox".Fica logo abaixo do botão "Entrar com SSO" (SSO é restrito a contas @ixcsoft — ver Acesso admin/suporte).
  2. Informe nome, CPF, e-mail, telefone e nome do workspace.Use um CPF com dígito verificador válido — o formulário calcula e valida em tempo real.
  3. Confirme o código de 6 dígitos enviado por e-mail.Válido por 30 minutos, com limite de tentativas e reenvio com intervalo mínimo.
  4. Defina uma senha (mínimo 10 caracteres, maiúscula/minúscula e número).
  5. Pronto — o acesso é ativado e você entra direto no workspace novo.
Tela de login do sandbox, com o link Criar acesso no sandbox abaixo do botão Entrar com SSO
Formulário de criação de acesso no sandbox preenchido com nome, CPF, e-mail, telefone e nome do workspace
API pura também funciona Todo o cadastro pode ser feito sem a interface, direto no endpoint abaixo — foi exatamente assim que os exemplos deste manual foram gerados.
POST /auth/signup
{
  "name": "Integrador Sandbox",
  "cpf": "918.426.735-64",
  "email": "integrador@empresasandbox.com",
  "phone": "5511999998888",
  "workspace": { "name": "Workspace Sandbox" }
}
200 OK
{ "masked_destination": "int***@empresasandbox.com" }

O código de 6 dígitos chega no e-mail informado. Depois, conclua com senha:

POST /auth/signup/complete
{ "email": "integrador@empresasandbox.com", "code": "263957", "password": "Sandbox#Integra2026" }

Passo 2

Criar empresa

Cada workspace pode ter várias empresas emissoras. O CNPJ aciona uma consulta automática de endereço pelo CEP.

Lista de empresas do workspace, com a Empresa Sandbox ativa
Diálogo Criar empresa com o CNPJ preenchido

O CNPJ 42.011.994/0001-91, em Chapecó/SC, é o emissor usado como exemplo em todos os payloads de NFS-e/NFCom/NF-e deste manual.

Lembre-se de marcar a empresa como ativa O campo active só fica true se você marcar — pelo painel, a empresa nasce inativa e você ativa depois em Empresas → Editar → Empresa ativa; pela API, basta enviar "active": true já no POST /companies. Enquanto estiver inativa, o painel avisa "Empresa está inativa e não aceita operações fiscais" ao tentar configurar um modelo fiscal.

Passo 3

Criar certificado

No sandbox, você não precisa de um certificado A1 real: a tela gera um certificado autoassinado, só para exercitar o fluxo — sem validade fiscal.

  1. Abra Certificados → Criar certificado.
  2. Informe o CNPJ da empresa e clique em Gerar certificado automaticamente.
  3. Arquivo e senha são preenchidos sozinhos — clique em Salvar.
  4. Associe o certificado à empresa em Empresas → Editar → Certificado digital.
Diálogo Criar certificado com o CNPJ preenchido, pronto para gerar automaticamente
Diálogo Criar certificado após gerar automaticamente, com arquivo .p12 e senha preenchidos
Lista de certificados do workspace, com o certificado SANDBOX válido por 365 dias

Pela linha de comando, o mesmo fluxo é duas chamadas — gerar o arquivo e depois enviá-lo (a criação exige upload multipart do arquivo, não um campo JSON):

Gerar e cadastrar via curl
# 1. gera o certificado autoassinado para o CNPJ da empresa
curl -X POST https://sandbox.edocs.ixcsoft.com.br/api/workspaces/{workspace_id}/certificates/sandbox-generate \
  -H "x-api-key: $API_KEY" -H "Content-Type: application/json" \
  -d '{ "tax_id": "42011994000191" }'
# devolve { "file_base64": "...", "file_name": "sandbox-42011994000191.p12", "password": "...", "tax_id": "..." }

# 2. decodifica o arquivo recebido e cadastra via upload multipart
echo "<file_base64 do passo 1>" | base64 -d > sandbox-42011994000191.p12
curl -X POST https://sandbox.edocs.ixcsoft.com.br/api/workspaces/{workspace_id}/certificates \
  -H "x-api-key: $API_KEY" \
  -F "password=<password do passo 1>" \
  -F "file=@sandbox-42011994000191.p12"
Geração automática só existe no sandbox POST /workspaces/{workspace_id}/certificates/sandbox-generate só funciona no ambiente sandbox; em produção, apenas upload de certificado real (.pfx/.p12) é aceito.

Passo 4

Configurar uma chave de API

Configurações → Integrações → Chaves de API → Criar integração. A chave é exibida em texto puro uma única vez — copie e guarde antes de fechar o diálogo.

Diálogo Criar integração com nome, IP liberado e Ativo marcados
POST /workspaces/{workspace_id}/integrations
{ "name": "Integração Tutorial Sandbox", "active": true, "allowed_ips": ["0.0.0.0/0"] }
201 Created
{
  "id": "66a2c9d28d2b45c9f11f8a33",
  "name": "Integração Tutorial Sandbox",
  "active": true,
  "api_key": "8ca7f7fe-****-****-****-6e50adbacb26",  // texto puro só nesta resposta
  "company_id": null  // null = vale para todas as empresas do workspace
}
Diálogo Token de Integração exibindo a chave de API em texto puro, uma única vez

Use essa chave no header x-api-key de toda chamada aos endpoints fiscais e de webhook mostrados neste manual.

Lista de chaves de API em Configurações → Integrações, com a chave mascarada

Passo 5

Configurar um webhook

Webhooks avisam seu sistema quando um documento muda de status — sem precisar ficar consultando a API. Cada entrega vem assinada com HMAC para você confirmar que partiu do e-docs.

Diálogo Criar webhook com todos os grupos de eventos por modelo fiscal: NFS-e, ARCA, NFCom e NF-e

Os eventos são agrupados por modelo fiscal (NFS-e, ARCA, NFCom, NF-e, SIFEN) — cada grupo tem seu próprio ciclo de vida. Editar webhook reaproveita o mesmo formulário, para ajustar URL, eventos ou empresa depois de criado.

POST /webhooks
{
  "name": "Webhook ERP",
  "url": "https://erp.cliente.com.br/webhooks/nfse",
  "events": ["nfse_authorized", "nfse_rejected"],
  "active": true
}
201 Created
{
  "id": "69540c22a40eabd46472f2ad",
  "events": ["nfse_authorized", "nfse_rejected"],
  "active": true,
  "signing_secret": "9e90a1ac...df91"  // texto puro só nesta resposta — guarde para validar a assinatura
}
URLs privadas/internas são bloqueadas Por segurança, o e-docs recusa registrar webhook apontando para localhost ou faixas de IP privadas — precisa ser um endpoint público real, alcançável pela internet.

Exemplo de entrega

O botão "Testar" da tela de webhooks dispara uma entrega de exemplo para o seu endpoint, no mesmo formato usado pelos eventos reais:

Diálogo Testar webhook com o evento NFS-e criada selecionado
Corpo da requisição recebida pelo seu endpoint
{
  "payload": {
    "event": "nfse_authorized",
    "webhook_id": "6a84da3a51c71fcab8f1d293",
    "occurred_at": "2026-08-18T22:27:00.916Z",
    "document_type": "nfse",
    "document": {
      "id": "000000000000000000000000",
      "external_id": "test-nfse-001",
      "status": "authorized",
      "protocol": "TST-2026031800001",
      "total_amount": 100,
      "authorized_at": "2026-08-18T22:27:00.915Z"
    }
  }
}
Headers recebidos
x-app-signature: t=1787092022,v1=4e3ff906d3544c105220d35941d4ccdad695f57e3ee36ff62f677002cd417a28
x-request-id: 96c553ba-089d-471c-a8e9-f9ecf490232e
idempotency-key: 96c553ba-089d-471c-a8e9-f9ecf490232e
x-app-name: IXC E-Docs
x-auth-type: service
content-type: application/json

Validar a assinatura

A assinatura é HMAC-SHA256(signing_secret, "<t>.<corpo_bruto>"):

Node.js
const crypto = require('crypto')

function verify(rawBody, header, signingSecret) {
  const [tPart, v1Part] = header.split(',')
  if (!tPart?.startsWith('t=') || !v1Part?.startsWith('v1=')) return false
  const timestamp = Number(tPart.slice(2))
  if (!Number.isSafeInteger(timestamp) || Math.abs(Date.now() / 1000 - timestamp) > 300) return false
  const expected = Buffer.from(crypto
    .createHmac('sha256', signingSecret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex'), 'hex')
  const received = Buffer.from(v1Part.slice(3), 'hex')
  return expected.length === received.length && crypto.timingSafeEqual(expected, received)
}

Idempotência recomendada: deduplique por webhook_id + document.id + event + occurred_at. Entrega é at-least-once: HTTP 2xx confirma a entrega; outro status, timeout ou erro de rede agenda nova tentativa. O padrão é até 5 tentativas, com backoff exponencial e jitter; confirme a configuração efetiva do ambiente antes de assumir esse valor. x-request-id e idempotency-key permanecem iguais nas tentativas automáticas do mesmo envio. Sem signing_secret, o header x-app-signature não é enviado.

Atualização e consulta de documentos

Envio, cancelamento, sincronização e reenvio são assíncronos. O webhook é a fonte de atualização: não faça polling de detalhe ou listagem para descobrir o status. Ao receber o evento, é adequado reler o documento; use a consulta apenas para localizar, conferir pontualmente ou reconciliar uma operação.

Localizar pelo identificador do ERP
GET /nfse?issuer_tax_id=42011994000191&external_id=nfse-001&limit=10
GET /nfse/42011994000191/nfse-001
GET /nfcom?issuer_tax_id=42011994000191&external_id=nfcom-001&limit=10
GET /nfcom/42011994000191/nfcom-001
GET /nfe?issuer_tax_id=42011994000191&external_id=nfe-001&limit=10
GET /nfe/42011994000191/nfe-001

As listagens usam cursor. limit aceita de 10 a 500 e o padrão é 10. A rota composta devolve somente o documento vigente; a lista pode ser usada para localizar a trilha. Não existe rota by-external-id.

NFS-e

Mapa de atuação / cobertura municipal

Antes de configurar o modelo fiscal de uma empresa, vale checar quais municípios já têm provedor homologado em produção — evita escolher uma integração municipal sem lastro real.

Mapa de cobertura NFS-e → Painel público que mostra, por município, se há nota emitida em produção nos últimos 3 meses (homologado), se existe empresa/perfil configurado sem nota ainda, ou se não há nenhum caminho montado. Alimenta tanto a tela autenticada quanto a landing page pública — são os mesmos municípios que estão de fato rodando hoje.
EstadoSignificado
HomologadoHá nota emitida em produção dentro da janela — prova de uso real.
Existe, não homologadoHá perfil ou empresa configurada, nenhuma nota emitida ainda.
Sem caminhoNão há perfil, empresa configurada nem nota naquele município.

O mapa é uma referência visual. Para o seu código verificar por API se um município (por código IBGE) tem provedor próprio configurado, use o mesmo endpoint usado ao configurar o modelo fiscal da empresa — ver NFS-e Nacional vs. municipal a seguir.

NFS-e Nacional vs. municipal

Ao configurar o modelo fiscal de uma empresa você escolhe entre dois caminhos — não existe uma consulta em tempo real tipo "este município usa nacional?": a escolha é operacional.

Nacional (DPS) Layout único, cobre o Brasil inteiro. Funciona independente do município do cliente — é o caminho mais simples para começar. Foi o usado em todos os exemplos deste manual.
Municipal Usa o webservice específico da prefeitura, quando ela tem provedor homologado (ver mapa de cobertura acima). Preserva o perfil oficial do município, quando isso importa para o seu caso.

Para verificar se existe um perfil municipal específico já mapeado para o CNPJ do seu emissor (municipality_code é o código IBGE do município, 7 dígitos):

GET /nfse/{municipality_code}/profile
{
  "municipality": "Chapecó", "state": "SC", "municipality_code": "4204202",
  "provider": "sigssis",
  "provider_config": { "active": true, "requires_certificate": true, "max_series_per_company": 3 }
}

Sem perfil municipal registrado para o código IBGE informado → não há via municipal própria; use integration: "national".

Enviar NFS-e

Configure o modelo fiscal da empresa uma vez, depois envie quantos documentos quiser. A configuração é a mesma usada em produção — o campo environment aqui se refere ao ambiente do webservice (produção/homologação da prefeitura ou do padrão nacional), não ao sandbox do e-docs.

Diálogo Configurar NFS-e com integração Nacional, ambiente Produção e série 1
PUT /nfse/config/companies/{cnpj}
{ "integration": "national", "environment": "production", "numbering": { "dps": ["1"] } }
POST /nfse
[
  {
    "external_id": "nfse-001",
    "competence_date": "2026-08-19T00:00:00-03:00",
    "issuer": { "tax_id": "42011994000191" },
    "customer": {
      "tax_id": "05823474911",
      "legal_name": "Cliente Sandbox",
      "email": "cliente@exemplo.com",
      "phone": "5549988079672",
      "address": {
        "street": "Rua Tamoios - E", "number": "1012", "neighborhood": "Esplanada",
        "city": "Chapecó", "state": "SC", "postal_code": "89812437",
        "municipality_code": "4204202", "country": "BR"
      }
    },
    "send_email": true,
    "service": {
      "description": "Consultoria de integração de sistemas",
      "cnae_code": "6201501", "lc116_code": "1.07",
      "national_tax_code": "010701", "municipal_tax_code": "802"
    },
    "taxes": { "iss_taxation": 1, "iss_retention_type": 1, "pis_cofins_cst": "01" },
    "values": {
      "total_amount": 1500, "base_amount": 1500, "pis_cofins_base_amount": 1500,
      "pis_rate": 0.65, "pis_amount": 9.75, "cofins_rate": 3, "cofins_amount": 45
    }
  }
]
201 Created
[{
  "id": "6a8507ea84a913c3e6f7355e",
  "external_id": "nfse-001",
  "issuer_tax_id": "42011994000191",
  "reference_status": "allocated",
  "dps_number": 3, "dps_series": "1"
}]

O envio devolve 201 quase na hora — a autorização é assíncrona. Prefira escutar o webhook (nfse_authorized/nfse_rejected) em vez de ficar consultando via GET; use o GET só para conferência pontual, não como mecanismo principal. Para o mesmo emitente e external_id, a NFS-e reaproveita o mesmo documento nos estados permitidos pelo fluxo de DPS/RPS.

Resposta autorizada e rejeição

GET /nfse/{nfse_id}Autorizada
{
  "status": "authorized",
  "integration": "national", "provider": "national",
  "nfse_number": "NFSE-46d842ae99a3d6c99d371633",
  "authorization": "NFSE-46d842ae99a3d6c99d371633",
  "authorized_at": "2026-08-19T01:33:37.495Z",
  "pdf_url": "https://.../nfse/6a8507ea....pdf?download_token=..."
}

pdf_url é o nome único da URL da DANFSe, igual em todos os documentos fiscais do e-docs que geram PDF.

Com o cenário do painel em "Rejeitar" (ver Cenários de teste), a mesma chamada de envio resulta em:

GET /nfse/{id} — rejeitada
{
  "status": "rejected",
  "rejected_at": "2026-08-19T01:58:26.386Z",
  "rejection_reason": "Provider simulado rejeitou a operação.",
  "authorization": null, "access_key": null
}

Cancelamento e sincronização

Pelo painel, selecione o documento e use Mais ações — as mesmas opções (Sincronizar, Cancelar, Reenviar webhook) valem para NFS-e, NFCom e NF-e.

Menu Mais ações da lista de NFS-e, com as opções Reenviar webhook, Marcar como erro e Cancelar
Diálogo Cancelar NFS-e com o motivo do cancelamento preenchido
POST /nfse/cancel
{
  "resolve": [{ "nfse_id": "6a8507ea84a913c3e6f7355e" }],
  "cancel_reason": "Cancelamento de teste do manual de integração"
}

Cada item de resolve[] aceita nfse_id OU issuer_tax_id + external_id — use a segunda forma quando o ERP não grava o ID interno da nota:

Alternativa: resolver por CNPJ do emissor + ID externo
{ "resolve": [{ "issuer_tax_id": "42011994000191", "external_id": "nfse-2026-001" }], "cancel_reason": "..." }

O retorno confirma que o pedido foi enfileirado; o documento permanece autorizado até a confirmação fiscal. O desfecho chega por nfse_canceled ou nfse_cancellation_failed. operation_control.window_ends_at, quando presente, é uma janela de reconciliação operacional — não é prazo municipal de cancelamento.

Lista de NFS-e com o documento no status Cancelada

Uma nova DANFSe é gerada automaticamente para o cancelamento.

Sincronizar

O botão Sincronizar na barra de ações força uma nova consulta ao provedor para o(s) documento(s) selecionado(s) — útil quando um envio ficou muito tempo em pending/processing e você não quer esperar o próximo ciclo automático de consulta.

POST /nfse/sync
{ "resolve": [{ "nfse_id": "6a8507ea84a913c3e6f7355e" }] }
Alternativa: resolver por CNPJ do emissor + ID externo
{ "resolve": [{ "issuer_tax_id": "42011994000191", "external_id": "nfse-2026-001" }] }

XML e DANFSe

Assim que o status vira authorized ou canceled, XML e DANFSe são gerados e salvos automaticamente — nenhum passo manual adicional. No sandbox, a DANFSe sai com uma marca d'água SANDBOX na diagonal, para nunca ser confundida com um documento real.

DANFSe real gerada pelo sandbox, com marca d'água SANDBOX na diagonal
XML real da DPS (padrão Nacional)
<DPS xmlns="http://www.sped.fazenda.gov.br/nfse" versao="1.01"><infDPS Id="DPS420420221122233300019900001000000000000001"><tpAmb>1</tpAmb><dhEmi>2026-03-01T12:00:00-03:00</dhEmi><serie>1</serie><nDPS>1</nDPS><dCompet>2026-03-01</dCompet><prest><CNPJ>42011994000191</CNPJ><IM>98765</IM></prest><toma><CPF>05823474911</CPF><xNome>Cliente Sandbox</xNome></toma><serv><cServ><cTribNac>010701</cTribNac><cTribMun>802</cTribMun><xDescServ>Consultoria de integração de sistemas</xDescServ></cServ></serv><valores><vServPrest><vServ>1500.00</vServ></vServPrest></valores></infDPS></DPS>
Baixar o XML e a DANFSe pela API
GET /nfse/{nfse_id}.xml?download_token=<token>   // artefato XML da NFS-e/DPS quando disponível
GET /nfse/{nfse_id}.pdf?download_token=<token>   // DANFSe — 202+Retry-After enquanto gera

NFCom

Enviar NFCom

Assim como na NFS-e, o ambiente é configurado uma vez no modelo fiscal da empresa — o envio não carrega esse campo. environment só aceita production ou homologation (o alvo fiscal real); no sandbox, use production normalmente — a simulação é decidida pela plataforma, não pelo ambiente escolhido aqui.

Diálogo Configurar NFCom com integração Nacional, ambiente Produção e série 1
PUT /nfcom/config/companies/{cnpj}
{ "environment": "production", "series": "1" }
POST /nfcom
[
  {
    "external_id": "nfcom-001",
    "issuer": { "tax_id": "42011994000191",
      "address": { "street": "Rua Sao Leopoldo", "number": "881", "neighborhood": "Esplanada",
        "city": "Chapecó", "state": "SC", "postal_code": "89812530", "municipality_code": "4204202" } },
    "customer": { "tax_id": "05823474911", "legal_name": "Cliente Sandbox", "ie_indicator": 9,
      "address": { "street": "Rua do Cliente", "number": "10", "neighborhood": "Centro",
        "city": "Chapecó", "state": "SC", "postal_code": "89801001", "municipality_code": "4204202" } },
    "subscriber": { "code": "ASSIN-100", "type": 3, "service_type": 4 },
    "service": { "items": [{
      "product_code": "PLANO-100", "description": "Plano de internet 100 MB",
      "classification_code": "0100401", "unit": 4, "quantity": 1, "unit_value": 99.9,
      "icms": { "cst": "00", "base": 99.9, "rate": 17, "amount": 16.98 }
    }] }
  }
]
201 Created
[{ "id": "6a8543de85fabb49b3311cdc", "number": 4, "series": "1", "status": "created" }]

O campo de endereço é city (não municipality) — usar o nome errado deixa o XML sem o município preenchido.

O envio devolve 201 quase na hora — a autorização é assíncrona, no mesmo padrão de NFS-e e NF-e. Prefira escutar o webhook em vez de ficar consultando via GET; use o GET só para conferência pontual. Após rejeição conclusiva, reenviar o mesmo emitente e external_id reaproveita id, número e série, gera nova tentativa e responde 200. Uso denegado (cStat 110, 301, 302 ou 303) ou documento vigente ativo responde 409, pois a numeração já foi registrada. Erro ou não sincronização com evidência de transmissão exige POST /nfcom/{nfcom_id}/sync.

Resposta e consulta

GET /nfcom/{id}Autorizada
{
  "status": "authorized",
  "access_key": "42260842011994000191620010000000041030483081",
  "protocol": "6217100430622062",
  "xmotivo": "Autorizado o Uso da NFCom",
  "pdf_url": "https://.../nfcom/6a8543de....pdf?download_token=...",
  "xml_url": "https://.../nfcom/6a8543de....xml?download_token=..."
}
Erro de cadastro comum: Inscrição Estadual ausente NFCom exige Inscrição Estadual cadastrada na empresa emissora (Empresas → Editar → Inscrição Estadual). Sem ela, o envio é rejeitado:
GET /nfcom/{id} — sem Inscrição Estadual cadastrada
{
  "status": "rejected",
  "xmotivo": "Sandbox rejeitou: XML não contém a raiz e o Id vinculados à chave informada.",
  "rejection_details": [{ "code": "nfcom.sandbox.xml_identity_mismatch" }]
}

O XML sai com <IE></IE> vazio quando a empresa emissora não tem Inscrição Estadual — a mensagem de rejeição não menciona IE diretamente, mas a causa raiz aparece assim que você inspeciona o XML gerado.

Cancelamento

O mesmo padrão de Cancelamento e sincronização da NFS-e vale para NFCom — pela tela, Mais ações → Cancelar ou Sincronizar; por API:

POST /nfcom/cancel
{
  "resolve": [{ "nfcom_id": "6a8543de85fabb49b3311cdc" }],
  "cancel_reason": "Cancelamento de teste do manual de integração"
}

Cada item de resolve[] aceita nfcom_id OU issuer_tax_id + external_id — use a segunda forma quando o ERP não grava o ID interno da nota:

Alternativa: resolver por CNPJ do emissor + ID externo
{ "resolve": [{ "issuer_tax_id": "42011994000191", "external_id": "nfcom-2026-001" }], "cancel_reason": "..." }

O retorno confirma que o pedido foi enfileirado; acompanhe nfcom_canceled ou nfcom_cancellation_failed pelo webhook. A NFCom não expõe inutilização de numeração nesta API.

Uma nova DANFCOM é gerada automaticamente para o cancelamento.

Sincronizar

Igual à NFS-e, o botão Sincronizar força uma nova consulta ao provedor para o(s) documento(s) selecionado(s).

POST /nfcom/sync
{ "resolve": [{ "nfcom_id": "6a8543de85fabb49b3311cdc" }] }
Alternativa: resolver por CNPJ do emissor + ID externo
{ "resolve": [{ "issuer_tax_id": "42011994000191", "external_id": "nfcom-2026-001" }] }

XML e DANFCOM

Assim que o status vira authorized ou canceled, XML e DANFCOM são gerados e salvos automaticamente (pdfkit, QR Code oficial) — nenhum passo manual adicional. No sandbox, a DANFCOM sai com uma marca d'água SANDBOX na diagonal, para nunca ser confundida com um documento real.

DANFCOM real gerada pelo sandbox, com marca d'água SANDBOX na diagonal

Exemplo estrutural de XML (nfcomProc) autorizado:

XML de NFCom autorizada
<nfcomProc xmlns="http://www.portalfiscal.inf.br/nfcom" versao="1.00"><NFCom><infNFCom versao="1.00" Id="NFCom42260842011994000191620010000000041030483081"><ide><cUF>42</cUF><tpAmb>1</tpAmb><mod>62</mod><serie>1</serie><nNF>4</nNF><dhEmi>2026-08-19T05:49:19+00:00</dhEmi><cMunFG>4204202</cMunFG></ide><emit><CNPJ>42011994000191</CNPJ><IE>1234567890</IE><CRT>3</CRT><xNome>Empresa Sandbox LTDA</xNome><xFant>Empresa Sandbox</xFant><enderEmit><xLgr>Rua Sao Leopoldo</xLgr><nro>881</nro><xBairro>Esplanada</xBairro><cMun>4204202</cMun><xMun>Chapeco</xMun><UF>SC</UF></enderEmit></emit><dest><xNome>Cliente Sandbox</xNome><CPF>05823474911</CPF><indIEDest>9</indIEDest><enderDest><xLgr>Rua do Cliente</xLgr><nro>10</nro><xBairro>Bairro Alto</xBairro><xMun>Chapeco</xMun><UF>SC</UF></enderDest></dest><assinante><iCodAssinante>ASSIN-100</iCodAssinante><tpAssinante>3</tpAssinante><tpServUtil>4</tpServUtil></assinante><det nItem="1"><prod><cProd>PLANO-100</cProd><xProd>Plano de internet 100 MB</xProd><vProd>99.90</vProd></prod><imposto><ICMS00><CST>00</CST><vBC>99.90</vBC><pICMS>17.00</pICMS><vICMS>16.98</vICMS></ICMS00></imposto></det><total><vProd>99.90</vProd><ICMSTot><vBC>99.90</vBC><vICMS>16.98</vICMS></ICMSTot><vNF>99.90</vNF></total></infNFCom></NFCom></nfcomProc>

O link sai em pdf_url na leitura do documento e no payload do webhook — o mesmo nome usado em todos os documentos fiscais do e-docs.

Baixar o XML e a DANFCOM pela API
GET /nfcom/{nfcom_id}.xml?download_token=<token>   // nfcomProc quando authorized/canceled
GET /nfcom/{nfcom_id}.pdf?download_token=<token>   // DANFCOM — 202+Retry-After enquanto gera

NF-e

Enviar NF-e

O ambiente é configurado uma vez no modelo fiscal da empresa, igual aos demais modelos. environment só aceita production ou homologation — no sandbox, use production normalmente; a simulação é decidida pela plataforma, não pelo ambiente escolhido aqui.

Diálogo Configurar NF-e com emissão Nacional (SEFAZ), UF SC e série 1
PUT /nfe/config/companies/{cnpj}
{
  "environment": "production",
  "numbering": [{ "series": "1", "number": 1 }]
}    // UF e CRT vêm do cadastro da empresa; a 1ª série da lista é a padrão
POST /nfe
[
  {
    "external_id": "nfe-001",
    "identification": {
      "operation_nature": "VENDA DE MERCADORIA", "type": 1, "destination": 1, "purpose": 1,
      "final_consumer": true, "presence_indicator": 1, "taxable_event_municipality_code": "4204202"
    },
    "issuer": { "tax_id": "42011994000191" },
    "items": [{
      "product": { "code": "P001", "description": "PRODUTO TESTE", "ncm": "85044010", "cfop": "5102",
        "commercial_unit": "UN", "commercial_quantity": 1, "commercial_unit_value": 100, "total_value": 100,
        "taxable_unit": "UN", "taxable_quantity": 1, "taxable_unit_value": 100, "composes_total": true },
      "taxes": { "icms": { "csosn": "102", "origin": 0 } }
    }],
    "totals": { "icms": { "base": 0, "amount": 0, "products_amount": 100, "nfe_amount": 100 /* + demais campos zerados */ } },
    "transport": { "freight_mode": 9 },
    "payments": [{ "indicator": 0, "type": "01", "amount": 100 }]
  }
]
201 Created
[{
  "id": "6a84dbf451c71fcab8f1e2e4", "number": 1, "series": "1",
  "access_key": "42260842011994000191550010000000011100450868",
  "environment": "production", "status": "created"
}]

Não envie número, chave de acesso, protocolo ou URLs de artefato — a plataforma gera tudo isso. Só issuer.tax_id, sem endereço/IE/CRT (isso vem do cadastro da empresa). Após rejeição conclusiva, reenviar o mesmo emitente e external_id reaproveita id, número e série, mas cria nova tentativa e responde 200. Uso denegado (cStat 110, 301, 302 ou 303) ou documento vigente ativo responde 409, pois a numeração já foi registrada. Erro ou não sincronização com evidência de transmissão exige POST /nfe/{nfe_id}/sync.

Resposta e consulta

O envio devolve 201 quase na hora — a autorização é assíncrona, no mesmo padrão de NFS-e e NFCom. Prefira escutar o webhook em vez de ficar consultando via GET /nfe/{nfe_id}; use o GET só para conferência pontual.

GET /nfe/{id}Autorizada
{
  "status": "authorized",
  "environment": "production",
  "access_key": "42260842011994000191550010000000011100450868",
  "pdf_url": "https://.../nfe/6a84dbf4....pdf?download_token=...",
  "xml_url": "https://.../nfe/6a84dbf4....xml?download_token=...",
  "operation_control": { "can_cancel": true, "can_correct": true, "can_retry_manual_sync": true }
}

Cancelamento e inutilização

Cancelamento e sincronização seguem o mesmo padrão de NFS-e: o pedido é assíncrono e o webhook confirma ou falha o cancelamento. A NF-e tem uma operação exclusiva do modelo 55 — inutilizar uma faixa de numeração não usada, para manter a sequência íntegra junto à SEFAZ (operação irreversível).

Menu Mais ações da lista de NF-e, com as opções Cancelar, Inutilizações de faixa e Saúde por UF
POST /nfe/cancel
{
  "resolve": [{ "nfe_id": "6a84dbf451c71fcab8f1e2e4" }],
  "cancel_reason": "Cancelamento de teste do manual de integração"
}

Cada item de resolve[] aceita nfe_id OU issuer_tax_id + external_id — use a segunda forma quando o ERP não grava o ID interno da nota:

Alternativa: resolver por CNPJ do emissor + ID externo
{ "resolve": [{ "issuer_tax_id": "42011994000191", "external_id": "nfe-2026-001" }], "cancel_reason": "..." }
201 Created
{ "canceled_ids": ["6a84dbf451c71fcab8f1e2e4"], "failed": [] }

Sincronizar

Igual à NFS-e, o botão Sincronizar força uma nova consulta ao provedor para o(s) documento(s) selecionado(s).

POST /nfe/sync
{ "resolve": [{ "nfe_id": "6a84dbf451c71fcab8f1e2e4" }] }
Alternativa: resolver por CNPJ do emissor + ID externo
{ "resolve": [{ "issuer_tax_id": "42011994000191", "external_id": "nfe-2026-001" }] }

Inutilizar faixa

Lista de inutilizações de NF-e com um pedido homologado pela SEFAZ
POST /nfe/inutilizations
{
  "issuer_tax_id": "42011994000191",
  "series": "1",
  "number_start": 2,
  "number_end": 5,
  "justification": "Numeracao reservada e nao utilizada, inutilizada para manter sequencia junto a SEFAZ"
}

A homologação chega pelo webhook Faixa de NF-e inutilizada. O XML homologado (ProcInutNFe) fica disponível para download assim que a SEFAZ confirma.

XML e DANFE

Assim que o status vira authorized ou canceled, XML e DANFE são gerados e salvos automaticamente pelo mesmo pipeline dos demais modelos — nenhum passo manual adicional. No sandbox, a DANFE sai com uma marca d'água SANDBOX na diagonal, para nunca ser confundida com um documento real.

DANFE real gerada pelo sandbox, com marca d'água SANDBOX

XML real (nfeProc) desta emissão:

XML real da NF-e (leiaute 4.00, nfeProc)
<nfeProc xmlns="http://www.portalfiscal.inf.br/nfe" versao="4.00"><NFe><infNFe versao="4.00" Id="NFe42260842011994000191550010000000011100450868"><ide><cUF>42</cUF><natOp>VENDA DE MERCADORIA</natOp><mod>55</mod><serie>1</serie><nNF>1</nNF><tpNF>1</tpNF><idDest>1</idDest><cMunFG>4204202</cMunFG><tpAmb>1</tpAmb><finNFe>1</finNFe><indFinal>1</indFinal></ide><emit><CNPJ>42011994000191</CNPJ><xNome>Empresa Sandbox LTDA</xNome><enderEmit><xLgr>Rua Sao Leopoldo</xLgr><nro>881</nro><cMun>4204202</cMun><UF>SC</UF><CEP>89812530</CEP></enderEmit><CRT>1</CRT></emit><det nItem="1"><prod><cProd>P001</cProd><xProd>PRODUTO TESTE SANDBOX</xProd><NCM>85044010</NCM><CFOP>5102</CFOP><uCom>UN</uCom><qCom>1.00</qCom><vUnCom>100.00</vUnCom><vProd>100.00</vProd></prod><imposto><ICMS><ICMSSN102><CSOSN>102</CSOSN></ICMSSN102></ICMS></imposto></det><total><ICMSTot><vBC>0.00</vBC><vICMS>0.00</vICMS><vProd>100.00</vProd><vNF>100.00</vNF></ICMSTot></total><transp><modFrete>9</modFrete></transp><pag><detPag><tPag>01</tPag><vPag>100.00</vPag></detPag></pag></infNFe><Signature xmlns="http://www.w3.org/2000/09/xmldsig#">...</Signature></NFe><protNFe versao="4.00"><infProt><tpAmb>1</tpAmb><chNFe>42260842011994000191550010000000011100450868</chNFe><dhRecbto>2026-08-19T05:14:43+00:00</dhRecbto><nProt>353164456123549</nProt><cStat>100</cStat><xMotivo>Autorizado o uso da NF-e</xMotivo></infProt></protNFe></nfeProc>
Baixar o XML e a DANFE pela API
GET /nfe/{nfe_id}.xml?download_token=<token>   // nfeProc quando authorized/canceled
GET /nfe/{nfe_id}.pdf?download_token=<token>   // DANFE — 202+Retry-After enquanto gera

Anexos

Coleções Postman e Insomnia

Todas as requisições deste manual, prontas para importar — variáveis de ambiente para base_url, api_key e issuer_tax_id.

Anexos

Documentação técnica e site

Este manual cobre o fluxo de integração de ponta a ponta. Para a referência completa de campos, endpoints e modelos fiscais, use a documentação técnica:

Documentação técnica (GitBook) → Referência completa de endpoints, campos e modelos fiscais da API E-Docs.
edocs.ixcsoft.com.br → Site institucional do E-Docs, com o mapa de cobertura NFS-e e contato comercial.

Informativo

Acesso administrativo / suporte

Restrito a contas @ixcsoft — não é um passo do integrador O botão "Entrar com SSO" na tela de login é exclusivo para colaboradores IXC Soft autenticados via SSO corporativo. Acesso administrativo ou de suporte ao sandbox é solicitado internamente ao time de segurança — um integrador externo nunca precisa (nem consegue) passar por esse caminho; o cadastro público descrito em Cadastro e workspace é suficiente para tudo neste manual.