Invosend

API de Geração de Faturas

Gere faturas em PDF profissionais programaticamente a partir do seu próprio servidor, adequado para sistemas internos, marketplaces ou seu próprio produto SaaS.

1. Autenticação#

Crie uma chave de API em app.invosend.com/settings/api-keys. É necessário um plano de espaço de trabalho pago e a função de proprietário.

Envie a chave como token Bearer no cabeçalho Authorization em cada solicitação:

Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx
Chaves de API ausentes, malformadas, inválidas ou revogadas são rejeitadas com 403. As chaves também são rejeitadas se o espaço de trabalho estiver em um plano gratuito, suspenso ou expirado.

2. Endpoint#

POST/api/invoices/generate-external

URL Base: https://app.invosend.com

Descrição da API legível por máquina: OpenAPI 3.1 e Postman collection. Importe qualquer uma no Postman, no Insomnia ou em um gerador de SDK.

3. Corpo da Solicitação#

CampoTipoObrigatórioDescrição
customer_namestringSimNome do cliente ou destinatário da fatura.
customer_emailstringNãoEndereço de e-mail válido. A fatura criada por esta chamada não é enviada por e-mail (esta API não envia e-mails). Obrigatório para faturas recorrentes: cada fatura gerada depois é enviada para este endereço.
customer_tax_idstringNãoNúmero de identificação fiscal do cliente (NPWP na Indonésia, até 40 caracteres). Impresso abaixo do endereço do cliente na fatura.
itemsarraySimPelo menos 1 item válido com descrição, quantity > 0, e price >= 0.
items[].descriptionstringNãoNome do produto ou serviço. Se vazio, usa Item.
items[].quantitynumberSimNúmero de unidades, com até 2 casas decimais (por exemplo 1.5 hora), de 0.01 a 999.999.
items[].pricenumberSimPreço por unidade.
items[].discountnumberNãoValor do desconto por item. Padrão 0.
currencystringNãoCódigo da moeda, como IDR ou USD. Padrão IDR.
tax_ratenumberNãoPercentual de imposto calculado sobre o subtotal após o desconto. Padrão 0.
due_datestringNãoFormato YYYY-MM-DD. Padrão 14 dias após a geração.
notesstringNãoNotas adicionais exibidas na fatura.
items[].unitstringNãoRótulo de unidade exibido ao lado da quantidade, como pcs ou hour.
items[].tax_ratenumberNãoSubstituição do percentual de imposto por item (0-100). Omita para usar o tax_rate no nível da fatura para esse item.
discount_totalnumberNãoDesconto no nível da fatura. É subtraído antes do imposto, então o imposto é calculado sobre o valor com desconto (rateado entre os itens na proporção do valor de cada um). Padrão 0.
templatestringNãoID do modelo de fatura a usar. Veja os disponíveis com GET /api/invoices/external/templates. Se omitido, usa-se o modelo padrão escolhido em Configurações e, depois, o padrão do Invosend.
document_languagestringNãoIdioma das palavras do documento da fatura (PDF e e-mail): en (padrão), id, es, fr, de, nl, it, pt, zh, ja, hi, ar (indonésio, espanhol, francês, alemão, holandês, italiano, português do Brasil, chinês simplificado, japonês, hindi, árabe). Qualquer outro valor é recusado com um erro. O layout interno simples, usado apenas quando não existe nenhum modelo, é sempre em inglês.
custom_payment_notesstringNãoInstruções de pagamento extras exibidas no PDF.
footer_textstringNãoTexto curto exibido na parte inferior do PDF.
is_recurringbooleanNãoCria uma série recorrente. Esta fatura é a primeira; as próximas são geradas e enviadas automaticamente para customer_email conforme o cronograma, cada uma usando 1 crédito de fatura. Requer um plano com o recurso de faturas recorrentes, além de recurring_interval e customer_email.
recurring_intervalstringNãoCom que frequência a série se repete: um de weekly, fortnightly, monthly, quarterly, semi-annually, yearly. Obrigatório quando is_recurring é true.
recurring_countintegerNãoNúmero total de faturas da série, incluindo esta primeira: um inteiro de 2 a 121. Padrão 4. Use este campo ou recurring_end_date, não ambos.
recurring_end_datestringNãoData após a qual nenhuma fatura nova é gerada, YYYY-MM-DD, no futuro. Use este campo ou recurring_count, não ambos.
payment_gatewaystringNãoUm de midtrans, xendit, stripe, paypal, razorpay, mollie. O gateway já deve estar conectado no espaço de trabalho.
payment_accountstringNãoID de uma conta de pagamento existente (dados bancários) para anexar à fatura.

