API REST · Documentazione
Tutto quello che serve per collegare l'API.
Una chiave, un indirizzo e le stesse regole per tutti i servizi. Qui trovi la guida comune e l'endpoint dei QR statici; ogni servizio ha la sua scheda tecnica.
curl "https://www.qrcodegenerate.it/api/v1/qrcode/generate-static?content=https://www.tuosito.it&size=300" \
-H "x-api-key: LA_TUA_API_KEY" \
--output qrcode.png
Da dove partire.
La guida comune vale per tutto. Poi scegli il servizio che ti serve.
Endpoint, parametri, esempi in molti linguaggi e risposte, in questa pagina.
Vai → Guida comunePaginazione, limiti di frequenza, webhook, date ed errori: valgono per tutti i servizi.
Vai → QR dinamiciScheda tecnica con endpoint, parametri, errori ed esempi.
Scheda tecnica →Biglietti con convalidaScheda tecnica con endpoint, parametri, errori ed esempi.
Scheda tecnica →Etichette digitaliScheda tecnica con endpoint, parametri, errori ed esempi.
Scheda tecnica →Anti-contraffazioneScheda tecnica con endpoint, parametri, errori ed esempi.
Scheda tecnica →Chiave e indirizzo.
Tutte le richieste partono da qui.
https://www.qrcodegenerate.it/api/v1Va nell'header di ogni richiesta. Tienila sul tuo server: mai in un'app o in una pagina pubblica. La convalida dei biglietti usa una chiave dedicata.
x-api-key: LA_TUA_API_KEYHanno sempre la forma { "status", "code", "message" }: usa code nel tuo codice.
Guida comune.
Vale per tutti i servizi: QR statici e dinamici, biglietti e buoni, etichette digitali, anti-contraffazione e webhook. I numeri sono quelli in vigore adesso.
Elenchi e paginazione
Gli elenchi (QR, eventi, biglietti, chiavi, schede) accettano limit e offset nell'indirizzo. limit è il numero di elementi per pagina: da 1 a 100, predefinito 50. offset è quanti elementi saltare.
La risposta contiene items, total (tutti gli elementi), limit e offset usati. Per leggere tutto, continua ad aumentare offset di limit finché offset + limit non raggiunge total.
GET /api/v1/qrcode/dynamic?limit=100&offset=100
Limiti di frequenza
Le chiamate fatte con la tua chiave API hanno un limite di richieste al minuto che dipende dal piano: lo trovi nella tabella «Cosa include ogni piano». Ogni risposta riporta X-RateLimit-Limit e X-RateLimit-Remaining. Superato il limite ricevi 429 TROPPE_RICHIESTE_AL_MINUTO con l'intestazione Retry-After: i secondi da aspettare. Una richiesta respinta non consuma la quota mensile.
In più, contro le raffiche, ogni indirizzo di rete può fare al massimo 6.000 richieste al minuto, qualunque sia il piano.
La convalida ai varchi ha limiti propri, pensati per il personale: 300 scansioni al minuto per ogni chiave di convalida e 100 richieste non riuscite (chiave sbagliata, richiesta malformata) ogni 10 minuti per indirizzo. Le scansioni dei clienti sul QR non contano nelle richieste del piano.
Oltre al limite di frequenza, il piano fissa una quota mensile di richieste e un numero massimo di QR, eventi, biglietti, chiavi e schede: la tabella «Cosa include ogni piano» di ogni prodotto mostra i valori in vigore.
Webhook
Un webhook è un indirizzo https del tuo server che riceve una chiamata POST appena succede qualcosa nel tuo account. Si gestiscono dalla dashboard (scheda «Webhook») o con /api/v1/webhooks. Sono inclusi secondo il piano: la tabella «Cosa include ogni piano» dice quanti.
Eventi: qr.scanned, qr.expired, ticket.validated, voucher.redeemed, authenticity.checked. Il corpo è JSON: { "id", "type", "apiVersion", "createdAt", "data" }; id è unico per ogni invio e si ripete nei nuovi tentativi, quindi puoi usarlo per non elaborare due volte lo stesso evento.
Ogni invio porta X-QRG-Event, X-QRG-Delivery, X-QRG-Webhook e X-QRG-Signature: t=<secondi>,v1=<firma>. La firma è HMAC-SHA256, in esadecimale, del testo «t.corpo» con il segreto del webhook (whsec_…). Il segreto si vede solo alla creazione e quando lo rinnovi.
Il tuo server deve rispondere con un codice 2xx entro 10 secondi. Se non succede si riprova dopo 1 minuto, 5 minuti, 30 minuti, 2 ore, 8 ore. Dopo 20 invii non consegnati di fila il webhook si sospende e lo riattivi dalla dashboard. Il registro degli invii resta 30 giorni.
Si invia solo a indirizzi https pubblici. I redirect non vengono seguiti.
// Node.js: verifica della firma
const crypto = require("crypto");
function firmaValida(corpoGrezzo, intestazione, segreto) {
const p = Object.fromEntries(intestazione.split(",").map((x) => x.split("=")));
const attesa = crypto.createHmac("sha256", segreto).update(p.t + "." + corpoGrezzo).digest();
const ricevuta = Buffer.from(String(p.v1 || ""), "hex");
if (ricevuta.length !== attesa.length) return false; // firma assente o di lunghezza sbagliata
return crypto.timingSafeEqual(attesa, ricevuta) && Math.abs(Date.now() / 1000 - Number(p.t)) < 300; // al massimo 5 minuti fa
}Date, orari e fusi
Le date e gli orari che invii vanno nel formato ISO 8601 con il fuso orario, per esempio 2026-10-04T21:00:00+02:00. Le risposte li restituiscono sempre in UTC, con la Z finale.
Gli intervalli di date delle statistiche (from e to) sono giorni nel formato AAAA-MM-GG e si contano sul fuso dell'Italia (Europe/Rome).
Errori
Ogni errore ha la forma { "status", "code", "message" }: status è il codice HTTP, code è un testo stabile che puoi usare nel codice, message è una spiegazione in italiano. Non basare la logica sul testo di message. Alcune risposte hanno anche error, con lo stesso testo di message: c'è per compatibilità, usa code.
Chiave e quota valgono per tutti i servizi: 401 CHIAVE_MANCANTE (manca l'header x-api-key), 403 CHIAVE_NON_VALIDA, 403 PIANO_NON_ATTIVO, 429 TROPPE_RICHIESTE_AL_MINUTO (limite al minuto del piano), 429 QUOTA_MENSILE_ESAURITA (richieste del periodo finite), 429 TROPPE_RICHIESTE (troppe richieste dallo stesso indirizzo di rete).
Una richiesta con campi che non esistono viene rifiutata con 422 CAMPO_NON_CONSENTITO: i nomi vanno scritti come nelle tabelle dei parametri. 401 e 403 riguardano la chiave, 404 un elemento che non esiste o non è tuo, 409 una modifica in conflitto, 429 troppe richieste.
QR statici.
Un QR statico contiene direttamente il testo o l'indirizzo: non si può cambiare dopo la stampa e non ha statistiche. Se ti serve cambiarlo, usa i QR dinamici.
Indirizzo e metodi POST e GET
- POST
/qrcode/generate-staticCorpo JSON. Consigliato: supporta tutti i parametri.
- GET
/qrcode/generate-staticParametri nell'indirizzo, utile per richieste semplici. I colori si passano come
color[dark]ecolor[light].
Parametri 6 campi
| Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
content |
stringa | Sì | Testo o URL da codificare nel QR Code, al massimo 2.000 caratteri. |
format |
stringa | No | Formato output: png, jpeg, webp, svg, base64url. Default: png. |
size |
numero | No | Lato del QR Code in pixel: numero intero da 100 a 2000. Default: 200. |
color |
oggetto | No | Solo POST: colori dark e light nel formato #RRGGBB o #RRGGBBAA, diversi tra loro. Esempio: { "dark": "#000000", "light": "#ffffff" }. |
color[dark] / color[light] |
query string | No | Solo GET: colori di primo piano e sfondo passati come parametri URL. |
logoUrl |
stringa URL | No | URL pubblico di un logo da inserire al centro del QR (PNG, JPEG o WebP, non SVG; al massimo 2 MB, scaricato entro 5 secondi). Funziona con png, jpeg, webp e base64url. Se il logo non si scarica il QR esce lo stesso, senza logo: l'intestazione X-QR-Logo vale applied o skipped. |
Nota: l'svg viene generato senza logo. Per un QR con logo usa png, jpeg, webp o base64url.
Esempi 14 linguaggi
Gli esempi usano l'endpoint reale e salvano il risultato come file quando il formato restituisce un'immagine. Sostituisci LA_TUA_API_KEY con la tua chiave o usa una variabile d'ambiente.
cURL — POST consigliato
curl -X POST "https://www.qrcodegenerate.it/api/v1/qrcode/generate-static" \
-H "Content-Type: application/json" \
-H "x-api-key: LA_TUA_API_KEY" \
--output qrcode.png \
-d '{
"content": "https://www.tuosito.it",
"format": "png",
"size": 300,
"color": {
"dark": "#000000",
"light": "#ffffff"
}
}'
Node.js 18+ — POST
import { writeFile } from "node:fs/promises";
const apiKey = process.env.QRCODEGENERATE_API_KEY;
const endpoint = "https://www.qrcodegenerate.it/api/v1/qrcode/generate-static";
if (!apiKey) {
throw new Error("Variabile QRCODEGENERATE_API_KEY mancante");
}
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": apiKey
},
body: JSON.stringify({
content: "https://www.tuosito.it",
format: "png",
size: 300,
color: {
dark: "#000000",
light: "#ffffff"
}
})
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`Errore API ${response.status}: ${errorBody}`);
}
const buffer = Buffer.from(await response.arrayBuffer());
await writeFile("qrcode.png", buffer);
console.log("QR Code salvato in qrcode.png");
Node.js 18+ — GET semplice
import { writeFile } from "node:fs/promises";
const apiKey = process.env.QRCODEGENERATE_API_KEY;
const endpoint = new URL("https://www.qrcodegenerate.it/api/v1/qrcode/generate-static");
endpoint.searchParams.set("content", "https://www.tuosito.it");
endpoint.searchParams.set("format", "svg");
endpoint.searchParams.set("size", "300");
endpoint.searchParams.set("color[dark]", "#000000");
endpoint.searchParams.set("color[light]", "#ffffff");
const response = await fetch(endpoint, {
method: "GET",
headers: {
"x-api-key": apiKey
}
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`Errore API ${response.status}: ${errorBody}`);
}
const svg = await response.text();
await writeFile("qrcode.svg", svg, "utf8");
console.log("QR Code SVG salvato in qrcode.svg");
Python — POST
import os
import requests
api_key = os.environ.get("QRCODEGENERATE_API_KEY")
endpoint = "https://www.qrcodegenerate.it/api/v1/qrcode/generate-static"
if not api_key:
raise RuntimeError("Variabile QRCODEGENERATE_API_KEY mancante")
payload = {
"content": "https://www.tuosito.it",
"format": "png",
"size": 300,
"color": {
"dark": "#000000",
"light": "#ffffff"
}
}
response = requests.post(
endpoint,
headers={"x-api-key": api_key},
json=payload,
timeout=30
)
if not response.ok:
raise RuntimeError(f"Errore API {response.status_code}: {response.text}")
with open("qrcode.png", "wb") as file:
file.write(response.content)
print("QR Code salvato in qrcode.png")
PHP — POST con cURL
<?php
$apiKey = getenv('QRCODEGENERATE_API_KEY');
$endpoint = 'https://www.qrcodegenerate.it/api/v1/qrcode/generate-static';
if (!$apiKey) {
throw new RuntimeException('Variabile QRCODEGENERATE_API_KEY mancante');
}
$payload = json_encode([
'content' => 'https://www.tuosito.it',
'format' => 'png',
'size' => 300,
'color' => [
'dark' => '#000000',
'light' => '#ffffff'
]
]);
$ch = curl_init($endpoint);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'x-api-key: ' . $apiKey
],
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30
]);
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($response === false) {
throw new RuntimeException(curl_error($ch));
}
curl_close($ch);
if ($statusCode < 200 || $statusCode >= 300) {
throw new RuntimeException('Errore API ' . $statusCode . ': ' . $response);
}
file_put_contents('qrcode.png', $response);
echo 'QR Code salvato in qrcode.png';
TypeScript — POST
import { writeFile } from "node:fs/promises";
const apiKey = process.env.QRCODEGENERATE_API_KEY;
const endpoint = "https://www.qrcodegenerate.it/api/v1/qrcode/generate-static";
if (!apiKey) {
throw new Error("Variabile QRCODEGENERATE_API_KEY mancante");
}
const payload = {
content: "https://www.tuosito.it",
format: "png",
size: 300,
color: {
dark: "#000000",
light: "#ffffff"
}
};
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": apiKey
},
body: JSON.stringify(payload)
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`Errore API ${response.status}: ${errorBody}`);
}
const fileBuffer = Buffer.from(await response.arrayBuffer());
await writeFile("qrcode.png", fileBuffer);
Ruby — POST
require "net/http"
require "json"
require "uri"
api_key = ENV["QRCODEGENERATE_API_KEY"]
endpoint = URI("https://www.qrcodegenerate.it/api/v1/qrcode/generate-static")
raise "Variabile QRCODEGENERATE_API_KEY mancante" if api_key.to_s.empty?
request = Net::HTTP::Post.new(endpoint)
request["Content-Type"] = "application/json"
request["x-api-key"] = api_key
request.body = {
content: "https://www.tuosito.it",
format: "png",
size: 300,
color: {
dark: "#000000",
light: "#ffffff"
}
}.to_json
response = Net::HTTP.start(endpoint.hostname, endpoint.port, use_ssl: endpoint.scheme == "https") do |http|
http.request(request)
end
unless response.is_a?(Net::HTTPSuccess)
raise "Errore API #{response.code}: #{response.body}"
end
File.binwrite("qrcode.png", response.body)
puts "QR Code salvato in qrcode.png"
Swift — POST
import Foundation
@main
struct GenerateQrCode {
static func main() async throws {
let apiKey = ProcessInfo.processInfo.environment["QRCODEGENERATE_API_KEY"] ?? ""
guard !apiKey.isEmpty else {
fatalError("Variabile QRCODEGENERATE_API_KEY mancante")
}
let endpoint = URL(string: "https://www.qrcodegenerate.it/api/v1/qrcode/generate-static")!
var request = URLRequest(url: endpoint)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(apiKey, forHTTPHeaderField: "x-api-key")
let payload: [String: Any] = [
"content": "https://www.tuosito.it",
"format": "png",
"size": 300,
"color": [
"dark": "#000000",
"light": "#ffffff"
]
]
request.httpBody = try JSONSerialization.data(withJSONObject: payload)
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
let body = String(data: data, encoding: .utf8) ?? ""
throw NSError(domain: "QRCodeGenerate", code: 1, userInfo: [NSLocalizedDescriptionKey: body])
}
try data.write(to: URL(fileURLWithPath: "qrcode.png"))
print("QR Code salvato in qrcode.png")
}
}
Go — POST
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
apiKey := os.Getenv("QRCODEGENERATE_API_KEY")
if apiKey == "" {
panic("Variabile QRCODEGENERATE_API_KEY mancante")
}
payload := map[string]interface{}{
"content": "https://www.tuosito.it",
"format": "png",
"size": 300,
"color": map[string]string{
"dark": "#000000",
"light": "#ffffff",
},
}
body, err := json.Marshal(payload)
if err != nil {
panic(err)
}
req, err := http.NewRequest("POST", "https://www.qrcodegenerate.it/api/v1/qrcode/generate-static", bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-api-key", apiKey)
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
errorBody, _ := io.ReadAll(resp.Body)
panic(fmt.Sprintf("Errore API %d: %s", resp.StatusCode, string(errorBody)))
}
file, err := os.Create("qrcode.png")
if err != nil {
panic(err)
}
defer file.Close()
if _, err := io.Copy(file, resp.Body); err != nil {
panic(err)
}
fmt.Println("QR Code salvato in qrcode.png")
}
C++ — POST con libcurl
#include <curl/curl.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
int main() {
const char* apiKeyEnv = std::getenv("QRCODEGENERATE_API_KEY");
if (apiKeyEnv == nullptr) {
std::cerr << "Variabile QRCODEGENERATE_API_KEY mancante" << std::endl;
return 1;
}
FILE* output = std::fopen("qrcode.png", "wb");
if (!output) {
std::cerr << "Impossibile creare qrcode.png" << std::endl;
return 1;
}
CURL* curl = curl_easy_init();
if (!curl) {
std::fclose(output);
return 1;
}
std::string apiHeader = std::string("x-api-key: ") + apiKeyEnv;
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, apiHeader.c_str());
const char* payload = R"json({
"content": "https://www.tuosito.it",
"format": "png",
"size": 300,
"color": {
"dark": "#000000",
"light": "#ffffff"
}
})json";
curl_easy_setopt(curl, CURLOPT_URL, "https://www.qrcodegenerate.it/api/v1/qrcode/generate-static");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, output);
CURLcode result = curl_easy_perform(curl);
if (result != CURLE_OK) {
std::cerr << curl_easy_strerror(result) << std::endl;
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
std::fclose(output);
return result == CURLE_OK ? 0 : 1;
}
C# — POST
using System.Text;
var apiKey = Environment.GetEnvironmentVariable("QRCODEGENERATE_API_KEY");
if (string.IsNullOrWhiteSpace(apiKey))
{
throw new InvalidOperationException("Variabile QRCODEGENERATE_API_KEY mancante");
}
var endpoint = "https://www.qrcodegenerate.it/api/v1/qrcode/generate-static";
var json = """
{
"content": "https://www.tuosito.it",
"format": "png",
"size": 300,
"color": {
"dark": "#000000",
"light": "#ffffff"
}
}
""";
using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, endpoint);
request.Headers.Add("x-api-key", apiKey);
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsByteArrayAsync();
if (!response.IsSuccessStatusCode)
{
var errorText = Encoding.UTF8.GetString(body);
throw new Exception($"Errore API {(int)response.StatusCode}: {errorText}");
}
await File.WriteAllBytesAsync("qrcode.png", body);
Console.WriteLine("QR Code salvato in qrcode.png");
Java 11+ — POST
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
public class GenerateQrCode {
public static void main(String[] args) throws Exception {
String apiKey = System.getenv("QRCODEGENERATE_API_KEY");
if (apiKey == null || apiKey.isBlank()) {
throw new IllegalStateException("Variabile QRCODEGENERATE_API_KEY mancante");
}
String json = """
{
"content": "https://www.tuosito.it",
"format": "png",
"size": 300,
"color": {
"dark": "#000000",
"light": "#ffffff"
}
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://www.qrcodegenerate.it/api/v1/qrcode/generate-static"))
.header("Content-Type", "application/json")
.header("x-api-key", apiKey)
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<byte[]> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofByteArray());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new RuntimeException("Errore API " + response.statusCode() + ": " + new String(response.body()));
}
Files.write(Path.of("qrcode.png"), response.body());
System.out.println("QR Code salvato in qrcode.png");
}
}
VB.NET — POST
Imports System
Imports System.IO
Imports System.Net.Http
Imports System.Text
Imports System.Threading.Tasks
Module Program
Sub Main()
MainAsync().GetAwaiter().GetResult()
End Sub
Private Async Function MainAsync() As Task
Dim apiKey = Environment.GetEnvironmentVariable("QRCODEGENERATE_API_KEY")
If String.IsNullOrWhiteSpace(apiKey) Then
Throw New InvalidOperationException("Variabile QRCODEGENERATE_API_KEY mancante")
End If
Dim endpoint = "https://www.qrcodegenerate.it/api/v1/qrcode/generate-static"
Dim json = "{" &
"""content"":""https://www.tuosito.it""," &
"""format"":""png""," &
"""size"":300," &
"""color"":{""dark"":""#000000"",""light"":""#ffffff""}" &
"}"
Using client As New HttpClient()
Using request As New HttpRequestMessage(HttpMethod.Post, endpoint)
request.Headers.Add("x-api-key", apiKey)
request.Content = New StringContent(json, Encoding.UTF8, "application/json")
Using response = Await client.SendAsync(request)
Dim body = Await response.Content.ReadAsByteArrayAsync()
If Not response.IsSuccessStatusCode Then
Dim errorText = Encoding.UTF8.GetString(body)
Throw New Exception("Errore API " & CInt(response.StatusCode) & ": " & errorText)
End If
File.WriteAllBytes("qrcode.png", body)
Console.WriteLine("QR Code salvato in qrcode.png")
End Using
End Using
End Using
End Function
End Module
Frontend — esempio sicuro tramite tuo backend
<form id="qrForm">
<input id="qrContent" type="url" placeholder="https://www.tuosito.it" required>
<button type="submit">Genera QR</button>
</form>
<img id="qrPreview" alt="QR Code generato" hidden>
<script>
document.getElementById("qrForm").addEventListener("submit", async (event) => {
event.preventDefault();
const content = document.getElementById("qrContent").value;
const response = await fetch("/api/qr-proxy", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ content })
});
if (!response.ok) {
throw new Error(await response.text());
}
const blob = await response.blob();
const imageUrl = URL.createObjectURL(blob);
const preview = document.getElementById("qrPreview");
preview.src = imageUrl;
preview.hidden = false;
});
</script>
Risposte ed errori 200, 401, 403, 422, 429, 500
Per png, jpeg, webp e svg, una richiesta valida restituisce direttamente il file generato.
Per base64url, la risposta è JSON con il valore base64.
| Status | Quando accade | Esempio risposta |
|---|---|---|
200 |
QR Code generato correttamente. | image/png, image/jpeg, image/webp, image/svg+xml oppure JSON per base64url. |
422 |
content mancante o troppo lungo, formato, dimensione o colori non validi. |
{ "status": 422, "code": "DIMENSIONE_NON_VALIDA", "message": "Dimensione non valida: numero intero tra 100 e 2000." } |
401 |
Header x-api-key mancante. |
{ "status": 401, "code": "CHIAVE_MANCANTE", "message": "Chiave API mancante. Includi l'header x-api-key." } |
403 |
Chiave non valida (CHIAVE_NON_VALIDA) o piano API non attivo (PIANO_NON_ATTIVO). |
{ "status": 403, "code": "PIANO_NON_ATTIVO", "message": "Il piano API di questa chiave non è attivo." } |
429 |
Limite al minuto del piano (TROPPE_RICHIESTE_AL_MINUTO, con Retry-After in secondi), richieste del periodo finite (QUOTA_MENSILE_ESAURITA) o troppe richieste dallo stesso indirizzo (TROPPE_RICHIESTE). |
{ "status": 429, "code": "TROPPE_RICHIESTE_AL_MINUTO", "message": "Hai superato le … richieste al minuto del tuo piano. Riprova tra … secondi." } |
500 |
Errore interno durante la verifica della chiave, il conteggio delle richieste o la generazione del QR. | { "status": 500, "code": "ERRORE_GENERAZIONE", "message": "Errore interno durante la generazione del QR Code. Riprova." } |
Conserva la chiave sul server, gestisci gli errori con code, rispetta Retry-After quando ricevi 429 e controlla i limiti del piano prima di automatizzare grandi volumi.