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

# integração de notas fiscais

> a integração de notas fiscais envia para a teceo as NF-e já emitidas pelo seu ERP, vinculando-as ao cliente e aos pedidos que originaram o faturamento

## fluxo principal

<Steps>
  <Step title="emitir a nota no seu ERP">
    a teceo não emite NF-e. o faturamento continua acontecendo no seu sistema.
  </Step>

  <Step title="criar a nota na teceo">
    envie número, série e chave de acesso, o cliente, os valores totais, os itens faturados e os pedidos que originaram a nota. guarde o `id` devolvido.
  </Step>

  <Step title="anexar o DANFE e o XML">
    vincule os arquivos à nota criada, por url ou enviando o binário. este passo é opcional na API, mas sem ele ninguém consegue baixar os arquivos pela plataforma.
  </Step>
</Steps>

## endpoints

| endpoint | o que faz |
| - | - |
| `POST /v1/invoices` | cria a nota com os itens e o vínculo com os pedidos, e devolve o `id` dela |
| `GET /v1/invoices` | lista as notas, com filtro por data de emissão, série, cliente e status |
| `GET /v1/invoices/{invoiceId}` | traz a nota com os pedidos vinculados e os itens faturados |
| `PUT /v1/invoices/{invoiceId}/attachments/pdf` | vincula o DANFE em PDF à nota |
| `PUT /v1/invoices/{invoiceId}/attachments/xml` | vincula o XML à nota |

os campos de cada rota, com tipo, obrigatoriedade e exemplo, estão na página da própria rota, no menu ao lado. a listagem é paginada por cursor, como descrito em [paginação](/integracoes/brand/paginacao).

## regras de negócio

### vínculo com cliente e pedidos

o `customerCode` precisa ser de um cliente que já existe na teceo com esse código preenchido. não há alternativa por CNPJ.

<Warning>
  `orderCodes` e `items[].orderCode` esperam o **código do pedido no seu ERP**, o mesmo que você enviou como `integrationCode` ao [sincronizar o pedido](/integracoes/brand/pedidos/overview). item sem `orderCode` é gravado sem vínculo e volta com `orderId: null`, sem erro.
</Warning>

quando o item informa `orderCode`, esse código também precisa estar em `orderCodes`.

### guarde o `id`

o `id` da nota identifica ela nos anexos e nas contas a receber. o `409` de nota duplicada não devolve o `id`, e a listagem não filtra por `code` nem por `accessKey`, então sem guardar você depende de paginar a listagem para reencontrar a nota.

### status da nota

a nota nasce com status `INVOICED` e a API não altera status. cancelar no ERP só reflete aqui nas marcas com conector ativo e importação automática de notas ligada, e nesse caso a varredura alcança também as notas criadas pela API. os outros status aparecem em notas que chegaram por esses fluxos de integração com o ERP.

### criação

a criação grava a nota, os itens faturados e o vínculo com os pedidos de origem. ela não baixa estoque, não muda o status do pedido, não gera contas a receber e não dispara webhook.

* o vínculo entre nota e pedido é de muitos para muitos, então uma nota pode cobrir vários pedidos e várias notas podem apontar para o mesmo pedido
* a quantidade de cada item é gravada como veio, então faturamento parcial e quantidade acima da pedida são aceitos
* os valores do cabeçalho também são gravados como vieram, sem conferir com a soma dos itens

### listagem e detalhe

* a listagem vem da nota mais antiga para a mais recente, por data de criação na teceo e não pela data de emissão. nota nova sempre entra no fim
* a listagem já traz o cabeçalho completo, com `pdfUrl`, `xmlUrl`, `status` e cliente. os itens e os pedidos vinculados só vêm no detalhe

### anexos

anexar é opcional para a API, e a nota existe sem os arquivos. só que sem eles o download do DANFE e do XML falha, e a plataforma esconde a ação de exportar.

* envie `url` **ou** `file`, nunca os dois e nunca nenhum
* o tamanho máximo é **10 MiB** nas duas formas. por `file`, acima de 20 MiB o parser recusa antes de chegar na aplicação, com `413`
* o conteúdo é conferido pela assinatura do arquivo, então o PDF precisa ser um PDF e o XML precisa ser um XML, independente do nome ou da extensão
* o download da url tem timeout de **10 segundos**
* o arquivo é re-hospedado pela teceo, que passa a servi-lo pela própria url. a url de origem não é usada na plataforma
* reenviar o anexo gera uma url nova e apaga o arquivo anterior. não existe versionamento, então quem guardou a url antiga perde o acesso a ela
* a resposta não devolve a url final do arquivo. para obter `pdfUrl` e `xmlUrl`, consulte o detalhe da nota

## erros

### ao criar a nota

| status | código | quando acontece |
| - | - | - |
| `409` | `api.exception.invoiceAlreadyExists` | já existe uma nota sua na teceo com o mesmo `code` + `series`, ou com a mesma `accessKey` |
| `404` | `api.exception.invoiceCustomerNotFound` | o `customerCode` não existe na sua base na teceo |
| `400` | `api.exception.invoiceOrderNotSynced` | algum código em `orderCodes` não corresponde a um pedido sincronizado, ou um item aponta para um `orderCode` que não foi declarado em `orderCodes` |
| `404` | `api.exception.invoiceSkuNotFound` | algum `skuCode` dos itens não existe na sua base na teceo |

### ao anexar

| status | código | quando acontece |
| - | - | - |
| `400` | `api.exception.invoiceAttachmentUrlOrFileRequired` | nenhuma ou as duas fontes foram enviadas |
| `400` | `api.exception.invoiceAttachmentTooLarge` | o arquivo passa de 10 MiB |
| `400` | `api.exception.invoiceAttachmentDownloadFailed` | a url não respondeu, estourou o timeout ou devolveu erro |
| `400` | `api.exception.invoiceAttachmentInvalidType` | o conteúdo não corresponde ao tipo do endpoint |
| `404` | `api.exception.invoiceNotFound` | a nota não existe na sua base na teceo |
| `413` | - | o arquivo enviado em `file` passa de 20 MiB |

o `code` acompanha os erros de regra de negócio listados aqui, mas não serve para separar erro da aplicação de erro de infraestrutura. o `413` vem do parser de upload, e o `404` do detalhe da nota e os `400` de validação de payload também chegam sem ele, só com `status` e `message`.

## exemplo de fluxo completo

```mermaid theme={null}
sequenceDiagram
    participant ERP as seu sistema
    participant API as teceo API

    ERP->>ERP: emite a NF-e
    ERP->>API: POST /v1/invoices
    API-->>ERP: id da nota

    ERP->>API: PUT /v1/invoices/{invoiceId}/attachments/pdf
    API-->>ERP: anexo vinculado

    ERP->>API: PUT /v1/invoices/{invoiceId}/attachments/xml
    API-->>ERP: anexo vinculado
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.