Exemplo completo de solicitação:

curl -X POST https://app.invosend.com/api/invoices/generate-external \
  -H "Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_name": "Acme Corp",
    "customer_email": "billing@acme.com",
    "items": [
      { "description": "Consulting Services", "quantity": 2, "price": 2500, "tax_rate": 11 }
    ],
    "discount_total": 250,
    "currency": "BRL",
    "notes": "Thank you for your business."
  }'

Exemplo de fatura recorrente (a primeira agora e depois uma por mês, 6 no total):

curl -X POST https://app.invosend.com/api/invoices/generate-external \
  -H "Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_name": "Acme Corp",
    "customer_email": "billing@acme.com",
    "items": [
      { "description": "Monthly retainer", "quantity": 1, "price": 12500 }
    ],
    "currency": "BRL",
    "recurring_interval": "monthly",
    "recurring_count": 6
  }'
Para tentar novamente com segurança após um timeout ou erro de rede, adicione um cabeçalho Idempotency-Key (1-255 caracteres, por exemplo um UUID gerado para cada fatura). Se a primeira requisição teve sucesso, a nova tentativa devolve a mesma resposta com o cabeçalho Idempotent-Replayed: true, sem criar outra fatura nem usar outro crédito (credits_remaining é o valor da primeira chamada). As chaves ficam guardadas por 24 horas por workspace. Apenas respostas bem-sucedidas são armazenadas, então uma requisição que falhou pode ser repetida com a mesma chave.

4. Resposta#

200 OK significa que a fatura foi criada e o PDF foi gerado:

{
  "data": {
    "id": "cjld2cjxh0000qzrmn831i7rn",
    "invoice_number": "INV-1-202609-0016",
    "pdf_url": "https://cdn.invosend.com/company/1/pdf/Invoice_INV_1_202609_0016_UNPAID_0da2beeabb.pdf",
    "credits_remaining": 24,
    "is_recurring": false,
    "template": {
      "id": "k3p9x2m7c0000abcd1234efgh",
      "name": "Classic",
      "source": "system_default"
    }
  }
}
credits_remaining é null quando o espaço de trabalho tem cota ilimitada. id identifica esta fatura para os endpoints adicionais abaixo. Faturas criadas por esta API também aparecem na lista de faturas do espaço de trabalho e usam a mesma sequência de numeração de faturas criadas manualmente. Os números de fatura têm a forma INV-{id do workspace}-{AAAAMM}-{sequência}. Em uma fatura recorrente, a resposta inclui também um objeto recurring: schedule_id, interval, occurrences, next_issue_date, end_date. recurring.schedule_id é o id usado nos endpoints de recorrência abaixo.

5. Códigos de Erro#

StatusCausa
400Campos obrigatórios ausentes ou inválidos: customer_name, items vazio, nenhum item válido, um payment_gateway não reconhecido, um payment_gateway não conectado neste workspace ou, em uma fatura recorrente, recurring_interval ou customer_email ausente, ou recurring_count / recurring_end_date inválido. Este status também é retornado se o PDF não puder ser gerado: repita a requisição (nenhum crédito é descontado).
402O saldo de invoice_credits do espaço de trabalho está vazio. Recarregue os créditos para continuar.
403O cabeçalho Authorization está ausente ou malformado, a chave de API é inválida ou foi revogada, ou o plano do espaço de trabalho não inclui acesso à API.
403 (recorrente)is_recurring foi definido, mas o plano do espaço de trabalho não inclui faturas recorrentes.
409Uma requisição com a mesma Idempotency-Key ainda está sendo processada. Tente novamente em instantes.
422A Idempotency-Key já foi usada com um corpo de requisição diferente. Use uma nova chave para uma nova fatura.
429Limite de taxa excedido. Veja a seção Limite de Taxa.

6. Limite de Taxa#

