Notas / faturas
Como criar notas (invoices) na API de Integrações, vinculá-las a pedidos, gerar contas a receber e registrar impostos.
Uma nota / fatura (/invoices) é o documento de faturamento de uma venda. É a terceira etapa do fluxo de vendas: pode ser ligada a um pedido, carregar impostos por item e gerar contas a receber.
Permissão exigida: invoices (ações create, read, update, delete).
Esta é a nota comercial. A API de Integrações oferece o CRUD; ela não transmite documentos fiscais (NFe/NFSe) nem faz "emissão" — esses fluxos ficam fora deste canal.
Conceitos e campos-chave
| Campo | Tipo | Obrigatório | Observações |
|---|---|---|---|
reference_code | string | Sim | Exatamente 9 dígitos (^\d{9}$, ex.: "000000042"). Não é auto-gerado |
customer_id | UUID | Sim* | *Ou o objeto customer inline — exatamente um dos dois |
product_type | enum | Sim | goods, service ou mixed |
invoice_date | date | Sim | YYYY-MM-DD |
items | array | Sim | 1 a 200 itens |
series | string | Não | Série do documento |
operation_type | string | Não | Padrão sale |
sales_order_id | UUID | Não | Pedido de origem (ver validações abaixo) |
customer_tax_type | enum | Não | individual ou company |
discount_amount | string | Não | Desconto em valor (≥ 0) — decimal numeric(18,6) como string |
discount_rate | number | Não | Percentual do subtotal (0 a 100; ex.: 15 = 15%). Percentual segue number |
fiscal_notes, internal_notes | string | Não | |
taxes | array | Não | Impostos manuais por item (ver abaixo) |
receivables | array | Não | Gera contas a receber (ver abaixo) |
metadata, br_data, us_data | — | Não |
discount_rateusa a escala percentual (0 a 100) —15significa 15%, igual a orçamentos e pedidos.
Itens da nota
Cada item referencia um product_id ou traz um product inline (exatamente um dos dois). Campos: item_description, quantity (string decimal ≥ "0.000001"), unit_price (string decimal ≥ "0"), discount_amount (string decimal). Para rastrear a origem no pedido, informe sales_order_item_id no item.
Impostos (taxes[])
Impostos são informados por item, com tax_code, tax_name, base_amount (string decimal), rate (número, 0 a 100), amount (string decimal), position (inteiro) e flags como is_withheld (retido) e is_included. Códigos aceitos: ISS, PIS, COFINS, IR, CSLL, INSS, IBS_STATE, IBS_CITY, CBS.
Vínculo com o pedido
Ao enviar sales_order_id, a API valida que customer_id, operation_type e product_type da nota casam com os do pedido. Só pode existir uma nota ativa por pedido — uma segunda tentativa retorna erro. Ver o fluxo de vendas.
Gerando contas a receber
Inclua um array receivables[] (amount — decimal como string —, due_date date-time, financial_account_id; opcionais payment_method_id, description). A soma de receivables[].amount deve ser exatamente igual ao total líquido da nota (net_receivable_total = total − impostos retidos), senão a criação é rejeitada. Se houver mais de um, viram parcelas.
Os recebíveis criados nascem pending e ficam ligados por origin_type = "invoice"; eles não aparecem no corpo da nota — consulte-os no recurso /receivables.
Criar uma nota (ligada ao pedido, com recebível)
curl -X POST https://api.biterp.ai/invoices \
-H "Authorization: Bearer sk_xxx_yyy" \
-H "Content-Type: application/json" \
-d '{
"reference_code": "000000042",
"customer_id": "8f2c1e4a-9b3d-4c7e-a1f2-6d5b8e0c3a71",
"sales_order_id": "7e6d5c4b-3a2f-4109-8e7d-6c5b4a3f2e1d",
"product_type": "goods",
"invoice_date": "2026-07-06",
"operation_type": "sale",
"items": [
{
"product_id": "3a7b9c2d-1e4f-4a6b-8c0d-2f5e7a9b1c3d",
"item_description": "Cadeira ergonômica",
"quantity": "2.000000",
"unit_price": "450.000000",
"sales_order_item_id": "d4c3b2a1-9f8e-4706-a5b4-c3d2e1f0a9b8"
},
{
"product_id": "5d8e1f3a-6b2c-4d7e-9a0f-1c3b5e7d9a2f",
"item_description": "Mesa de escritório",
"quantity": "1.000000",
"unit_price": "1200.000000"
}
],
"receivables": [
{
"amount": "2100.000000",
"due_date": "2026-08-06T00:00:00.000Z",
"financial_account_id": "9c8b7a6d-5e4f-4321-8b0a-1d2c3e4f5a6b"
}
]
}'Sem impostos retidos,
net_receivable_totalé igual ao total (2 × 450 + 1 × 1200 = 2100), entãoreceivables[].amountsoma"2100.000000".
Status e atualização
Pela API de Integrações, toda nota nasce em status: draft (os estados comerciais são draft, finalized, cancelled). No PATCH, os campos status, reference_code, series e operation_type não são editáveis.
Enviar items substitui a lista inteira: linhas com id são mantidas, omitidas são removidas.
Já taxes tem três comportamentos distintos no PATCH:
taxes no corpo | Efeito |
|---|---|
| Ausente | Não altera impostos. Enviando items, cada linha mantida preserva os impostos que já tinha. |
[] (array vazio) | Remove todos os impostos que seriam preservados. |
| Preenchido | Com items: substituição por item, endereçada pelo item_index — só as linhas citadas trocam de impostos; as não citadas preservam os que já tinham. Sem items: substitui o conjunto inteiro de impostos da nota. |
Um item que traga tax_resolution_id é sempre re-resolvido pelo motor fiscal, mesmo com taxes: [] — o array vazio limpa apenas os impostos preservados, não uma re-resolução pedida no mesmo corpo.
Mudança de comportamento no array vazio
Até então, enviar items junto de taxes: [] era tratado como "nenhuma substituição
por item" e preservava os impostos existentes. Agora esse par remove os
impostos. Se a sua integração enviava taxes: [] só para preencher o campo, omita
taxes do corpo para manter o comportamento anterior.
DELETE /invoices/{id} remove notas draft/finalized; recebíveis já pagos bloqueiam a exclusão.
Referência dos endpoints
| Método | Endpoint | Referência |
|---|---|---|
| POST | /invoices | Criar nota |
| GET | /invoices | Listar notas |
| GET | /invoices/{id} | Buscar por ID |
| PATCH | /invoices/{id} | Atualizar nota |
| DELETE | /invoices/{id} | Remover nota |

