API per sviluppatori

Pro e prova gratuita

Le API REST di ScontrinoZero permettono di integrare l'emissione di scontrini elettronici direttamente nel tuo gestionale, POS o e-commerce. Ogni chiamata usa le credenziali Fisconline del tuo esercente e trasmette il documento all'Agenzia delle Entrate in tempo reale.

Prerequisiti

  • Account ScontrinoZero con piano Pro attivo, oppure in prova gratuita (la prova include l'accesso API con una chiave; su Pro le chiavi attive sono al massimo 3). Alla scadenza della prova le chiavi smettono di autenticare e tornano attive passando a Pro, senza rigenerarle.
  • Credenziali Fisconline configurate nella sezione Configurazione attività.
  • Una chiave API di tipo business generata dalla dashboard: vai su Impostazioni → Altre impostazioni → API key, clicca + Nuova API key, assegnale un nome descrittivo (es. "POS principale"), clicca Genera e copia la chiave — sarà mostrata una sola volta.

Autenticazione

Includi la chiave API in ogni richiesta tramite l'header Authorization:

Authorization: Bearer szk_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Attenzione: la chiave viene mostrata una sola volta al momento della creazione e non è recuperabile in seguito. Se la perdi, revoca la vecchia e genera una nuova dalla dashboard.

Base URL

https://api.scontrinozero.it/v1

Sandbox

Per sviluppare e testare la tua integrazione senza emettere scontrini reali all'Agenzia delle Entrate, usa l'ambiente sandbox:

https://api-sandbox.scontrinozero.it/v1

Il sandbox è identico alla produzione, ma ogni chiamata all'AdE è simulata — nessun documento viene trasmesso. Le risposte hanno la stessa struttura di quelle reali; il campo adeProgressive è fittizio e contiene il prefisso MOCK- (es. DCW2026/MOCK-1).

  • Registra un account separato su sandbox.scontrinozero.it (non collegato alla produzione).
  • Le credenziali Fisconline accettano qualsiasi valore nel sandbox.
  • I dati sandbox possono essere resettati senza preavviso.
  • La prova gratuita basta per generare una chiave e integrare. Per testare anche il flusso di abbonamento — o il limite di 3 chiavi del piano Pro — attiva Pro con una carta di test Stripe: numero 4242 4242 4242 4242, scadenza una qualsiasi data futura, CVC tre cifre qualsiasi. Nessun addebito: il sandbox usa Stripe in modalità test, e la stessa carta viene rifiutata in produzione. L'elenco completo delle carte di test (3D Secure, pagamenti rifiutati) è nella documentazione Stripe.
  • La chiave API sandbox inizia sempre con szk_live_ — è un token di accesso all'ambiente sandbox, non alla produzione.

Endpoint

MetodoPathDescrizione
POST/v1/receiptsEmetti uno scontrino
GET/v1/receiptsLista scontrini in un intervallo di date
GET/v1/receipts/{id}Recupera lo stato di uno scontrino
POST/v1/receipts/{id}/voidAnnulla uno scontrino

POST/v1/receipts

Emette uno scontrino elettronico e lo trasmette all'Agenzia delle Entrate.

Corpo della richiesta

CampoTipoDescrizione
linesarray (1–100)Righe dello scontrino
lines[].descriptionstring (1–200)Descrizione del prodotto/servizio
lines[].quantitynumber (> 0, ≤ 9999)Quantità, max 3 decimali
lines[].grossUnitPricenumber (≥ 0)Prezzo unitario IVA inclusa (€)
lines[].vatCodestring (enum)Codice aliquota IVA (vedi tabella sotto)
paymentMethodstring (enum)PC = contanti, PE = elettronico (carta, bancomat, bonifico). Alternativo a payments: indicane esattamente uno.
paymentsarray | assentePagamento misto (Pro): ripartisce l’incasso fra PC e PE, es. [{"type":"PC","amount":5},{"type":"PE","amount":15}]. La somma degli importi più lo sconto a pagare deve fare il totale delle righe. Col pagamento misto il codice lotteria non è ammesso.
idempotencyKeystring (UUID v4)Chiave di idempotenza (vedi sezione Idempotenza)
lotteryCodestring (8 char [A-Z0-9]) | nullCodice lotteria scontrini (opzionale). Rilevante solo con PE e se il totale scontrino è ≥ €1,00; viene ignorato con PC.

Esempio

curl -X POST https://api.scontrinozero.it/v1/receipts \
  -H "Authorization: Bearer szk_live_XXXX" \
  -H "Content-Type: application/json" \
  -d '{
    "lines": [
      {
        "description": "Pizza Margherita",
        "quantity": 2,
        "grossUnitPrice": 8.00,
        "vatCode": "10"
      },
      {
        "description": "Acqua naturale",
        "quantity": 1,
        "grossUnitPrice": 2.50,
        "vatCode": "10"
      }
    ],
    "paymentMethod": "PE",
    "idempotencyKey": "550e8400-e29b-41d4-a716-446655440000",
    "lotteryCode": "ABCD1234"
  }'

