API di Generazione Fatture

Genera fatture PDF professionali in modo programmatico dal tuo server, adatto per sistemi interni, marketplace o il tuo prodotto SaaS.

1. Autenticazione#

Crea una chiave API su app.invosend.com/settings/api-keys. Sono richiesti un piano a pagamento per lo spazio di lavoro e il ruolo di proprietario.

Invia la chiave come token Bearer nell'header Authorization di ogni richiesta:

Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx
Le chiavi API mancanti, malformate, non valide o revocate vengono rifiutate con 403. Le chiavi vengono rifiutate anche se lo spazio di lavoro è in un piano gratuito, sospeso o scaduto.

2. Endpoint#

POST/api/invoices/generate-external

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

Descrizione dell'API leggibile dalle macchine: OpenAPI 3.1 e Postman collection. Importi l'una o l'altra in Postman, Insomnia o in un generatore di SDK.

3. Corpo della Richiesta#

CampoTipoObbligatorioDescrizione
customer_namestringSìNome del cliente o destinatario della fattura.
customer_emailstringNoIndirizzo e-mail valido. La fattura creata da questa chiamata non viene inviata per e-mail (questa API non invia e-mail). Obbligatorio per le fatture ricorrenti: ogni fattura generata successivamente viene inviata a questo indirizzo.
customer_tax_idstringNoCodice fiscale o partita IVA del cliente (NPWP in Indonesia, fino a 40 caratteri). Stampato sotto l'indirizzo del cliente nella fattura.
itemsarraySìAlmeno 1 elemento valido con descrizione, quantity > 0, e price >= 0.
items[].descriptionstringNoNome del prodotto o servizio. Se vuoto, viene usato Item.
items[].quantitynumberSìNumero di unità, con fino a 2 decimali (ad esempio 1.5 ore), da 0.01 a 999.999.
items[].pricenumberSìPrezzo per unità.
items[].discountnumberNoImporto dello sconto per articolo. Predefinito 0.
currencystringNoCodice valuta come IDR o USD. Predefinito IDR.
tax_ratenumberNoPercentuale d'imposta calcolata dal subtotale dopo lo sconto. Predefinito 0.
due_datestringNoFormato YYYY-MM-DD. Predefinito 14 giorni dopo la generazione.
notesstringNoNote aggiuntive mostrate sulla fattura.
items[].unitstringNoEtichetta unità mostrata accanto alla quantità, come pcs o hour.
items[].tax_ratenumberNoOverride della percentuale d'imposta per articolo (0-100). Ometti per usare il tax_rate a livello di fattura per quell'articolo.
discount_totalnumberNoSconto a livello di fattura. Viene sottratto prima dell'imposta, quindi l'imposta è calcolata sull'importo scontato (ripartito tra le righe in proporzione al loro valore). Predefinito 0.
templatestringNoID del modello di fattura da usare. Elenca quelli disponibili con GET /api/invoices/external/templates. Se omesso, si usa il modello predefinito scelto nelle Impostazioni, poi quello di Invosend.
document_languagestringNoLingua delle parole nel documento della fattura (PDF ed e-mail): en (predefinita), id, es, fr, de, nl, it, pt, zh, ja, hi, ar (indonesiano, spagnolo, francese, tedesco, olandese, italiano, portoghese brasiliano, cinese semplificato, giapponese, hindi, arabo). Qualsiasi altro valore viene rifiutato con un errore. Il layout integrato semplice, usato solo quando non esiste alcun modello, è sempre in inglese.
custom_payment_notesstringNoIstruzioni di pagamento aggiuntive mostrate sul PDF.
footer_textstringNoTesto breve mostrato in fondo al PDF.
is_recurringbooleanNoCrea una serie ricorrente. Questa fattura è la prima; le successive vengono generate e inviate automaticamente a customer_email secondo il calendario, ciascuna usando 1 credito fattura. Richiede un piano con la funzione fatture ricorrenti, oltre a recurring_interval e customer_email.
recurring_intervalstringNoCon quale frequenza si ripete la serie: uno tra weekly, fortnightly, monthly, quarterly, semi-annually, yearly. Obbligatorio quando is_recurring è true.
recurring_countintegerNoNumero totale di fatture della serie, compresa questa prima: un intero da 2 a 121. Predefinito 4. Usa questo campo o recurring_end_date, non entrambi.
recurring_end_datestringNoData dopo la quale non vengono generate altre fatture, YYYY-MM-DD, nel futuro. Usa questo campo o recurring_count, non entrambi.
payment_gatewaystringNoUno tra midtrans, xendit, stripe, paypal, razorpay, mollie. Il gateway deve essere già connesso nello spazio di lavoro.
payment_accountstringNoID di un account di pagamento esistente (dati bancari) da collegare alla fattura.

Esempio completo di richiesta:

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": 500, "tax_rate": 11 }
    ],
    "discount_total": 50,
    "currency": "EUR",
    "notes": "Thank you for your business."
  }'

