API Coduri QR
Prezentare generală
API-ul pentru coduri este inima qr3.app. Cu acesta poți crea, actualiza și șterge coduri QR dinamice și statice.
URL de bază: https://qr3.app/v1/codes
Contract REST obligatoriu
Următorul contract se aplică tuturor clienților:
POST /v1/codesacceptă numai tipurileurl,vcard,wifi,email,smsșilocation. Câmpurile sunt plate:url; cel puținvcard_first_namesauvcard_last_name;wifi_ssid;email_to;sms_phone; sau ambelelocation_latșilocation_lng.- Doar codurile
urlpot fi dinamice. Cererile de creare pot include opționalexpires_atca marcaj temporal ISO 8601;ab_enabled,ab_target_url_bșiab_weight_a(destinații A/B) sunt acceptate pentru coduriurldinamice;redirect_after_expirynu face parte din contractul de creare. GET /v1/codesacceptă numailimit,cursorșistatus(live,paused,flagged,draft).POST /v1/codes/batchacceptăurl,vcardșiwifi. Limita este de 10 pentru Free, 500 pentru Pro și 1.000 de înregistrări pentru Business/Agency/Enterprise per cerere. Scanările URL rulează sincron pentru cel mult 50 de elemente URL; peste 50 este necesarskip_url_scan: true.
Creare cod 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,q1Răspuns (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" }}Tipuri de coduri QR
| Tip | Descriere | Câmpuri obligatorii |
|---|---|---|
url | URL site web (dinamic sau static) | url |
vcard | Carte de vizită (vCard 3.0) | vcard_first_name sau vcard_last_name |
wifi | Configurație Wi-Fi | wifi_ssid |
email | E-mail (mailto:) | email_to |
sms | SMS | sms_phone |
location | Locație (geo:) | location_lat, location_lng |
Creare în lot (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 }'Răspuns (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 }}Listă coduri QR
GET /v1/codes
curl https://qr3.app/v1/codes?status=live&limit=20 \ -H "Authorization: Bearer qr3_sk_..."Parametri Query:
| Parametru | Tip | Implicit | Descriere |
|---|---|---|---|
cursor | string | — | Cursor pentru paginare |
limit | integer | 20 | Rezultate pe pagină (max. 100) |
status | string | — | Filtru: live, paused, flagged, draft |
Obținere cod QR
GET /v1/codes/:id
curl https://qr3.app/v1/codes/qr_a1b2c3d4 \ -H "Authorization: Bearer qr3_sk_..."Actualizare cod 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.
Codurile QR dinamice permit modificarea URL-ului de destinație în orice moment — fără a fi necesară retipărirea codului 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" }'Pagini de destinație și linkuri externe
Pentru codurile url dinamice, poți seta is_landing_page: true (la creare sau prin PATCH). O scanare va afișa atunci o pagină găzduită de qr3 cu fișierele publice și linkurile externe ale codului, în loc să redirecționeze. Linkurile externe sunt transmise ca un tablou (array) links:
{ "is_landing_page": true, "links": [ { "label": "Datenblatt", "url": "https://example.com/datenblatt.pdf" }, { "label": "Zertifikat", "url": "https://example.com/zertifikat.pdf" } ]}- 0–20 de linkuri per cod;
labelare între 1 și 100 de caractere;urltrebuie să fiehttp(s)(≤ 2048 de caractere). - Fiecare URL este verificat cu Google Web Risk — un URL nesigur returnează
422. - Dacă Web Risk nu este accesibil în momentul salvării, linkul este totuși acceptat, dar este marcat pentru o nouă verificare. Un job zilnic verifică din nou linkurile salvate (și periodic pe cele clasificate ca sigure) și suspendă automat codul dacă un link este detectat ulterior ca fiind nesigur.
"links": []șterge toate linkurile. Vezi ghidul pentru pagini de destinație.
Ștergere cod QR
DELETE /v1/codes/:id
Ștergere soft (Soft-Delete) — codul QR este arhivat, datele de scanare sunt păstrate.
O a doua cerere DELETE pentru același cod returnează 404, chiar dacă ambele cereri sosesc în același timp. Webhook-ul qr.deleted este trimis exact o singură dată.
curl -X DELETE https://qr3.app/v1/codes/qr_a1b2c3d4 \ -H "Authorization: Bearer qr3_sk_..."Descărcare imagini QR
Toate formatele de imagine sunt accesibile public — nu este necesară autentificarea.
| Format | URL | Utilizare |
|---|---|---|
| SVG (vectorial) | /v1/codes/:code/qr.svg | Web, scalare, digital |
| PNG (raster) | /v1/codes/:code/qr.png | E-mail, prezentări |
| PDF (vectorial) | /v1/codes/:code/qr.pdf | Implicit: pătrat (doar codul); ?format=a4 pentru o foaie de tipărit |
| EPS (vectorial) | /v1/codes/:code/qr.eps | Fluxuri de lucru profesionale de tipărire (Adobe, tipografii) |
Opțional: ?size=N — dimensiunea modulului în pixeli (2–20, implicit: 4) pentru SVG, PNG și EPS. PDF-ul utilizează o dimensiune fixă a modulului.
Doar PDF: ?format=a4|square — formatul paginii (implicit: square — doar codul + zona de liniște (quiet zone), fără spațiu alb A4; a4 pentru o foaie A4 gata de tipărit)
# 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.pdfCulori și corectarea erorilor
Toate cele patru rute de imagine acceptă trei parametri opționali. Aceștia se aplică pentru această singură descărcare și au prioritate față de culorile salvate în cod (secțiunea următoare).
| Parametru | Valori | Standard | SVG, PNG | PDF, EPS |
|---|---|---|---|---|
fg | Hex RRGGBB sau RGB | 000000 | este desenat | este desenat ca o culoare de tipar |
bg | Hex ca fg sau transparent | ffffff | este desenat | este desenat ca o culoare de tipar |
ecc | L, M, Q, H | M | are efect | are efect |
- Sintaxă: Nu se face distincție între majuscule și minuscule,
#este opțional. Dacă este trimis, se codifică ca%23. - Valorile nevalide sunt considerate ca nefiind setate.
?fg=lilareturnează culoarea salvată pe cod, sau negrul normal dacă nu este salvată niciuna, cu200și niciodată o eroare. Doar un?fg=000000explicit forțează culoarea neagră. bg=transparentreturnează un SVG, PDF sau EPS fără fundal și un PNG cu canal alfa real. Suprafața pe care plasezi codul trebuie să fie deschisă la culoare și să lase liberă o zonă de liniște de 4 module de jur împrejur. Un cod întunecat pe o suprafață întunecată nu poate fi scanat.- PDF și EPS scriu negru și gri ca nuanțe de gri (doar placa de negru) și orice altă culoare ca CMYK în procente întregi, de exemplu
1F4E79ca C74 M36 Y0 K53. De îndată ce este aleasă o culoare, în spatele codului și a zonei sale de liniște se află o umplere opacă, albă sau în culoareabg, ca în SVG. Fără culori, ambele fișiere rămân neschimbate. Conversie și limite: Culorile în tipar. - Lizibilitate: Ruta de imagine nu verifică contrastul. Se recomandă un raport de cel puțin 4:1 și module întunecate pe fundal deschis.
#1F4E79pe alb are 8,7:1,#ff6600pe alb doar 2,9:1. eccmodifică modelul de puncte, nu conținutul. Un cod imprimat continuă să funcționeze, dar fișierele de imprimare vechi și noi nu trebuie amestecate.QsauHfac codul mai robust, de exemplu pe carton ondulat. Un logo forțează întotdeaunaH.- Cu logo suprafața din spatele logo-ului rămâne albă, chiar și în cazul unui fundal colorat sau transparent.
- Cache: doar imaginea standard reală (negru pe alb, corectarea erorilor M, fără logo) este livrată ca imuabilă timp de 24 de ore; orice altă redare timp de 5 minute. Pentru PDF și EPS, orice fundal specificat contează ca o abatere:
bg=ffffffdesenează acolo o umplere albă pe care fișierul standard nu o are. - Disponibilitate: Culorile și corectarea erorilor sunt disponibile în orice tarif, inclusiv în cel gratuit.
# 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' });Salvarea culorilor pe cod
PATCH /v1/codes/:id salvează culorile ca appearance pe cod. Rutele de imagine le desenează apoi în mod implicit, fără 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 noneRăspuns (HTTP 200, prescurtat):
{ "data": { "id": "qr_a1b2c3d4", "short_code": "r7f3Kx", "appearance": { "foreground_color": "#1F4E79", "background_color": null } }, "meta": { "request_id": "req_xyz", "issues": [] }}- Valori:
foreground_colorca#RRGGBB,background_colorca#RRGGBBsautransparent. Alte chei returnează400. - Îmbinare: Un câmp omis își păstrează valoarea salvată.
nullresetează un câmp,"appearance": nullle resetează pe ambele. Negrul și albul nu sunt salvate; răspunsul le afișează canull. - Fiecare răspuns de cod conține
appearance, la fel ca și webhook-urileqr.createdșiqr.updated. - Ordinea în rutele de imagine: mai întâi parametrul, apoi culoarea salvată, apoi valoarea implicită.
?fg=000000oferă, prin urmare, fișierul de tipărire negru al unui cod colorat. - Imagini încorporate: Un URL de imagine urmează culorile salvate, în măsura în care nu le stabilește el însuși prin
fgșibg: un URL fără parametri pentru ambele culori,?fg=000000pentru fundal,?ecc=Qde asemenea pentru ambele. După o schimbare de culoare, o pagină care încorporează un astfel de URL poate afișa în continuare imaginea veche: timp de până la 24 de ore dacă URL-ul a livrat până atunci imaginea standard (negru pe alb, corectarea erorilor M, fără logo), altfel timp de până la 5 minute. Soluția este un parametru propriu adăugat la URL, care se modifică la fiecare schimbare de culoare, cum ar fi?v=2sau valoareaupdated_ata codului, ca în Dashboard. Rutele de imagine ignoră parametrii necunoscuți. - Corecția erorilor nu este salvată niciodată. Aceasta este selectată la fiecare descărcare cu
?ecc=. - Doar prin
PATCH:POST /v1/codes, batch-ul și importul respingappearancecu422. - PDF și EPS desenează culorile salvate ca culori de tipar, exact ca și parametrii. Deoarece albul nu este salvat niciodată, un cod cu o culoare de prim-plan salvată primește acolo o umplere albă, la fel ca în SVG.
Verificarea contrastului
API-ul verifică perechea rezultată din cerere și valoarea salvată:
| Nivel | Când | Răspuns |
|---|---|---|
blocked | contrast sub 1,5:1 | 422, nimic nu este salvat |
critical | sub 2:1 sau diferență de luminozitate sub 0,30; o avertizare împreună cu o siglă; orice fundal transparent | 200 cu meta.issues |
warning | sub 4:1 sau diferență de luminozitate sub 0,50; module deschise pe fundal închis | 200 cu meta.issues |
| ok | orice altceva | 200, meta.issues este gol |
Fiecare intrare din meta.issues are code, severity, field, message și, opțional, hints cum ar fi contrast_ratio — aceeași formă ca mesajele de conformitate ale unui pașaport digital al produsului. Un fundal transparent nu este blocat niciodată, deoarece un cod deschis la culoare pe un ambalaj închis este un caz de utilizare real. Cu toate acestea, fundalul are nevoie de un contrast clar și de o zonă de liniște liberă de jur împrejur de 4 module.
Încărcarea și eliminarea unui logo (POST și DELETE /v1/codes/:id/logo) verifică de asemenea culorile salvate și returnează constatările tot în meta.issues: cu un logo, o avertizare devine critical, fără logo devine din nou o avertizare.
Dacă o altă cerere modifică același cod în același moment, API-ul aplică modificările pe cea mai recentă versiune. Doar dacă acest lucru eșuează de trei ori la rând, acesta răspunde cu 409; clientul reîncarcă apoi codul și repetă modificarea.
Logo
POST /v1/codes/:id/logo
Cerere multipart, câmpul file: PNG, JPEG sau WebP, de maximum 1 MB, detectat după magic bytes. Normalizează imaginea la un PNG transparent de 512×512 și înlocuiește un logo existent.
curl -X POST https://qr3.app/v1/codes/qr_a1b2c3d4/logo \ -H "Authorization: Bearer qr3_sk_..." \Răspuns (HTTP 201): codul actualizat, cu logo_file_id setat.
DELETE /v1/codes/:id/logo
Elimină logo-ul și șterge obiectul stocat. Idempotent — o apelare fără un logo existent returnează în continuare 200.
Dacă o altă cerere modifică în același moment logo-ul aceluiași cod (o a doua încărcare sau o eliminare), POST și DELETE /v1/codes/:id/logo răspund cu 409 (errors/conflict) și nu modifică nimic; o imagine încărcată este eliminată. Reîncarcă codul și încearcă din nou. Două apeluri simultane ale DELETE /v1/codes/:id/logo nu reprezintă un conflict; ambele returnează 200.
Dacă este setat, toate cele patru formate — qr.svg, qr.png, qr.pdf și qr.eps — încorporează pixelii logo-ului și măresc corecția erorilor la H. Contractul complet — inclusiv ce modificare (adăugare/eliminare vs. înlocuire) modifică modelul de puncte — precum și instrucțiunile de imprimare se găsesc la Logo în codul QR.
Comentarii
Comentariile permit bucle de feedback între agenții și clienți.
GET /v1/codes/:id/comments
POST /v1/codes/:id/comments
PATCH /v1/codes/:id/comments/:commentId
DELETE /v1/codes/:id/comments/:commentId
Comentariile din Dashboard sunt atribuite utilizatorului care le-a creat (author_id); comentariile create prin chei API simple rămân neatribuite (author_id: null). Un comentariu poate fi șters doar de către autorul acestuia sau de către un org_admin/ws_admin — cheile API simple pot șterge doar comentariile neatribuite create prin 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 }'