Risposta — 201 Created

{
  "documentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "adeTransactionId": "151085589",
  "adeProgressive": "DCW2026/5111-2188"
}

GET/v1/receipts

Restituisce la lista paginata degli scontrini emessi nell'intervallo di date indicato. Utile per riconciliazione contabile, export periodico o sync verso sistemi gestionali.

Parametri query

ParametroTipoReq.Descrizione
fromYYYY-MM-DDInizio intervallo (incluso, UTC)
toYYYY-MM-DDFine intervallo (incluso, UTC). Max 31 giorni da from.
pageintero ≥ 1NoPagina (default: 1)
limit1–100NoRisultati per pagina (default: 20, max: 100)
kindSALE | VOIDNoFiltra per tipo documento (default: entrambi)
statusPENDING | ACCEPTED | VOID_ACCEPTED | REJECTED | ERRORNoFiltra per stato del documento. Senza questo parametro l'elenco restituisce solo i documenti registrati all'Agenzia delle Entrate (ACCEPTED e VOID_ACCEPTED): usa status=PENDING per ritrovare gli scontrini rimasti in sospeso.

Esempio

curl "https://api.scontrinozero.it/v1/receipts?from=2026-04-01&to=2026-04-30&limit=100" \
  -H "Authorization: Bearer szk_live_XXXX"

Se sono stati emessi più di 100 scontrini nel periodo, usa &page=2, &page=3, ecc. Il campo pagination.hasNextPage indica se esistono ulteriori pagine.

Risposta — 200 OK

{
  "data": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440000",
      "kind": "SALE",
      "status": "ACCEPTED",
      "adeTransactionId": "151085589",
      "adeProgressive": "DCW2026/5111-2188",
      "lotteryCode": null,
      "paymentMethod": "PE",
      "payments": null,
      "total": "18.50",
      "createdAt": "2026-04-05T10:00:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 100,
    "total": 1,
    "hasNextPage": false
  }
}

La risposta non include le righe di dettaglio. Per il contenuto completo di uno scontrino usa GET /v1/receipts/{id} (campo lines incluso).

GET/v1/receipts/{id}

Restituisce i dettagli e lo stato di uno scontrino emesso. Utile per verificare l'esito di un'emissione o per implementare l'idempotency check sul tuo client.

Esempio

curl https://api.scontrinozero.it/v1/receipts/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  -H "Authorization: Bearer szk_live_XXXX"

