> ## Documentation Index
> Fetch the complete documentation index at: https://docs.engineapi.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Vindo da Nuvem Fiscal

> Guia de migração da Nuvem Fiscal para engineAPI: mapeamento de endpoints, campos e diferenças de comportamento.

A Nuvem Fiscal anunciou desativação em 31/07/2026. Este guia mapeia o contrato público dela (`api.nuvemfiscal.com.br/openapi/swagger.json`) para o da engineAPI, campo a campo.

**Tempo estimado de migração: 4-8 horas de desenvolvimento**

A Nuvem Fiscal expõe o leiaute bruto da SEFAZ em JSON (mesma estrutura do XML: `infNFe.ide`, `infNFe.det[].imposto.ICMS.ICMS00`, etc.). A engineAPI abstrai isso num payload plano. A migração não é só trocar nomes de campo: é escrever uma camada de tradução do leiaute bruto para o formato abstraído, daí o tempo maior que os outros guias desta coleção.

## Diferenças principais

| Aspecto                      | Nuvem Fiscal                                                                                                                                                                     | engineAPI                                                                                                                                                                                |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Autenticação**             | OAuth 2.0 client credentials: `POST https://auth.nuvemfiscal.com.br/oauth/token` troca `client_id`/`client_secret` por um token, usado depois em `Authorization: Bearer {token}` | `x-api-key: {key}` (integração server-to-server) ou `Authorization: Bearer {jwt}` (dashboard, via `POST /v1/auth/login`), sem passo de troca de token                                    |
| **Payload do documento**     | Leiaute bruto da SEFAZ em JSON (`infNFe.ide`, `infNFe.emit`, `infNFe.det[].prod`, `infNFe.det[].imposto`), mesma estrutura do XML                                                | Payload plano em camelCase (`items[]`, `destinatario`, `pagamentos[]`); a engineAPI monta o XML por trás                                                                                 |
| **Identificação do emissor** | Vai dentro do próprio documento: `infNFe.emit.CNPJ`. A empresa precisa estar cadastrada (`POST /empresas`) e com certificado ativo antes                                         | `issuerId` (UUID) no body, retornado por `POST /v1/companies`. Opcional com 1 emissor cadastrado; obrigatório com 2+                                                                     |
| **Ambiente**                 | Campo `ambiente` (`"homologacao"` / `"producao"`) dentro de CADA pedido de emissão                                                                                               | Amarrado ao emissor (`ambienteFiscal`). Todo emissor nasce em homologação; promover para produção é self-service via `PATCH /v1/companies/{id}/ambiente`, ver [Sandbox](/guides/sandbox) |
| **Cancelamento**             | `justificativa` opcional, a API preenche automaticamente se vazia                                                                                                                | `justificativa` **obrigatória**, mínimo 15 caracteres                                                                                                                                    |
| **Webhooks/eventos**         | Não há webhook nativo documentado no OpenAPI público; consulta é por polling (`GET /nfe/{id}`, `GET /nfe/eventos/{id}`)                                                          | Webhooks configuráveis (`PATCH /v1/webhooks/config`), com payload padronizado e assinatura HMAC                                                                                          |

## Mapeamento de endpoints