EscopoLimite
Por workspace (todas as requisições da API somadas)Professional 10/min · Specialist 20/min · Business 30/min · Enterprise 60/min
Por endereço IP (todas as requisições da API somadas)30 solicitações/minuto
Chaves de API ativas por workspaceProfessional 3 · Specialist 5 · Business 10 · Enterprise 20
A geração de faturas e os endpoints de leitura/gerenciamento compartilham o mesmo limite. Respostas bem-sucedidas incluem os cabeçalhos X-RateLimit-Limit e X-RateLimit-Remaining. As cotas de API do workspace são configuradas por plano de assinatura no Invosend. Precisa de mais volume em produção? Fale conosco pela conta do seu workspace. Chaves revogadas não contam para o limite de chaves.

7. Endpoints Adicionais#

A mesma chave de API também pode ler e gerenciar faturas criadas por meio de generate-external:

MétodoCaminhoDescrição
GET/api/invoices/externalLista faturas para este espaço de trabalho. Suporta os parâmetros de consulta ?status= e ?page=/?pageSize=.
GET/api/invoices/external/templatesLista os modelos de fatura que você pode informar em template, se o seu plano permite cada um e qual é o padrão.
GET/api/invoices/external/:idObtém uma fatura pelo seu id (o valor retornado por generate-external).
PUT/api/invoices/external/:id/statusAtualiza o status da fatura. Corpo: { "status": "paid" } (um de unpaid, paid, overdue, cancelled).
PUT/api/invoices/external/:id/archiveArquiva ou desarquiva uma fatura. Corpo: { "is_archived": true }.
POST/api/invoices/external/:id/pdfBusca novamente a URL do PDF, regenerando-a se necessário. Corpo: { "force": true } para forçar a regeneração.
GET/api/invoices/external/recurringLista as séries recorrentes. Aceita ?status= (active, paused, completed) e ?page=/?pageSize=.
GET/api/invoices/external/recurring/:idObtém uma série (o recurring.schedule_id retornado por generate-external) com todas as ocorrências: data, status e o id da fatura gerada por cada uma.
PUT/api/invoices/external/recurring/:id/statusPausa ou retoma uma série. Corpo: { "status": "paused" } ou { "status": "active" }. Retomar exige um plano com faturas recorrentes.
PUT/api/invoices/external/recurring/:id/extendAdiciona ocorrências depois da última. Corpo: { "count": 3 } ou { "end_date": "2027-12-31" }.
PUT/api/invoices/external/recurring/:id/frequencyAltera a frequência da série; as próximas ocorrências ainda não geradas são substituídas. Corpo: { "frequency": "monthly", "start_date": "2027-01-01", "count": 6 } (use end_date no lugar de count, se preferir; start_date deve estar no futuro).
POST/api/invoices/external/recurring/:id/skipRemove uma ocorrência futura. Corpo: { "date": "2027-01-01" }. Ocorrências que já geraram uma fatura não podem ser removidas.
Para receber um pagamento online, defina payment_gateway (e opcionalmente payment_account) em generate-external e depois envie ao cliente a página de pagamento pública da fatura: https://app.invosend.com/p/invoice/{id}, usando o id retornado pela API. Ele paga ali pelo gateway conectado e a fatura é marcada como paga automaticamente. O checkout é tratado por essa página; não há um endpoint de checkout público separado para chamar.

8. Webhooks#

Em vez de consultar a API repetidamente, cadastre uma URL HTTPS e o Invosend enviará a ela uma requisição POST com corpo JSON sempre que uma fatura mudar. Adicione endpoints em Configurações > Webhooks (proprietário do workspace, plano com acesso à API, até 5 endpoints). Cada endpoint tem seu próprio segredo de assinatura, exibido apenas uma vez.

Os eventos são enviados tanto para faturas criadas no painel quanto pela API. Os modelos de séries recorrentes nunca são enviados.

EventoEnviado quando
invoice.createdUma fatura é criada. O PDF pode ainda não estar pronto, então pdf_url pode ser null.
invoice.paidO status muda para paid (por você, pela API ou por um pagamento online).
invoice.overdueO status muda para overdue (automaticamente após o vencimento, ou manualmente).
invoice.cancelledO status muda para cancelled.

Todos os eventos têm o mesmo formato. data.object é a fatura, com a mesma estrutura de GET /api/invoices/external/:id; eventos de status também incluem data.previous_status:

