API Codici QR
Panoramica
L’API dei codici è il cuore di qr3.app. Ti consente di creare, aggiornare e eliminare codici QR dinamici e statici.
URL di base: https://qr3.app/v1/codes
Contratto REST vincolante
Il seguente contratto si applica a tutti i client:
POST /v1/codesaccetta soltanto i tipiurl,vcard,wifi,email,smselocation. I campi sono piatti:url; almenovcard_first_nameovcard_last_name;wifi_ssid;email_to;sms_phone; oppure entrambilocation_latelocation_lng.- Solo i codici
urlpossono essere dinamici. Le richieste di creazione possono includere facoltativamenteexpires_atcome timestamp ISO 8601;ab_enabled,ab_target_url_beab_weight_a(destinazioni A/B) sono ammessi per i codiciurldinamici;redirect_after_expirynon fa parte del contratto di creazione. GET /v1/codessupporta sololimit,cursorestatus(live,paused,flagged,draft).POST /v1/codes/batchaccettaurl,vcardewifi. Il limite è 10 per Free, 500 per Pro e 1.000 record per Business/Agency/Enterprise per richiesta. Le scansioni URL sono sincrone per al massimo 50 elementi URL; oltre 50 è richiestoskip_url_scan: true.
Creare un codice QR
POST /v1/codes
curl -X POST https://qr3.app/v1/codes \ -H "Authorization: Bearer qr3_sk_..." \ -H "Content-Type: application/json" \ -d '{ "type": "url", "url": "https://example.com", "title": "Mein erster QR-Code", "tags": ["marketing", "q1"], "is_dynamic": true }'const code = await qr3.codes.create({ type: 'url', url: 'https://example.com', title: 'Mein erster QR-Code', tags: ['marketing', 'q1'], is_dynamic: true,});qr3 create https://example.com --title "Mein QR-Code" --tags marketing,q1Risposta (HTTP 201):
{ "data": { "id": "qr_a1b2c3d4", "short_code": "r7f3Kx", "redirect_url": "https://qr3.app/r7f3Kx", "image_svg_url": "https://qr3.app/v1/codes/r7f3Kx/qr.svg", "image_png_url": "https://qr3.app/v1/codes/r7f3Kx/qr.png", "image_pdf_url": "https://qr3.app/v1/codes/r7f3Kx/qr.pdf", "image_eps_url": "https://qr3.app/v1/codes/r7f3Kx/qr.eps", "type": "url", "target_url": "https://example.com", "is_dynamic": true, "status": "live", "tags": ["marketing", "q1"], "total_scans": 0, "created_at": "2026-03-15T10:00:00.000Z" }, "meta": { "request_id": "req_xyz123" }}Tipi di codici QR
| Tipo | Descrizione | Campi obbligatori |
|---|---|---|
url | URL del sito web (dinamico o statico) | url |
vcard | Biglietto da visita (vCard 3.0) | vcard_first_name o vcard_last_name |
wifi | Configurazione Wi-Fi | wifi_ssid |
email | E-mail (mailto:) | email_to |
sms | SMS | sms_phone |
location | Posizione (geo:) | location_lat, location_lng |
Creazione batch
POST /v1/codes/batch
curl -X POST https://qr3.app/v1/codes/batch \ -H "Authorization: Bearer qr3_sk_..." \ -H "Content-Type: application/json" \ -d '{ "items": [ { "type": "url", "url": "https://produkt-1.example.com", "tags": ["batch"] }, { "type": "url", "url": "https://produkt-2.example.com", "tags": ["batch"] }, { "type": "wifi", "wifi_ssid": "GastWLAN", "wifi_password": "geheim123" } ], "skip_url_scan": false }'Risposta (HTTP 201):
{ "data": { "created": [ { "id": "qr_...", "short_code": "abc123", "redirect_url": "https://qr3.app/abc123" }, { "id": "qr_...", "short_code": "def456", "redirect_url": "https://qr3.app/def456" }, { "id": "qr_...", "short_code": "ghi789", "status": "live" } ], "total": 3, "failed": 0 }}Elenco dei codici QR
GET /v1/codes
curl https://qr3.app/v1/codes?status=live&limit=20 \ -H "Authorization: Bearer qr3_sk_..."Parametri di query:
| Parametro | Tipo | Predefinito | Descrizione |
|---|---|---|---|
cursor | string | — | Cursore per la paginazione |
limit | integer | 20 | Risultati per pagina (max. 100) |
status | string | — | Filtro: live, paused, flagged, draft |
Recuperare un codice QR
GET /v1/codes/:id
curl https://qr3.app/v1/codes/qr_a1b2c3d4 \ -H "Authorization: Bearer qr3_sk_..."Aggiornare un codice QR
PATCH /v1/codes/:id
Update contract: url may be changed only for an existing type: "url" code, and its value must use http:// or https://. Other code types must not receive url; invalid requests return 422.
I codici QR dinamici consentono di modificare l’URL di destinazione in qualsiasi momento, senza dover ristampare il codice QR.
curl -X PATCH https://qr3.app/v1/codes/qr_a1b2c3d4 \ -H "Authorization: Bearer qr3_sk_..." \ -H "Content-Type: application/json" \ -d '{ "url": "https://neue-zielseite.example.com", "status": "live" }'Landing page e link esterni
Per i codici url dinamici, puoi impostare is_landing_page: true (durante la creazione o tramite PATCH). Una scansione mostrerà quindi una pagina ospitata da qr3 con i file pubblici e i link esterni del codice, invece di reindirizzare. I link esterni vengono passati come array links :
{ "is_landing_page": true, "links": [ { "label": "Datenblatt", "url": "https://example.com/datenblatt.pdf" }, { "label": "Zertifikat", "url": "https://example.com/zertifikat.pdf" } ]}- Da 0 a 20 link per codice;
labeldeve essere compreso tra 1 e 100 caratteri;urldeve esserehttp(s)(≤ 2048 caratteri). - Ogni URL viene verificato con Google Web Risk — un URL non sicuro restituisce
422. - Se Web Risk non è raggiungibile al momento del salvataggio, il link viene comunque accettato, ma contrassegnato per una nuova verifica. Un processo giornaliero ricontrolla i link salvati (e periodicamente quelli classificati come sicuri) e mette in pausa automaticamente il codice se un link viene successivamente rilevato come non sicuro.
"links": []elimina tutti i link. Consulta la guida alle landing page.
Eliminare un codice QR
DELETE /v1/codes/:id
Soft-delete — il codice QR viene archiviato, i dati di scansione vengono conservati.
Un secondo DELETE dello stesso codice restituisce 404, anche se entrambe le richieste arrivano contemporaneamente. Il webhook qr.deleted viene inviato esattamente una volta.
curl -X DELETE https://qr3.app/v1/codes/qr_a1b2c3d4 \ -H "Authorization: Bearer qr3_sk_..."Scaricare le immagini dei codici QR
Tutti i formati di immagine sono accessibili pubblicamente — non è richiesta alcuna autenticazione.
| Formato | URL | Utilizzo |
|---|---|---|
| SVG (vettoriale) | /v1/codes/:code/qr.svg | Web, ridimensionamento, digitale |
| PNG (raster) | /v1/codes/:code/qr.png | E-mail, presentazioni |
| PDF (vettoriale) | /v1/codes/:code/qr.pdf | Predefinito: quadrato (solo il codice); ?format=a4 per un foglio di stampa |
| EPS (vettoriale) | /v1/codes/:code/qr.eps | Flussi di lavoro di stampa professionali (Adobe, tipografie) |
Opzionale: ?size=N — dimensione del modulo in pixel (2–20, predefinito: 4) per SVG, PNG ed EPS. Il PDF utilizza una dimensione del modulo fissa.
Solo PDF: ?format=a4|square — formato di pagina (predefinito: square — solo codice + quiet zone, senza spazio bianco A4; a4 per un foglio A4 pronto per la stampa)
# SVG für Webcurl https://qr3.app/v1/codes/r7f3Kx/qr.svg
# PNG in hoher Auflösungcurl https://qr3.app/v1/codes/r7f3Kx/qr.png?size=10 -o qr-hires.png
# Kompaktes PDF (nur der Code, Standard)curl https://qr3.app/v1/codes/r7f3Kx/qr.pdf -o qr.pdf
# Druckfertiges A4-Blattcurl "https://qr3.app/v1/codes/r7f3Kx/qr.pdf?format=a4" -o qr-a4.pdfColori e correzione dell’errore
Tutte e quattro le rotte delle immagini accettano tre parametri opzionali. Si applicano a questa singola richiesta e hanno la priorità sui colori memorizzati nel codice (sezione successiva).
| Parametro | Valori | Predefinito | SVG, PNG | PDF, EPS |
|---|---|---|---|---|
fg | Hex RRGGBB o RGB | 000000 | viene disegnato | viene disegnato come colore di stampa |
bg | Hex come fg o transparent | ffffff | viene disegnato | viene disegnato come colore di stampa |
ecc | L, M, Q, H | M | ha effetto | ha effetto |
- Sintassi: Maiuscole e minuscole non fanno differenza, il carattere
#è opzionale. Se inviato, viene codificato come%23. - I valori non validi contano come non impostati.
?fg=lilarestituisce il colore memorizzato sul codice, o il normale nero se non ne è memorizzato alcuno, con200e mai un errore. Solo un?fg=000000esplicito forza il nero. bg=transparentrestituisce un SVG, PDF o EPS senza sfondo e un PNG con un canale alfa reale. La superficie su cui viene posizionato il codice deve essere chiara e lasciare una zona di rispetto libera di 4 moduli tutt’intorno. Un codice scuro su sfondo scuro non è leggibile.- PDF e EPS scrivono il nero e il grigio come scala di grigi (solo lastra del nero) e qualsiasi altro colore come CMYK in percentuale intera, ad esempio
1F4E79come C74 M36 Y0 K53. Non appena viene scelto un colore, dietro il codice e la sua zona di rispetto si posiziona un riempimento opaco, bianco o nel colore dibg, come nell’SVG. Senza colori entrambi i file rimangono invariati. Conversione e limiti: Colori di stampa. - Leggibilità: La rotta dell’immagine non verifica il contrasto. Si raccomanda un rapporto di almeno 4:1 e moduli scuri su sfondo chiaro.
#1F4E79su bianco ha un rapporto di 8,7:1,#ff6600su bianco solo 2,9:1. eccmodifica il motivo dei punti, non il contenuto. Un codice stampato continua a funzionare, ma i vecchi e i nuovi file di stampa non devono essere mescolati.QoHrendono il codice più robusto, ad esempio sul cartone ondulato. Un logo impone sempreH.- Con logo l’area dietro il logo rimane bianca, anche con uno sfondo colorato o trasparente.
- Caching: Solo l’immagine predefinita effettiva (nero su bianco, correzione dell’errore M, nessun logo) viene fornita come immutabile per 24 ore; qualsiasi altra rappresentazione per 5 minuti. Per PDF ed EPS qualsiasi sfondo specificato conta come una deviazione:
bg=ffffffdisegna lì un riempimento bianco che il file standard non ha. - Piano: I colori e la correzione dell’errore sono disponibili in qualsiasi piano, anche in quello gratuito.
# Dark blue code on whitecurl "https://qr3.app/v1/codes/r7f3Kx/qr.svg?fg=1F4E79" -o qr-blue.svg
# Transparent PNG for a layout on a light surfacecurl "https://qr3.app/v1/codes/r7f3Kx/qr.png?size=10&bg=transparent" -o qr-transparent.png
# More robust for corrugated board: error correction Qcurl "https://qr3.app/v1/codes/r7f3Kx/qr.pdf?ecc=Q" -o qr-q.pdf// @qr3/sdk 1.2.0 or later — imageUrl() only builds the URL, it sends no request// Dark blue code on whiteqr3.codes.imageUrl('r7f3Kx', { format: 'svg', fg: '1F4E79' });// → https://qr3.app/v1/codes/r7f3Kx/qr.svg?fg=1F4E79
// Transparent PNG for a layout on a light surfaceqr3.codes.imageUrl('r7f3Kx', { format: 'png', size: 10, bg: 'transparent' });
// More robust for corrugated board: error correction Qqr3.codes.imageUrl('r7f3Kx', { format: 'pdf', ecc: 'Q' });Salvare i colori sul codice
PATCH /v1/codes/:id salva i colori come appearance sul codice. Le rotte delle immagini li disegnano quindi per impostazione predefinita, senza parametri.
curl -X PATCH https://qr3.app/v1/codes/qr_a1b2c3d4 \ -H "Authorization: Bearer qr3_sk_..." \ -H "Content-Type: application/json" \ -d '{"appearance": {"foreground_color": "#1F4E79"}}'// @qr3/sdk 1.2.0 or laterconst code = await qr3.codes.update('qr_a1b2c3d4', { appearance: { foreground_color: '#1F4E79' },});code.appearance; // { foreground_color: '#1F4E79', background_color: null }code.issues; // contrast check findings, absent when there are noneRisposta (HTTP 200, abbreviata):
{ "data": { "id": "qr_a1b2c3d4", "short_code": "r7f3Kx", "appearance": { "foreground_color": "#1F4E79", "background_color": null } }, "meta": { "request_id": "req_xyz", "issues": [] }}- Valori:
foreground_colorcome#RRGGBB,background_colorcome#RRGGBBotransparent. Altre chiavi restituiscono400. - Unione: Un campo omesso conserva il suo valore salvato.
nullripristina un campo,"appearance": nullentrambi. Il nero e il bianco non vengono salvati; la risposta li mostra comenull. - Ogni risposta del codice contiene
appearance, così come i webhookqr.createdeqr.updated. - Ordine nelle rotte delle immagini: prima il parametro, poi il colore salvato, infine il valore predefinito.
?fg=000000fornisce quindi il file di stampa nero di un codice a colori. - Immagini incorporate: Un URL dell’immagine segue i colori memorizzati, a meno che non li imposti esso stesso con
fgebg: un URL senza parametri per entrambi i colori,?fg=000000per lo sfondo,?ecc=Qugualmente per entrambi. Dopo una variazione di colore, una pagina che incorpora un tale URL può ancora mostrare la vecchia immagine: fino a 24 ore se l’URL ha fornito l’immagine predefinita fino a quel momento (nero su bianco, correzione dell’errore M, senza logo), altrimenti fino a 5 minuti. La soluzione è un parametro personalizzato nell’URL che cambia a ogni variazione di colore, come?v=2o ilupdated_atdel codice come nel Dashboard. Le rotte delle immagini ignorano i parametri sconosciuti. - La correzione d’errore non viene mai salvata. Viene selezionata per ogni download con
?ecc=. - Solo tramite
PATCH:POST /v1/codes, il batch e l’importazione rifiutanoappearancecon422. - PDF e EPS disegnano i colori salvati come colori di stampa, esattamente come i parametri. Poiché il bianco non viene mai salvato, un codice con un colore di primo piano salvato ottiene un riempimento bianco, come nel formato SVG.
Verifica del contrasto
L’API verifica la coppia risultante dalla richiesta e dal valore salvato:
| Livello | Quando | Risposta |
|---|---|---|
blocked | contrasto inferiore a 1,5:1 | 422, non viene salvato nulla |
critical | inferiore a 2:1 o differenza di luminosità inferiore a 0,30; un avviso insieme a un logo; qualsiasi sfondo trasparente | 200 con meta.issues |
warning | inferiore a 4:1 o differenza di luminosità inferiore a 0,50; moduli chiari su sfondo scuro | 200 con meta.issues |
| ok | tutto il resto | 200, meta.issues è vuoto |
Ogni voce in meta.issues ha code, severity, field, message e opzionalmente hints come contrast_ratio — la stessa forma dei messaggi di conformità di un passaporto digitale di prodotto. Uno sfondo trasparente non viene mai bloccato, perché un codice chiaro su un imballaggio scuro è un caso d’uso reale. Lo sfondo ha comunque bisogno di un contrasto netto e di una zona di silenzio libera di 4 moduli tutt’intorno.
Il caricamento e la rimozione di un logo (POST e DELETE /v1/codes/:id/logo) eseguono lo stesso controllo sui colori memorizzati e restituiscono i risultati sempre in meta.issues: con un logo un avviso diventa critical, senza logo torna a essere un avviso.
Se un’altra richiesta modifica lo stesso codice nello stesso momento, l’API applica le modifiche allo stato più recente. Solo se questo fallisce per tre volte di seguito, risponde con 409; il client ricarica quindi il codice e ripete la modifica.
Logo
POST /v1/codes/:id/logo
Richiesta multipart, campo file: PNG, JPEG o WebP, massimo 1 MB, rilevato tramite magic bytes. Normalizza l’immagine in un PNG trasparente 512×512 e sostituisce un logo esistente.
curl -X POST https://qr3.app/v1/codes/qr_a1b2c3d4/logo \ -H "Authorization: Bearer qr3_sk_..." \Risposta (HTTP 201): il codice aggiornato, con logo_file_id impostato.
DELETE /v1/codes/:id/logo
Rimuove il logo ed elimina l’oggetto memorizzato. Idempotente — una chiamata senza un logo esistente restituisce comunque 200.
Se un’altra richiesta modifica il logo dello stesso codice nello stesso momento (un secondo caricamento o una rimozione), POST e DELETE /v1/codes/:id/logo rispondono con 409 (errors/conflict) e non modificano nulla; un’immagine caricata viene scartata. Ricarica il codice e riprova. Due chiamate simultanee a DELETE /v1/codes/:id/logo non costituiscono un conflitto; entrambe restituiscono 200.
Se impostato, tutti e quattro i formati — qr.svg, qr.png, qr.pdf e qr.eps — incorporano i pixel del logo e aumentano la correzione dell’errore a H. Il contratto completo — incluso quale modifica (aggiunta/rimozione vs. sostituzione) altera il pattern di punti — e le istruzioni di stampa sono disponibili in Logo nel codice QR.
Commenti
I commenti consentono cicli di feedback tra agenzie e clienti.
GET /v1/codes/:id/comments
POST /v1/codes/:id/comments
PATCH /v1/codes/:id/comments/:commentId
DELETE /v1/codes/:id/comments/:commentId
I commenti del dashboard vengono attribuiti all’utente che li ha creati (author_id); i commenti creati tramite semplici API key rimangono non attribuiti (author_id: null). Un commento può essere eliminato solo dal suo autore o da un org_admin/ws_admin — le semplici API key possono eliminare solo i commenti non attribuiti creati tramite API.
# Kommentar hinzufügencurl -X POST https://qr3.app/v1/codes/qr_a1b2c3d4/comments \ -H "Authorization: Bearer qr3_sk_..." \ -H "Content-Type: application/json" \ -d '{ "body": "QR-Code bitte auf grünen Hintergrund abstimmen.", "author_name": "Max Müller" }'
# Offene Kommentare auflistencurl "https://qr3.app/v1/codes/qr_a1b2c3d4/comments?resolved=false" \ -H "Authorization: Bearer qr3_sk_..."
# Kommentar als erledigt markierencurl -X PATCH https://qr3.app/v1/codes/qr_a1b2c3d4/comments/cmt_xyz \ -H "Authorization: Bearer qr3_sk_..." \ -H "Content-Type: application/json" \ -d '{ "resolved": true }'