Risposta — 200 OK

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "kind": "SALE",
  "status": "ACCEPTED",
  "idempotencyKey": "550e8400-e29b-41d4-a716-446655440000",
  "adeTransactionId": "151085589",
  "adeProgressive": "DCW2026/5111-2188",
  "createdAt": "2026-03-26T10:00:00.000Z",
  "paymentMethod": "PE",
  "payments": null,
  "lotteryCode": "ABCD1234",
  "voidedDocumentId": null,
  "total": "18.50",
  "lines": [
    {
      "description": "Pizza Margherita",
      "quantity": "2.000",
      "grossUnitPrice": "8.00",
      "vatCode": "10"
    },
    {
      "description": "Acqua naturale",
      "quantity": "1.000",
      "grossUnitPrice": "2.50",
      "vatCode": "10"
    }
  ]
}
CampoDescrizione
kindSALE (vendita) o VOID (annullo).
statusACCEPTED, VOID_ACCEPTED, REJECTED, ERROR o PENDING.
paymentMethodPC (contanti) o PE (elettronico), così come inviato in emissione. null sui documenti che non lo portano.
paymentsRipartizione dell'incassato fra più metodi. Oggi sempre null: l'emissione con pagamento ripartito non è ancora disponibile, e il campo esiste perché un client scritto adesso continui a funzionare quando lo sarà.
lotteryCodeCodice lotteria scontrini, null se non fornito o se il metodo di pagamento è PC.
voidedDocumentIdPresente solo per documenti VOID: UUID del SALE che è stato annullato.
totalTotale calcolato dalle righe, con 2 decimali (es. "18.50").
lines[].quantityStringa con 3 decimali fissi (es. "2.000").
lines[].grossUnitPriceStringa con 2 decimali fissi (es. "8.00"), in euro.

POST/v1/receipts/{id}/void

Annulla uno scontrino precedentemente emesso. L'annullamento è irreversibile e viene trasmesso all'Agenzia delle Entrate.

Corpo della richiesta

CampoTipoDescrizione
idempotencyKeystring (UUID v4)Chiave di idempotenza per l'annullamento

Esempio

curl -X POST https://api.scontrinozero.it/v1/receipts/a1b2c3d4-e5f6-7890-abcd-ef1234567890/void \
  -H "Authorization: Bearer szk_live_XXXX" \
  -H "Content-Type: application/json" \
  -d '{"idempotencyKey": "b2c3d4e5-f6a7-8901-bcde-f01234567890"}'

Risposta — 200 OK

{
  "voidDocumentId": "c3d4e5f6-a7b8-9012-cdef-012345678901",
  "adeTransactionId": "151085590",
  "adeProgressive": "DCW2026/5111-2189"
}

Codici IVA

Il campo vatCode accetta i seguenti valori:

ValoreAliquotaRegime
44%Ridotta (es. beni di prima necessità)
55%Ridotta (es. alcuni prodotti farmaceutici)
1010%Ridotta (es. alimenti, ristorazione, turismo)
2222%Ordinaria
N10%Art. 15 DPR 633/72 — Escluso da IVA
N20%Non soggetto a IVA
N30%Non imponibile
N40%Esente
N50%Regime del margine
N60%Altro non IVA

Idempotenza

Ogni richiesta di emissione e annullamento richiede un campo idempotencyKey: un UUID v4 univoco che identifichi quella specifica operazione.

Se invii la stessa richiesta due volte con lo stesso idempotencyKey (es. in seguito a un timeout di rete), il sistema restituisce ilrisultato dell'operazione originale senza emettere un secondo scontrino. Genera una nuova chiave per ogni scontrino distinto.

// Esempio generazione in JavaScript
const idempotencyKey = crypto.randomUUID();

Rate limiting

I limiti sono per chiave API, con finestra scorrevole di 1 ora:

EndpointLimite
POST /v1/receipts120 richieste / ora
GET /v1/receipts60 richieste / ora
POST /v1/receipts/{id}/void20 richieste / ora

Al superamento del limite ricevi una risposta 429 con header Retry-After che indica i secondi da attendere prima di riprovare.

Codici di errore

Tutti gli errori restituiscono lo stesso oggetto JSON, su qualsiasi endpoint e qualsiasi status:

{
  "code": "PENDING_IN_PROGRESS",
  "message": "Una richiesta con la stessa idempotencyKey è ancora in corso.",
  "requestId": "9f1c2f5e-7b3a-4c1d-9e8f-2a6b0d4c7e11"
}
  • code — stringa stabile: è il campo su cui costruire la logica del tuo client.
  • message — testo pensato per una persona. Può cambiare senza preavviso: non farne parsing.
  • requestId — identificativo della richiesta, presente anche nell'header X-Request-Id di tutte le risposte (successi inclusi). Citalo quando ci scrivi: ci permette di ritrovare la richiesta nei log.
  • documentId — presente solo quando l'errore riguarda uno scontrino il cui esito è ancora aperto (ADE_UNAVAILABLE, DB_TIMEOUT, PENDING_IN_PROGRESS): è l'id da interrogare con GET /v1/receipts/{id} per sapere come è andata a finire. Sugli errori definitivi il campo non c'è.

Quando una risposta include l'header Retry-After, l'errore è temporaneo: attendi i secondi indicati e ripeti la richiesta identica, con la stessa idempotencyKey. Non generare mai una chiave nuova per un tentativo ripetuto: rischieresti un secondo scontrino, che non è più annullabile automaticamente.

StatusCodeCausa
400INVALID_BODY · VALIDATION_ERROR · INVALID_QUERY_PARAM · INVALID_IDRichiesta non valida: corpo assente o non JSON, campo fuori schema (mancante, tipo errato, UUID non valido), oppure un parametro di query malformato — from/to mancanti o non in formato YYYY-MM-DD, intervallo oltre 31 giorni, page o limit non interi o minori di 1, kind diverso da SALE/VOID. I valori malformati vengono rifiutati, non corretti in silenzio (un limit oltre 100 fa eccezione: viene ridotto a 100).
401UNAUTHORIZEDChiave API assente, non valida, revocata o scaduta.
402PLAN_UPGRADE_REQUIREDIl piano attivo non include l'accesso alle API. Passa al Piano Pro.
403BUSINESS_KEY_REQUIREDServe una business key szk_live_: hai usato una chiave di tipo diverso.
404NOT_FOUNDScontrino non trovato: l'ID non esiste o appartiene a un altro esercente. Vale per GET /v1/receipts/{id} e per l'annullamento.
409PENDING_IN_PROGRESS · VOID_PENDING_IN_PROGRESSUna richiesta con la stessa idempotencyKey è ancora in corso. È temporaneo: attendi i secondi indicati in Retry-After e ripeti la richiesta identica.
409ALREADY_REJECTED · ALREADY_VOIDED · VOID_ALREADY_TARGETED · IDEMPOTENCY_PAYLOAD_MISMATCHConflitto definitivo sulla chiave di idempotenza: il documento è già stato rifiutato o annullato, c'è un annullo concorrente sullo stesso scontrino, oppure la chiave è stata riusata con un contenuto diverso. Ripetere non aiuta: serve una chiave nuova per una nuova operazione.
409ADE_REAUTH_REQUIRED · ADE_PASSWORD_EXPIREDServe un intervento dell'esercente nell'app web ScontrinoZero: la sessione con l'Agenzia delle Entrate (CIE) è scaduta e va rinnovata, oppure la password Fisconline è scaduta e va aggiornata. Il retry automatico è inutile finché non lo fa.
413PAYLOAD_TOO_LARGECorpo della richiesta oltre il limite: 32 KB in emissione, 8 KB in annullamento.
422ADE_REJECTEDL'Agenzia delle Entrate ha rifiutato il documento nel merito, o mancano dati fiscali. Lo scontrino non è stato registrato e ripetere la stessa richiesta fallirebbe di nuovo: va corretto il contenuto.
429RATE_LIMIT_EXCEEDEDRate limit superato. Riprova dopo i secondi indicati in Retry-After.
500VOID_SYNC_FAILED · INTERNAL_ERRORErrore interno. VOID_SYNC_FAILED è il caso specifico in cui l'annullo è stato registrato sull'AdE ma la nostra sincronizzazione è fallita: scrivici citando il requestId.
503DB_TIMEOUTServizio temporaneamente sovraccarico. È transitorio: riprova dopo i secondi indicati in Retry-After.
503ADE_UNAVAILABLEL'Agenzia delle Entrate non ha risposto (rete, errore 5xx, timeout). L'esito della trasmissione è ignoto: lo scontrino potrebbe essere già registrato. Riprova dopo i secondi indicati in Retry-After con la stessa idempotencyKey — una chiave nuova rischierebbe un secondo scontrino.