{
  "id": "evt_9f2c1b7a4e3d5c6b8a1f0e2d",
  "object": "event",
  "type": "invoice.paid",
  "created": "2026-10-01T09:30:12.000Z",
  "data": {
    "object": {
      "id": "cjld2cjxh0000qzrmn831i7rn",
      "invoice_number": "INV-1-202610-0007",
      "customer_name": "Acme Corp",
      "customer_email": "billing@acme.com",
      "currency": "USD",
      "subtotal": 500,
      "discount_total": 0,
      "tax_rate": 0,
      "tax_amount": 0,
      "amount": 500,
      "amount_paid": 500,
      "amount_credited": 0,
      "amount_received": 500,
      "invoice_status": "paid",
      "is_archived": false,
      "is_recurring": false,
      "recurring_interval": "none",
      "issue_date": "2026-10-01T02:15:40.000Z",
      "due_date": "2026-10-15",
      "paid_at": "2026-10-01T09:30:11.000Z",
      "pdf_url": "https://cdn.invosend.com/company/1/pdf/Invoice_INV_1_202610_0007_PAID.pdf",
      "pdf_status": "ready"
    },
    "previous_status": "unpaid"
  }
}

Cada requisição traz estes cabeçalhos. Para verificá-la, calcule um HMAC-SHA256 de {t}.{corpo bruto} com o segredo do endpoint e compare com v1; rejeite a requisição se t tiver mais de 5 minutos:

POST /your/webhook/url
Content-Type: application/json
Invosend-Event: invoice.paid
Invosend-Delivery: evt_9f2c1b7a4e3d5c6b8a1f0e2d
Invosend-Signature: t=1790847012,v1=5b1d...e9a2

// Node.js
import crypto from "crypto";

function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(parts.t + "." + rawBody)
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
Responda com qualquer status 2xx em até 10 segundos. Caso contrário, haverá até 7 novas tentativas (após 1 minuto, 5 minutos, 30 minutos, 2 horas, 6 horas, 12 horas e 24 horas). Um endpoint que continua falhando é desativado e você é notificado. Um evento pode chegar mais de uma vez ou fora de ordem: use o id do evento para ignorar duplicados e trate invoice_status como fonte da verdade. Os registros de entrega ficam por 30 dias e qualquer evento pode ser reenviado em Configurações > Webhooks.

9. Limitações#

Esta API é intencionalmente limitada à geração de faturas e ao gerenciamento leve de faturas. O seguinte ainda não está disponível:

  • Os webhooks cobrem apenas fatura criada, paga, vencida e cancelada. Outras alterações, como edição ou arquivamento, não são enviadas: leia o estado atual com GET /invoices/external/:id.
  • A fatura criada em cada requisição não é enviada por e-mail: esta API apenas gera o PDF, então entregá-lo ao cliente fica por sua conta (ou use o painel). A exceção são as séries recorrentes: cada fatura seguinte gerada pelo agendador é enviada automaticamente para customer_email.
  • Sem edição de uma fatura após a criação — apenas seu status e estado de arquivamento podem ser alterados por meio desta API.
  • O suporte a gateway de pagamento requer que o gateway já esteja conectado no painel; esta API apenas o anexa à fatura, não conecta um gateway por conta própria.
  • Uma série recorrente pode ser pausada, retomada, estendida, reprogramada e ter ocorrências futuras puladas pela API, mas seu conteúdo (itens, cliente, valores) não pode ser editado nem a série excluída pela API; faça isso no painel.

Perguntas Frequentes#

Como obtenho uma chave de API do Invosend?

Crie uma conta em app.invosend.com, atualize o espaço de trabalho para um plano pago, depois abra Settings > API Keys e clique em Generate key. A chave bruta é mostrada apenas uma vez, no momento da criação.

Quanto custa cada chamada da API de geração de faturas?

Cada solicitação bem-sucedida deduz 1 crédito de fatura do saldo do seu espaço de trabalho. Ela usa o mesmo pool de créditos de fatura das faturas criadas pelo painel.

Qual é o limite de taxa desta API?

O limite de taxa do workspace segue a configuração do seu plano pago. A seção Rate Limit acima lista o limite atual de cada plano.