| Nuvem Fiscal                           | engineAPI                                 | Notas                                                                                                                                                                   |
| -------------------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `POST /empresas`                       | `POST /v1/companies`                      | Nuvem Fiscal usa `snake_case` (`cpf_cnpj`, `nome_razao_social`); engineAPI usa camelCase (`cnpj`, `name`); ver mapeamento de campos                                     |
| `GET /empresas/{cpf_cnpj}`             | `GET /v1/companies/{id}`                  | Identificador muda de CNPJ (string) para UUID interno                                                                                                                   |
| `PUT /empresas/{cpf_cnpj}/certificado` | `POST /v1/companies/{id}/certificate`     | Nuvem Fiscal aceita certificado em JSON base64 (`certificado`, `password`) ou multipart (`/certificado/upload`); engineAPI só multipart/form-data, campo `file`         |
| `POST /nfe`                            | `POST /v1/nfe`                            | Payload raiz completamente diferente, ver [Mapeamento de Campos](#mapeamento-de-campos)                                                                                 |
| `GET /nfe/{id}`                        | `GET /v1/nfe/{id}`                        | N/A                                                                                                                                                                     |
| `POST /nfe/{id}/cancelamento`          | `POST /v1/nfe/{idOuChave}/cancelar`       | `justificativa` opcional lá, obrigatória (mín. 15 caracteres) aqui                                                                                                      |
| `POST /nfe/{id}/carta-correcao`        | `POST /v1/nfe/{accessKey}/carta-correcao` | N/A                                                                                                                                                                     |
| `GET /nfe/{id}/xml`                    | `GET /v1/nfe/xml/{accessKey}`             | N/A                                                                                                                                                                     |
| `GET /nfe/{id}/pdf`                    | `GET /v1/nfe/pdf/{accessKey}`             | N/A                                                                                                                                                                     |
| `POST /nfce`                           | `POST /v1/nfce`                           | Nuvem Fiscal usa o MESMO leiaute bruto do `/nfe` (modelo NFC-e); engineAPI tem um payload próprio e mais simples (`destCPF`/`destNome` em vez de destinatário completo) |
| `POST /nfce/{id}/cancelamento`         | `POST /v1/nfce/{idOuChave}/cancelar`      | N/A                                                                                                                                                                     |
| `GET /nfce/{id}/xml`                   | `GET /v1/nfce/xml/{accessKey}`            | N/A                                                                                                                                                                     |
| `GET /nfce/{id}/pdf`                   | `GET /v1/nfce/pdf/{accessKey}`            | N/A                                                                                                                                                                     |
| `POST /nfse/dps`                       | `POST /v1/nfse`                           | Nuvem Fiscal exige o `infDPS` bruto do Sistema Nacional NFS-e (ADN); engineAPI abstrai em `tomador`/`servico`, mas ambos carregam o mesmo `cTribNac` nacional           |
| `GET /nfse/{id}`                       | `GET /v1/nfse/{id}`                       | N/A                                                                                                                                                                     |
| `POST /nfse/{id}/cancelamento`         | `POST /v1/nfse/{id}/cancelar`             | N/A                                                                                                                                                                     |
| `GET /nfse/{id}/xml`                   | `GET /v1/nfse/xml/{id}`                   | N/A                                                                                                                                                                     |

## Mapeamento de campos

### Raiz (NF-e/NFC-e: `infNFe.ide`)

| Campo Nuvem Fiscal    | Campo engineAPI    | Notas                                                                                                                     |
| --------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------- |
| `ambiente`            | N/A                | Sem equivalente por requisição: o ambiente é do emissor (`ambienteFiscal`), não do pedido. Ver [Sandbox](/guides/sandbox) |
| `infNFe.ide.natOp`    | `naturezaOperacao` | N/A                                                                                                                       |
| `infNFe.ide.serie`    | `serie`            | N/A                                                                                                                       |
| `infNFe.ide.nNF`      | `numero`           | Ausente na engineAPI = alocado automaticamente                                                                            |
| `infNFe.ide.tpNF`     | `tpNF`             | N/A                                                                                                                       |
| `infNFe.ide.idDest`   | `idDest`           | N/A                                                                                                                       |
| `infNFe.ide.indFinal` | `indFinal`         | N/A                                                                                                                       |
| `infNFe.ide.indPres`  | `indPres`          | N/A                                                                                                                       |
| `infNFe.ide.finNFe`   | `finNFe`           | N/A                                                                                                                       |
| `infNFe.emit.CNPJ`    | N/A                | Sem equivalente: engineAPI identifica o emissor por `issuerId` (UUID), não por CNPJ dentro do documento                   |

### Destinatário (`infNFe.dest`)

| Campo Nuvem Fiscal                     | Campo engineAPI                         | Notas                                                        |
| -------------------------------------- | --------------------------------------- | ------------------------------------------------------------ |
| `infNFe.dest.CNPJ` / `infNFe.dest.CPF` | `destinatario.cnpjCpf`                  | Campo único (11 a 14 dígitos), não há `CNPJ`/`CPF` separados |
| `infNFe.dest.xNome`                    | `destinatario.nome`                     | N/A                                                          |
| `infNFe.dest.indIEDest`                | `destinatario.indicadorIE`              | N/A                                                          |
| `infNFe.dest.IE`                       | `destinatario.ie`                       | N/A                                                          |
| `infNFe.dest.email`                    | `destinatario.email`                    | N/A                                                          |
| `infNFe.dest.enderDest.xLgr`           | `destinatario.endereco.logradouro`      | N/A                                                          |
| `infNFe.dest.enderDest.nro`            | `destinatario.endereco.numero`          | N/A                                                          |
| `infNFe.dest.enderDest.xCpl`           | `destinatario.endereco.complemento`     | N/A                                                          |
| `infNFe.dest.enderDest.xBairro`        | `destinatario.endereco.bairro`          | N/A                                                          |
| `infNFe.dest.enderDest.cMun`           | `destinatario.endereco.codigoMunicipio` | Código IBGE                                                  |
| `infNFe.dest.enderDest.xMun`           | `destinatario.endereco.municipio`       | N/A                                                          |
| `infNFe.dest.enderDest.UF`             | `destinatario.endereco.uf`              | N/A                                                          |
| `infNFe.dest.enderDest.CEP`            | `destinatario.endereco.cep`             | N/A                                                          |

### Item: produto (`infNFe.det[].prod`)

| Campo Nuvem Fiscal         | Campo engineAPI         | Notas                                                                                    |
| -------------------------- | ----------------------- | ---------------------------------------------------------------------------------------- |
| `infNFe.det[].nItem`       | N/A                     | Não existe campo de número por item na engineAPI: o índice do array já identifica o item |
| `infNFe.det[].prod.cProd`  | `items[].codigo`        | N/A                                                                                      |
| `infNFe.det[].prod.cEAN`   | `items[].ean`           | Ausente na engineAPI = "SEM GTIN"                                                        |
| `infNFe.det[].prod.xProd`  | `items[].descricao`     | N/A                                                                                      |
| `infNFe.det[].prod.NCM`    | `items[].ncm`           | N/A                                                                                      |
| `infNFe.det[].prod.CEST`   | `items[].cest`          | N/A                                                                                      |
| `infNFe.det[].prod.CFOP`   | `items[].cfop`          | N/A                                                                                      |
| `infNFe.det[].prod.uCom`   | `items[].unidade`       | N/A                                                                                      |
| `infNFe.det[].prod.qCom`   | `items[].quantidade`    | N/A                                                                                      |
| `infNFe.det[].prod.vUnCom` | `items[].valorUnitario` | N/A                                                                                      |
| `infNFe.det[].prod.vProd`  | `items[].valorTotal`    | Opcional na engineAPI, recalculado se ausente                                            |
| `infNFe.det[].prod.vDesc`  | `items[].desconto`      | Desconto incondicional                                                                   |

### Item: tributos (`infNFe.det[].imposto`)

O grupo `imposto` da Nuvem Fiscal é um **union por CST/CSOSN**: cada situação tributária tem seu próprio objeto (`ICMS00`, `ICMS10`, `ICMS20`... `ICMSSN101`, `ICMSSN102`...). A engineAPI usa um único objeto flexível por item (`items[].icms`), sem sub-tipar por CST.

| Campo Nuvem Fiscal                                              | Campo engineAPI              | Notas                                   |
| --------------------------------------------------------------- | ---------------------------- | --------------------------------------- |
| `imposto.ICMS.ICMS00.orig` (ou equivalente nos demais `ICMSxx`) | `items[].icms.origem`        | N/A                                     |
| `imposto.ICMS.ICMS00.CST`                                       | `items[].icms.cst`           | Regime Lucro Real/Presumido             |
| `imposto.ICMS.ICMSSN101.CSOSN` (ou demais `ICMSSNxxx`)          | `items[].icms.csosn`         | Regime Simples Nacional                 |
| `imposto.ICMS.ICMS00.vBC`                                       | `items[].icms.baseCalculo`   | N/A                                     |
| `imposto.ICMS.ICMS00.pICMS`                                     | `items[].icms.aliquota`      | N/A                                     |
| `imposto.ICMS.ICMS00.vICMS`                                     | `items[].icms.valor`         | N/A                                     |
| `imposto.PIS.PISAliq.CST`                                       | `items[].pis.cst`            | N/A                                     |
| `imposto.PIS.PISAliq.vBC`                                       | `items[].pis.baseCalculo`    | N/A                                     |
| `imposto.PIS.PISAliq.pPIS`                                      | `items[].pis.aliquota`       | N/A                                     |
| `imposto.PIS.PISAliq.vPIS`                                      | `items[].pis.valor`          | N/A                                     |
| `imposto.COFINS.COFINSAliq.CST`                                 | `items[].cofins.cst`         | N/A                                     |
| `imposto.COFINS.COFINSAliq.vBC`                                 | `items[].cofins.baseCalculo` | N/A                                     |
| `imposto.COFINS.COFINSAliq.pCOFINS`                             | `items[].cofins.aliquota`    | N/A                                     |
| `imposto.COFINS.COFINSAliq.vCOFINS`                             | `items[].cofins.valor`       | N/A                                     |
| `imposto.IPI.IPITrib.CST`                                       | `items[].ipi.cst`            | Só NF-e: a NFC-e não tem IPI no leiaute |
| `imposto.IPI.IPITrib.vBC`                                       | `items[].ipi.baseCalculo`    | N/A                                     |
| `imposto.IPI.IPITrib.pIPI`                                      | `items[].ipi.aliquota`       | N/A                                     |
| `imposto.IPI.IPITrib.vIPI`                                      | `items[].ipi.valor`          | N/A                                     |
| `imposto.IPI.cEnq`                                              | `items[].ipi.cEnq`           | N/A                                     |

### Pagamento (`infNFe.pag`)

| Campo Nuvem Fiscal         | Campo engineAPI      | Notas                              |
| -------------------------- | -------------------- | ---------------------------------- |
| `infNFe.pag.detPag[].tPag` | `pagamentos[].forma` | Código SEFAZ da forma de pagamento |
| `infNFe.pag.detPag[].vPag` | `pagamentos[].valor` | N/A                                |
| `infNFe.pag.vTroco`        | `troco`              | N/A                                |

### Empresa (cadastro do emissor)

| Campo Nuvem Fiscal          | Campo engineAPI | Notas                                                                                           |
| --------------------------- | --------------- | ----------------------------------------------------------------------------------------------- |
| `cpf_cnpj`                  | `cnpj`          | N/A                                                                                             |
| `nome_razao_social`         | `name`          | N/A                                                                                             |
| `nome_fantasia`             | `tradeName`     | N/A                                                                                             |
| `inscricao_estadual`        | `ie`            | N/A                                                                                             |
| `inscricao_municipal`       | `im`            | N/A                                                                                             |
| `fone`                      | `phone`         | N/A                                                                                             |
| `email`                     | `email`         | N/A                                                                                             |
| `endereco.logradouro`       | `address`       | Sem equivalente aninhado: engineAPI usa campos PLANOS na raiz do body, não um objeto `endereco` |
| `endereco.numero`           | `number`        | N/A                                                                                             |
| `endereco.complemento`      | `complement`    | N/A                                                                                             |
| `endereco.bairro`           | `neighborhood`  | N/A                                                                                             |
| `endereco.codigo_municipio` | `ibgeCode`      | N/A                                                                                             |
| `endereco.cidade`           | `city`          | N/A                                                                                             |
| `endereco.uf`               | `state`         | N/A                                                                                             |
| `endereco.cep`              | `cep`           | N/A                                                                                             |

### NFS-e (`infDPS`)

| Campo Nuvem Fiscal                     | Campo engineAPI                     | Notas                                              |
| -------------------------------------- | ----------------------------------- | -------------------------------------------------- |
| `infDPS.toma.CNPJ` / `infDPS.toma.CPF` | `tomador.cnpjCpf`                   | Campo único                                        |
| `infDPS.toma.xNome`                    | `tomador.razaoSocial`               | N/A                                                |
| `infDPS.toma.IM`                       | `tomador.inscricaoMunicipal`        | N/A                                                |
| `infDPS.serv.cServ.cTribNac`           | `dpsNacional.cTribNac`              | Código de tributação nacional do ISSQN (6 dígitos) |
| `infDPS.serv.cServ.cTribMun`           | `servico.codigoTributacaoMunicipio` | N/A                                                |
| `infDPS.serv.cServ.xDescServ`          | `servico.discriminacao`             | N/A                                                |
| `infDPS.valores.vServPrest.vServ`      | `servico.valorServicos`             | N/A                                                |
| `infDPS.dCompet`                       | `competencia`                       | N/A                                                |

## Diferenças importantes

<AccordionGroup>
  <Accordion title="O payload deixa de ser o leiaute bruto da SEFAZ">
    A Nuvem Fiscal expõe o JSON praticamente idêntico ao XML da SEFAZ: os mesmos grupos (`ide`, `emit`, `dest`, `det`, `imposto`) e o mesmo union por CST/CSOSN dentro de `imposto.ICMS`. A engineAPI abstrai tudo isso num payload plano (`items[].icms` único, sem sub-tipar por CST). Isso reduz o volume do payload, mas exige reescrever a camada que monta a nota: não dá para só renomear campos 1:1.
  </Accordion>

  <Accordion title="O emissor sai do documento e vira issuerId">
    Na Nuvem Fiscal, o emissor é identificado pelo CNPJ dentro do próprio `infNFe.emit`. Na engineAPI, é o `issuerId` (UUID) retornado por `POST /v1/companies`, opcional com um único emissor cadastrado, obrigatório a partir do segundo.
  </Accordion>

  <Accordion title="Ambiente é do emissor, não do pedido">
    A Nuvem Fiscal escolhe homologação/produção a cada requisição (campo `ambiente`). Na engineAPI, o ambiente é uma propriedade do emissor (`ambienteFiscal`): todo emissor nasce em homologação; promover para produção é self-service, ver [Sandbox](/guides/sandbox).
  </Accordion>

  <Accordion title="Cancelamento passa a exigir justificativa">
    Na Nuvem Fiscal, `justificativa` é opcional (preenchida automaticamente se vazia). Na engineAPI, é obrigatória (mínimo 15 caracteres) em `POST /v1/nfe/{idOuChave}/cancelar` e `POST /v1/nfce/{idOuChave}/cancelar`.
  </Accordion>

  <Accordion title="Notificação passa a ser webhook, não polling">
    O OpenAPI público da Nuvem Fiscal não documenta webhook: o consumo de eventos é via polling nos endpoints de consulta (`GET /nfe/eventos/{id}`, por exemplo). A engineAPI notifica por webhook configurável (`PATCH /v1/webhooks/config`), com assinatura HMAC no payload.
  </Accordion>
</AccordionGroup>

## Checklist de migração

<Steps>
  <Step title="Criar conta na engineAPI">
    Registre-se em [app.engineapi.com.br](https://app.engineapi.com.br) e gere sua API Key.
  </Step>

  <Step title="Cadastrar empresas emissoras">
    `POST /v1/companies` para cada CNPJ, convertendo os campos conforme a tabela [Empresa](#empresa-cadastro-do-emissor). Atenção ao endereço, que deixa de ser aninhado.
  </Step>

  <Step title="Upload dos certificados">
    `POST /v1/companies/{id}/certificate` (multipart, campo `file`) com o `.pfx` de cada empresa. A Nuvem Fiscal aceitava base64 em JSON, a engineAPI só multipart.
  </Step>

  <Step title="Testar em homologação">
    Todo emissor novo já nasce em homologação (`ambienteFiscal: 2`). Emita notas de teste e valide os mapeamentos, sem precisar de um campo `ambiente` por requisição.
  </Step>

  <Step title="Escrever a camada de tradução do payload">
    Converta o leiaute bruto (`infNFe.ide`/`dest`/`det`/`imposto`) para o payload plano da engineAPI (`naturezaOperacao`, `destinatario`, `items[]`, `pagamentos[]`) usando as tabelas acima: é o passo que consome a maior parte do tempo estimado.
  </Step>

  <Step title="Adaptar o cancelamento">
    Passe a enviar `justificativa` com pelo menos 15 caracteres em todo cancelamento. Na Nuvem Fiscal esse campo era opcional.
  </Step>

  <Step title="Configurar webhooks">
    Troque o polling por `PATCH /v1/webhooks/config` para receber eventos em tempo real.
  </Step>

  <Step title="Migrar para produção">
    Promover o emissor para produção é self-service, ver [Sandbox](/guides/sandbox).
  </Step>

  <Step title="Desativar a integração com a Nuvem Fiscal">
    Após validar a estabilidade por 1-2 semanas, encerre a integração antiga.
  </Step>
</Steps>

## Próximos passos

* [Autenticação](/authentication): JWT e API Keys da engineAPI.
* [Webhooks](/guides/webhooks): configurar notificações em tempo real.