Esempio di fattura ricorrente (la prima subito, poi una al mese, 6 in totale):

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": 2500 }
    ],
    "currency": "EUR",
    "recurring_interval": "monthly",
    "recurring_count": 6
  }'
Per riprovare in sicurezza dopo un timeout o un errore di rete, aggiunga un'intestazione Idempotency-Key (1-255 caratteri, ad esempio un UUID generato per ogni fattura). Se la prima richiesta è riuscita, il nuovo tentativo restituisce la stessa risposta con l'intestazione Idempotent-Replayed: true, senza creare un'altra fattura né usare un altro credito (credits_remaining è il valore della prima chiamata). Le chiavi vengono conservate 24 ore per spazio di lavoro. Vengono salvate solo le risposte riuscite, quindi una richiesta fallita può essere ritentata con la stessa chiave.

4. Risposta#

200 OK significa che la fattura è stata creata e il PDF è stato generato:

{
  "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 lo spazio di lavoro ha una quota illimitata. id identifica questa fattura per gli endpoint aggiuntivi qui sotto. Le fatture create tramite questa API appaiono anche nell'elenco fatture dello spazio di lavoro e usano la stessa sequenza di numerazione delle fatture create manualmente. I numeri di fattura hanno la forma INV-{id workspace}-{AAAAMM}-{sequenza}. Per una fattura ricorrente la risposta include anche un oggetto recurring: schedule_id, interval, occurrences, next_issue_date, end_date. recurring.schedule_id è l'id da usare con gli endpoint ricorrenti qui sotto.

5. Codici di Errore#

StatoCausa
400Campi obbligatori mancanti o non validi: customer_name, items vuoto, nessuna voce valida, un payment_gateway non riconosciuto, un payment_gateway non collegato per questo workspace oppure, per una fattura ricorrente, recurring_interval o customer_email mancante, o recurring_count / recurring_end_date non validi. Questo stato viene restituito anche se non è stato possibile generare il PDF: ripeti la richiesta (non viene scalato alcun credito).
402Il saldo invoice_credits dello spazio di lavoro è esaurito. Ricarica i crediti per continuare.
403L'header Authorization è mancante o malformato, la chiave API non è valida o è stata revocata, oppure il piano dello spazio di lavoro non include l'accesso API.
403 (ricorrente)is_recurring è stato impostato ma il piano dello spazio di lavoro non include le fatture ricorrenti.
409Una richiesta con la stessa Idempotency-Key è ancora in elaborazione. Riprovi tra un attimo.
422La Idempotency-Key è già stata usata con un corpo della richiesta diverso. Usi una nuova chiave per una nuova fattura.
429Limite di frequenza superato. Vedi la sezione Limite di Frequenza.

6. Limite di Frequenza#

AmbitoLimite
Per workspace (tutte le richieste API insieme)Professional 10/min · Specialist 20/min · Business 30/min · Enterprise 60/min
Per indirizzo IP (tutte le richieste API insieme)30 richieste/minuto
Chiavi API attive per workspaceProfessional 3 · Specialist 5 · Business 10 · Enterprise 20
La generazione di fatture e gli endpoint di lettura/gestione condividono lo stesso limite. Le risposte riuscite includono gli header X-RateLimit-Limit e X-RateLimit-Remaining. Le quote API del workspace sono configurate per piano di abbonamento in Invosend. Serve un volume di produzione maggiore? Contattaci dal tuo account workspace. Le chiavi revocate non contano per il limite di chiavi.

7. Endpoint Aggiuntivi#

La stessa chiave API può anche leggere e gestire le fatture create tramite generate-external:

MetodoPercorsoDescrizione
GET/api/invoices/externalElenca le fatture per questo spazio di lavoro. Supporta i parametri di query ?status= e ?page=/?pageSize=.
GET/api/invoices/external/templatesElenca i modelli di fattura che puoi indicare in template, se il tuo piano li consente e qual è quello predefinito.
GET/api/invoices/external/:idOttiene una fattura tramite il suo id (il valore restituito da generate-external).
PUT/api/invoices/external/:id/statusAggiorna lo stato della fattura. Corpo: { "status": "paid" } (uno tra unpaid, paid, overdue, cancelled).
PUT/api/invoices/external/:id/archiveArchivia o disarchivia una fattura. Corpo: { "is_archived": true }.
POST/api/invoices/external/:id/pdfRecupera nuovamente l'URL del PDF, rigenerandolo se necessario. Corpo: { "force": true } per forzare la rigenerazione.
GET/api/invoices/external/recurringElenca le serie ricorrenti. Supporta ?status= (active, paused, completed) e ?page=/?pageSize=.
GET/api/invoices/external/recurring/:idRecupera una serie (il recurring.schedule_id restituito da generate-external) con tutte le sue occorrenze: data, stato e id della fattura prodotta da ciascuna.
PUT/api/invoices/external/recurring/:id/statusMette in pausa o riprende una serie. Corpo: { "status": "paused" } oppure { "status": "active" }. Per riprendere serve un piano con fatture ricorrenti.
PUT/api/invoices/external/recurring/:id/extendAggiunge occorrenze dopo l'ultima. Corpo: { "count": 3 } oppure { "end_date": "2027-12-31" }.
PUT/api/invoices/external/recurring/:id/frequencyCambia la frequenza della serie; le occorrenze future non ancora generate vengono sostituite. Corpo: { "frequency": "monthly", "start_date": "2027-01-01", "count": 6 } (può usare end_date al posto di count; start_date deve essere futura).
POST/api/invoices/external/recurring/:id/skipRimuove un'occorrenza futura. Corpo: { "date": "2027-01-01" }. Le occorrenze che hanno già prodotto una fattura non possono essere rimosse.
Per incassare un pagamento online, imposta payment_gateway (e facoltativamente payment_account) in generate-external, poi invia al cliente la pagina di pagamento pubblica della fattura: https://app.invosend.com/p/invoice/{id}, usando l'id restituito dall'API. Lì paga tramite il gateway collegato e la fattura viene segnata come pagata automaticamente. Il checkout è gestito da quella pagina; non esiste un endpoint di checkout pubblico separato da chiamare.

8. Webhook#

Invece di interrogare l'API di continuo, registri un URL HTTPS: Invosend vi invia una richiesta POST con corpo JSON ogni volta che una fattura cambia. Aggiunga gli endpoint in Impostazioni > Webhooks (proprietario dello spazio di lavoro, piano con accesso all'API, fino a 5 endpoint). Ogni endpoint ha un proprio segreto di firma, mostrato una sola volta.

