Questa guida rapida vi accompagna nella creazione del vostro primo registro fiscale con fiskaly SIGN IT, dall’autenticazione fino a un documento commerciale conforme trasmesso all’AdE (Agenzia delle Entrate).
Prerequisiti
Sezione intitolata “Prerequisiti”- Un account fiskaly (registratevi su hub.fiskaly.com)
- Una chiave API e un segreto per un’organizzazione GROUP nell’ambiente TEST
- Credenziali Fisconline per il contribuente (in LIVE; non necessarie per TEST)
Il vostro segreto API viene mostrato una sola volta. Conservatelo immediatamente in un luogo sicuro.
Passaggi
Sezione intitolata “Passaggi”Autenticarsi
curl -X POST https://test.api.fiskaly.com/tokens \ -H "Content-Type: application/json" \ -H "X-Api-Version: 2026-06-01" \ -d '{ "content": { "type": "API_KEY", "key": "YOUR_API_KEY", "secret": "YOUR_API_SECRET" } }'const BASE = "https://test.api.fiskaly.com"; const API_VERSION = "2026-06-01"; const authResp = await fetch(`${BASE}/tokens`, { method: "POST", headers: { "Content-Type": "application/json", "X-Api-Version": API_VERSION, }, body: JSON.stringify({ content: { type: "API_KEY", key: "YOUR_API_KEY", secret: "YOUR_API_SECRET" }, }), }); const { access_token } = await authResp.json(); const headers = { "Authorization": `Bearer ${access_token}`, "Content-Type": "application/json", "X-Api-Version": API_VERSION, };import requests, uuid BASE = "https://test.api.fiskaly.com" API_VERSION = "2026-06-01" auth = requests.post(f"{BASE}/tokens", json={ "content": {"type": "API_KEY", "key": "YOUR_API_KEY", "secret": "YOUR_API_SECRET"} }, headers={"X-Api-Version": API_VERSION}) access_token = auth.json()["access_token"] hdrs = {"Authorization": f"Bearer {access_token}", "X-Api-Version": API_VERSION}// POST https://test.api.fiskaly.com/tokens // Headers: Content-Type: application/json, X-Api-Version: 2026-06-01 // Body: {"content":{"type":"API_KEY","key":"...","secret":"..."}}using var client = new HttpClient(); client.DefaultRequestHeaders.Add("X-Api-Version", "2026-06-01"); var authResp = await client.PostAsJsonAsync( "https://test.api.fiskaly.com/tokens", new { content = new { type = "API_KEY", key = "YOUR_API_KEY", secret = "YOUR_API_SECRET" } });📘NoteSIGN IT e SIGN FR condividono la stessa piattaforma API. Tutte le richieste richiedono l’intestazione
X-Api-Version. Le operazioni di scrittura necessitano anche di un’intestazioneX-Idempotency-Keycon un valore UUIDv3 o UUIDv4.Creare un'organizzazione UNIT
curl -X POST https://test.api.fiskaly.com/organizations \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -H "X-Api-Version: 2026-06-01" \ -H "X-Idempotency-Key: $(uuidgen)" \ -d '{ "content": { "type": "UNIT", "name": "My Italian Merchant" } }'const org = await fetch(`${BASE}/organizations`, { method: "POST", headers: { ...headers, "X-Idempotency-Key": crypto.randomUUID() }, body: JSON.stringify({ content: { type: "UNIT", name: "My Italian Merchant" }, }), }).then(r => r.json()); const orgId = org.id;org = requests.post(f"{BASE}/organizations", headers={ **hdrs, "X-Idempotency-Key": str(uuid.uuid4()) }, json={"content": {"type": "UNIT", "name": "My Italian Merchant"}}).json() org_id = org["id"]// POST /organizations // Headers: X-Idempotency-Key: <uuid> // Body: {"content":{"type":"UNIT","name":"My Italian Merchant"}}client.DefaultRequestHeaders.Add("X-Idempotency-Key", Guid.NewGuid().ToString()); var org = await client.PostAsJsonAsync($"{BASE}/organizations", new { content = new { type = "UNIT", name = "My Italian Merchant" } });Creare una chiave API soggetto e autenticarsi
Create una chiave API per la UNIT, poi autenticatevi con essa:
# Creare chiave API soggetto (con ambito sulla UNIT) curl -X POST https://test.api.fiskaly.com/subjects \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -H "X-Api-Version: 2026-06-01" \ -H "X-Idempotency-Key: $(uuidgen)" \ -H "X-Scope-Identifier: ${ORG_ID}" \ -d '{"content": {"type": "API_KEY"}}' # Autenticarsi con la nuova chiave API curl -X POST https://test.api.fiskaly.com/tokens \ -H "Content-Type: application/json" \ -H "X-Api-Version: 2026-06-01" \ -d '{"content": {"type": "API_KEY", "key": "NEW_KEY", "secret": "NEW_SECRET"}}'// Create Subject API Key scoped to the UNIT const subject = await fetch(`${BASE}/subjects`, { method: "POST", headers: { ...headers, "X-Idempotency-Key": crypto.randomUUID(), "X-Scope-Identifier": orgId, }, body: JSON.stringify({ content: { type: "API_KEY" } }), }).then(r => r.json()); // Re-authenticate with the new key const newAuth = await fetch(`${BASE}/tokens`, { method: "POST", headers: { "Content-Type": "application/json", "X-Api-Version": API_VERSION, }, body: JSON.stringify({ content: { type: "API_KEY", key: subject.key, secret: subject.secret }, }), }).then(r => r.json()); headers.Authorization = `Bearer ${newAuth.access_token}`;# Create Subject API Key subject = requests.post(f"{BASE}/subjects", headers={ **hdrs, "X-Idempotency-Key": str(uuid.uuid4()), "X-Scope-Identifier": org_id, }, json={"content": {"type": "API_KEY"}}).json() # Re-authenticate new_auth = requests.post(f"{BASE}/tokens", headers={"X-Api-Version": API_VERSION}, json={"content": {"type": "API_KEY", "key": subject["key"], "secret": subject["secret"]}}).json() hdrs["Authorization"] = f"Bearer {new_auth['access_token']}"// POST /subjects with X-Scope-Identifier: <orgId> // Body: {"content":{"type":"API_KEY"}} // Then POST /tokens with the new key and secret// Create Subject API Key, then re-authenticate with the new credentials // POST /subjects → returns key + secret // POST /tokens → returns new access_tokenCreare contribuente, sede e sistema
# Creare contribuente curl -X POST https://test.api.fiskaly.com/taxpayers \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -H "X-Api-Version: 2026-06-01" \ -H "X-Idempotency-Key: $(uuidgen)" \ -d '{ "content": { "type": "COMPANY", "name": { "legal": "La Pizzeria di Mario S.r.l.", "trade": "La Pizzeria di Mario" }, "address": { "line": { "type": "STREET_NUMBER", "street": "Via Roma", "number": "123" }, "code": "00100", "city": "Rome", "country": "IT" }, "fiscalization": { "type": "IT", "tax_id_number": "12345678901", "vat_id_number": "12345678901", "credentials": { "type": "FISCONLINE", "pin": "1234567890", "password": "MySecurePassword123", "tax_id_number": "RSSMRA85M01H501Z" } } } }' # Attivare il contribuente curl -X PATCH "https://test.api.fiskaly.com/taxpayers/${TAXPAYER_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -H "X-Api-Version: 2026-06-01" \ -H "X-Idempotency-Key: $(uuidgen)" \ -d '{"content": {"state": "COMMISSIONED"}}'// Create Taxpayer const taxpayer = await fetch(`${BASE}/taxpayers`, { method: "POST", headers: { ...headers, "X-Idempotency-Key": crypto.randomUUID() }, body: JSON.stringify({ content: { type: "COMPANY", name: { legal: "My Company S.r.l." }, address: { street: "Via Roma 1", zip: "00100", city: "Roma", country_code: "IT" }, fiscalization: { type: "IT", tax_id_number: "RSSMRA85M01H501Z", vat_id_number: "IT12345678901", }, }, }), }).then(r => r.json()); // Commission Taxpayer await fetch(`${BASE}/taxpayers/${taxpayer.id}`, { method: "PATCH", headers: { ...headers, "X-Idempotency-Key": crypto.randomUUID() }, body: JSON.stringify({ content: { state: "COMMISSIONED" } }), }); // Create + Commission Location and System follow the same pattern# Create Taxpayer taxpayer = requests.post(f"{BASE}/taxpayers", headers={ **hdrs, "X-Idempotency-Key": str(uuid.uuid4()) }, json={"content": { "type": "COMPANY", "name": {"legal": "My Company S.r.l."}, "address": {"street": "Via Roma 1", "zip": "00100", "city": "Roma", "country_code": "IT"}, "fiscalization": {"type": "IT", "tax_id_number": "RSSMRA85M01H501Z", "vat_id_number": "IT12345678901"}, }}).json() # Commission Taxpayer requests.patch(f"{BASE}/taxpayers/{taxpayer['id']}", headers={ **hdrs, "X-Idempotency-Key": str(uuid.uuid4()) }, json={"content": {"state": "COMMISSIONED"}})// POST /taxpayers → create, then PATCH /taxpayers/{id} → commission // POST /locations → create, then PATCH /locations/{id} → commission // POST /systems → create, then PATCH /systems/{id} → commission// POST /taxpayers → create COMPANY with IT fiscalization // PATCH /taxpayers/{id} → {"content":{"state":"COMMISSIONED"}} // Same pattern for locations and systems💡Create prima il contribuenteDopo, create una o più sedi (
type: "BRANCH") e uno o più System (type: "FISCAL_DEVICE"). Poi aggiornate il loro stato aCOMMISSIONEDper attivarli. Consultate la guida all’integrazione completa per la sequenza completa.📘Nota sulla fatturazionePer la maggior parte dei contratti, i
Systemsono le unità utilizzate per la fatturazione con fiskaly. UnSystemdiventa rilevante ai fini della fatturazione non appena il suo stato passa daACQUIREDaCOMMISSIONEDnell’ambiente LIVE. Le risorse nell’ambiente TEST non vengono fatturate. Per le condizioni di fatturazione esatte, fare riferimento al proprio contratto con fiskaly.Creare il primo registro
I registri richiedono due chiamate: una INTENTION seguita da una TRANSACTION.
# Parte A: Intention curl -X POST https://test.api.fiskaly.com/records \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -H "X-Api-Version: 2026-06-01" \ -H "X-Idempotency-Key: $(uuidgen)" \ -d '{ "content": { "type": "INTENTION", "system": {"id": "YOUR_SYSTEM_ID"}, "operation": {"type": "TRANSACTION"} } }' # Parte B: Transaction curl -X POST https://test.api.fiskaly.com/records \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -H "X-Api-Version: 2026-06-01" \ -H "X-Idempotency-Key: $(uuidgen)" \ -d '{ "content": { "type": "TRANSACTION", "record": { "id": "your_intention_id" }, "operation": { "type": "RECEIPT", "document": { "number": "0001" }, "breakdown": [ { "type": "VAT_RATE", "code": "STANDARD", "percentage": "22.00", "exclusive": "20.00", "inclusive": "24.40", "amount": "4.40" }, { "type": "VAT_RATE", "code": "REDUCED_1", "percentage": "10.00", "exclusive": "0.54545455", "inclusive": "0.60", "amount": "0.05454545" } ], "totals": { "vat": { "amount": "4.45454545", "exclusive": "20.54545455", "inclusive": "25.00" } }, "entries": [ { "type": "SALE", "details": { "concept": "GOOD" }, "data": { "type": "ITEM", "text": "Margherita pizza", "unit": { "quantity": "2.00", "price": { "inclusive": "12.20", "exclusive": "10.00" } }, "value": { "base": "20.00", "discount": "0.00" }, "vat": { "type": "VAT_RATE", "code": "STANDARD", "percentage": "22.00", "exclusive": "20.00", "inclusive": "24.40", "amount": "4.40" } } }, { "type": "SALE", "details": { "concept": "SERVICE" }, "data": { "type": "ITEM", "text": "Service ABC", "unit": { "quantity": "1.00", "price": { "inclusive": "0.60", "exclusive": "0.54545455" } }, "value": { "base": "0.54545455", "discount": "0.00" }, "vat": { "type": "VAT_RATE", "code": "REDUCED_1", "percentage": "10.00", "exclusive": "0.54545455", "inclusive": "0.60", "amount": "0.05454545" } } } ], "payments": [ { "type": "CASH", "details": { "amount": "25.00" } } ] } } }'// Part A: Intention const intention = await fetch(`${BASE}/records`, { method: "POST", headers: { ...headers, "X-Idempotency-Key": crypto.randomUUID() }, body: JSON.stringify({ content: { type: "INTENTION", system: { id: systemId }, operation: { type: "TRANSACTION" }, }, }), }).then(r => r.json()); // Part B: Transaction const record = await fetch(`${BASE}/records`, { method: "POST", headers: { ...headers, "X-Idempotency-Key": crypto.randomUUID() }, body: JSON.stringify({ content: { type: "TRANSACTION", record: { id: intention.id }, operation: { type: "RECEIPT", document: { number: "0001", }, breakdown: [ { type: "VAT_RATE", code: "STANDARD", percentage: "22.00", exclusive: "20.00", inclusive: "24.40", amount: "4.40", }, { type: "VAT_RATE", code: "REDUCED_1", percentage: "10.00", exclusive: "0.54545455", inclusive: "0.60", amount: "0.05454545", }, ], totals: { vat: { amount: "4.45454545", exclusive: "20.54545455", inclusive: "25.00", }, }, entries: [ { type: "SALE", details: { concept: "GOOD", }, data: { type: "ITEM", text: "Margherita pizza", unit: { quantity: "2.00", price: { inclusive: "12.20", exclusive: "10.00", }, }, value: { base: "20.00", discount: "0.00", }, vat: { type: "VAT_RATE", code: "STANDARD", percentage: "22.00", exclusive: "20.00", inclusive: "24.40", amount: "4.40", }, }, }, { type: "SALE", details: { concept: "SERVICE", }, data: { type: "ITEM", text: "Service ABC", unit: { quantity: "1.00", price: { inclusive: "0.60", exclusive: "0.54545455", }, }, value: { base: "0.54545455", discount: "0.00", }, vat: { type: "VAT_RATE", code: "REDUCED_1", percentage: "10.00", exclusive: "0.54545455", inclusive: "0.60", amount: "0.05454545", }, }, }, ], payments: [ { type: "CASH", details: { amount: "25.00", }, }, ], }, }, }), }).then(r => r.json()); console.log("Progressive number:", record.compliance?.data);# Part A: Intention intention = requests.post(f"{BASE}/records", headers={ **hdrs, "X-Idempotency-Key": str(uuid.uuid4()) }, json={"content": { "type": "INTENTION", "system": {"id": system_id}, "operation": {"type": "TRANSACTION"}, }}).json() # Part B: Transaction record = requests.post(f"{BASE}/records", headers={ **hdrs, "X-Idempotency-Key": str(uuid.uuid4()) }, json={"content": { "type": "TRANSACTION", "record": {"id": intention["id"]}, "operation": { "type": "RECEIPT", "document": {"number": "0001"}, "breakdown": [ {"type": "VAT_RATE", "code": "STANDARD", "percentage": "22.00", "exclusive": "20.00", "inclusive": "24.40", "amount": "4.40"}, {"type": "VAT_RATE", "code": "REDUCED_1", "percentage": "10.00", "exclusive": "0.54545455", "inclusive": "0.60", "amount": "0.05454545"}, ], "totals": {"vat": {"amount": "4.45454545", "exclusive": "20.54545455", "inclusive": "25.00"}}, "entries": [ {"type": "SALE", "details": {"concept": "GOOD"}, "data": { "type": "ITEM", "text": "Margherita pizza", "unit": {"quantity": "2.00", "price": {"inclusive": "12.20", "exclusive": "10.00"}}, "value": {"base": "20.00", "discount": "0.00"}, "vat": {"type": "VAT_RATE", "code": "STANDARD", "percentage": "22.00", "exclusive": "20.00", "inclusive": "24.40", "amount": "4.40"}}}, {"type": "SALE", "details": {"concept": "SERVICE"}, "data": { "type": "ITEM", "text": "Service ABC", "unit": {"quantity": "1.00", "price": {"inclusive": "0.60", "exclusive": "0.54545455"}}, "value": {"base": "0.54545455", "discount": "0.00"}, "vat": {"type": "VAT_RATE", "code": "REDUCED_1", "percentage": "10.00", "exclusive": "0.54545455", "inclusive": "0.60", "amount": "0.05454545"}}}, ], "payments": [{"type": "CASH", "details": {"amount": "25.00"}}], }, }}).json()// POST /records → INTENTION with system.id and operation.type = TRANSACTION // POST /records → TRANSACTION with intention.id and receipt data // Response includes compliance.data with the AdE progressive number// POST /records → INTENTION, then POST /records → TRANSACTION // Each requires X-Idempotency-Key header // Transaction response contains compliance data from AdEUna volta che il registro raggiunge lo stato
COMPLETEDcon modalitàFINISHED, il documento commerciale è stato trasmesso all’AdE.
Eseguire lo script
Sezione intitolata “Eseguire lo script”Volete eseguire tutti i passaggi automaticamente? Scaricate ed eseguite il nostro script di avvio rapido:
# Scarica ed esegui
curl -O https://workspace.fiskaly.com/scripts/sign-it-quickstart.sh
export API_KEY="your_api_key"
export API_SECRET="your_api_secret"
export GROUP_ORG_ID="your_group_org_id"
bash sign-it-quickstart.sh# Scarica ed esegui
curl -O https://workspace.fiskaly.com/scripts/sign-it-quickstart.mjs
API_KEY="your_key" API_SECRET="your_secret" GROUP_ORG_ID="your_org_id" node sign-it-quickstart.mjs