Scontrini rimasti in sospeso

Uno scontrino resta in sospeso quando l'Agenzia delle Entrate non risponde alla trasmissione: ricevi un 503 ADE_UNAVAILABLE e l'esito è ignoto, perché il documento potrebbe essere già registrato. La mossa è una sola: ripeti la richiesta con la stessa idempotencyKey. Prima di ritrasmettere cerchiamo il documento sull'Agenzia delle Entrate e, se c'è già, lo colleghiamo a quella vendita invece di emetterne un secondo.

Se il tuo processo smette di ritentare, lo scontrino resta in sospeso e non compare nell'elenco, che di default mostra solo i documenti registrati. Due modi per ritrovarlo: il campo documentId dell'errore, da interrogare con GET /v1/receipts/{id}, e la lista filtrata per stato, che restituisce tutte le righe in sospeso del periodo.

curl "https://api.scontrinozero.it/v1/receipts?from=2026-04-01&to=2026-04-30&status=PENDING" \
  -H "Authorization: Bearer szk_live_XXXX"

Quando all'Agenzia delle Entrate risultano più documenti compatibili — stesso importo, stesso giorno — nessun automatismo sa quale sia il tuo, e lo scontrino resta in sospeso: sceglie l'esercente dall'app web ScontrinoZero, dove il banner in dashboard mostra i candidati e chiede quale riconosce.

Domande frequenti

Posso usare le API durante la prova gratuita?

Sì: la prova gratuita di 30 giorni include l'accesso alla Developer API con una chiave attiva, senza inserire una carta di credito. Il piano Pro ne consente fino a 3. Su Starter le API non sono disponibili.

Cosa succede alle chiavi API quando scade la prova gratuita?

Smettono di autenticare: ogni richiesta riceve un errore 402 PLAN_UPGRADE_REQUIRED. Le chiavi restano nella dashboard e tornano attive appena attivi il piano Pro, quindi non devi rigenerarle né aggiornare l'integrazione.

Cosa succede se l'Agenzia delle Entrate non risponde durante l'emissione?

Ricevi un errore 503 ADE_UNAVAILABLE e lo scontrino resta in sospeso: l'esito della trasmissione è ignoto. Ripeti la richiesta con la stessa idempotencyKey — prima di ritrasmettere verifichiamo sull'Agenzia delle Entrate se il documento è già registrato, così non ne emetti due. L'errore porta il campo documentId per seguire lo scontrino con GET /v1/receipts/{id}, e GET /v1/receipts?status=PENDING elenca tutti quelli rimasti in sospeso.

Dove trovo la sezione API key nella dashboard?

In Impostazioni → Altre impostazioni → API key: la sezione è chiusa di default, aprila con il pulsante “Altre impostazioni”. La card è visibile su tutti i piani; se il tuo piano non include le API mostra l'upgrade invece dell'elenco delle chiavi.

Articoli correlati

Pronto a iniziare?

30 giorni di prova gratuita, senza carta di credito.

Crea l'account

Quando citiamo una norma indichiamo estremo e data, così puoi verificarla alla fonte. Informazione divulgativa: non sostituisce la consulenza del commercialista, e per situazioni specifiche vanno sempre verificati la normativa aggiornata e il tuo codice ATECO. Hai trovato un'imprecisione? Segnalacela a [email protected].