Gli eventi vengono inviati sia per le fatture create nella dashboard sia per quelle create tramite questa API. I modelli delle serie ricorrenti non vengono mai inviati.

EventoInviato quando
invoice.createdViene creata una fattura. Il PDF potrebbe non essere ancora pronto, quindi pdf_url può essere null.
invoice.paidLo stato diventa paid (da lei, tramite l'API o con un pagamento online).
invoice.overdueLo stato diventa overdue (automaticamente dopo la scadenza, oppure manualmente).
invoice.cancelledLo stato diventa cancelled.

Ogni evento ha la stessa struttura. data.object è la fattura, con la stessa forma di GET /api/invoices/external/:id; gli eventi di stato includono anche 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"
  }
}

Ogni richiesta include queste intestazioni. Per verificarla, calcoli un HMAC-SHA256 di {t}.{corpo grezzo} con il segreto dell'endpoint e lo confronti con v1; la rifiuti se t è più vecchio di 5 minuti:

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));
}
Risponda con un qualsiasi codice 2xx entro 10 secondi. In caso contrario l'invio viene ritentato fino a 7 volte (dopo 1 minuto, 5 minuti, 30 minuti, 2 ore, 6 ore, 12 ore e 24 ore). Un endpoint che continua a fallire viene disattivato e lei riceve una notifica. Un evento può arrivare più volte o fuori ordine: usi l'id dell'evento per ignorare i duplicati e consideri invoice_status come fonte di verità. I registri di consegna sono conservati 30 giorni e qualsiasi evento può essere reinviato da Impostazioni > Webhooks.

9. Limitazioni#

Questa API è intenzionalmente limitata alla generazione di fatture e alla gestione leggera delle fatture. Quanto segue non è ancora disponibile:

  • I webhook coprono solo fattura creata, pagata, scaduta e annullata. Le altre modifiche, come la modifica o l'archiviazione, non vengono inviate: legga lo stato attuale con GET /invoices/external/:id.
  • La fattura creata da ogni richiesta non viene inviata per e-mail: questa API genera solo il PDF, quindi consegnarlo al cliente spetta a te (o usa la dashboard). L'eccezione sono le serie ricorrenti: ogni fattura successiva generata dallo scheduler viene inviata automaticamente a customer_email.
  • Nessuna modifica di una fattura dopo la creazione — solo il suo stato e lo stato di archiviazione possono essere modificati tramite questa API.
  • Il supporto del gateway di pagamento richiede che il gateway sia già connesso nella dashboard; questa API lo collega solo alla fattura, non connette un gateway da sola.
  • Una serie ricorrente può essere messa in pausa, ripresa, estesa, riprogrammata e le sue occorrenze future possono essere saltate tramite API, ma il suo contenuto (voci, cliente, importi) non può essere modificato né la serie eliminata dall'API; lo faccia nella dashboard.

Domande frequenti#

Come ottengo una chiave API Invosend?

Crea un account su app.invosend.com, aggiorna lo spazio di lavoro a un piano a pagamento, quindi apri Settings > API Keys e fai clic su Generate key. La chiave grezza viene mostrata solo una volta al momento della creazione.

Quanto costa ogni chiamata all'API di generazione fatture?

Ogni richiesta riuscita detrae 1 credito fattura dal saldo del tuo spazio di lavoro. Utilizza lo stesso pool di crediti fattura delle fatture create tramite la dashboard.

Qual è il limite di frequenza per questa API?

Il limite di frequenza del workspace segue la configurazione del tuo piano a pagamento. La sezione Rate Limit qui sopra riporta il limite attuale di ogni piano.