QR-koder API
Oversigt
Codes-API’en er hjertet i qr3.app. Med den kan du oprette, opdatere og slette dynamiske og statiske QR-koder.
Basis-URL: https://qr3.app/v1/codes
Bindende REST-kontrakt
Følgende kontrakt gælder for alle klienter:
POST /v1/codesaccepterer kun typerneurl,vcard,wifi,email,smsoglocation. Felterne er flade:url; mindstvcard_first_nameellervcard_last_name;wifi_ssid;email_to;sms_phone; ellerlocation_latoglocation_lng.- Kun
url-koder kan være dynamiske. Oprettelsesanmodninger kan valgfrit indeholdeexpires_atsom et ISO 8601-tidspunkt;ab_enabled,ab_target_url_bogab_weight_a(A/B-destinationer) accepteres for dynamiskeurl-koder;redirect_after_expiryer ikke en del af oprettelseskontrakten. GET /v1/codesunderstøtter kunlimit,cursorogstatus(live,paused,flagged,draft).POST /v1/codes/batchacceptererurl,vcardogwifi. Grænsen er 10 for Free, 500 for Pro og 1.000 poster for Business/Agency/Enterprise pr. anmodning. URL-scanninger kører synkront for højst 50 URL-poster; over 50 krævesskip_url_scan: true.
Opret QR-kode
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,q1Response (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" }}QR-kodetyper
| Type | Beskrivelse | Påkrævede felter |
|---|---|---|
url | Website-URL (dynamisk eller statisk) | url |
vcard | Visitkort (vCard 3.0) | vcard_first_name eller vcard_last_name |
wifi | Wi-Fi-konfiguration | wifi_ssid |
email | E-mail (mailto:) | email_to |
sms | SMS | sms_phone |
location | Lokation (geo:) | location_lat, location_lng |
Batch-oprettelse
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 }'Response (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 }}QR-kodeliste
GET /v1/codes
curl https://qr3.app/v1/codes?status=live&limit=20 \ -H "Authorization: Bearer qr3_sk_..."Query-parametre:
| Parameter | Type | Standard | Beskrivelse |
|---|---|---|---|
cursor | string | — | Cursor til paginering |
limit | integer | 20 | Resultater pr. side (maks. 100) |
status | string | — | Filter: live, paused, flagged, draft |
Hent QR-kode
GET /v1/codes/:id
curl https://qr3.app/v1/codes/qr_a1b2c3d4 \ -H "Authorization: Bearer qr3_sk_..."Opdater QR-kode
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.
Dynamiske QR-koder gør det muligt at ændre destinations-URL’en når som helst — uden at skulle genprinte QR-koden.
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" }'Landingsside & eksterne links
For dynamiske url-koder kan du angive is_landing_page: true (ved oprettelse eller via PATCH). En scanning vil derefter vise en side hostet af qr3 med kodens offentlige filer og eksterne links i stedet for at viderestille. Eksterne links overføres som et links-array:
{ "is_landing_page": true, "links": [ { "label": "Datenblatt", "url": "https://example.com/datenblatt.pdf" }, { "label": "Zertifikat", "url": "https://example.com/zertifikat.pdf" } ]}- 0–20 links pr. kode;
labeler 1–100 tegn;urlskal værehttp(s)(≤ 2048 tegn). - Hver URL kontrolleres med Google Web Risk — en usikker URL returnerer
422. - Hvis Web Risk ikke er tilgængelig under lagring, accepteres linket stadig, men markeres til fornyet kontrol. Et dagligt job kontrollerer gemte links igen (og tjekker regelmæssigt links, der tidligere blev klassificeret som sikre) og sætter automatisk koden på pause, hvis et link senere identificeres som usikkert.
"links": []sletter alle links. Se vejledningen til landingssider.
Slet QR-kode
DELETE /v1/codes/:id
Soft-delete — QR-koden arkiveres, scanningsdata bevares.
Et andet DELETE på den samme kode returnerer 404, selvom begge anmodninger ankommer på samme tid. Webhooken qr.deleted sendes nøjagtig én gang.
curl -X DELETE https://qr3.app/v1/codes/qr_a1b2c3d4 \ -H "Authorization: Bearer qr3_sk_..."Download QR-billeder
Alle billedformater er offentligt tilgængelige — ingen godkendelse påkrævet.
| Format | URL | Anvendelse |
|---|---|---|
| SVG (vektor) | /v1/codes/:code/qr.svg | Web, skalering, digital |
| PNG (raster) | /v1/codes/:code/qr.png | E-mail, præsentationer |
| PDF (vektor) | /v1/codes/:code/qr.pdf | Standard: kvadratisk (kun koden); ?format=a4 til et printark |
| EPS (vektor) | /v1/codes/:code/qr.eps | Professionelle print-workflows (Adobe, trykkerier) |
Valgfrit: ?size=N — modulstørrelse i pixels (2–20, standard: 4) for SVG, PNG og EPS. PDF’en bruger en fast modulstørrelse.
Kun PDF: ?format=a4|square — sideformat (standard: square — kun kode + quiet zone, intet hvidt A4-område; a4 til et printklart A4-ark)
# 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.pdfFarver og fejlkorrektion
Alle fire billedruter accepterer tre valgfrie parametre. De gælder for denne ene anmodning og har forrang over farver, der er gemt på koden (næste afsnit).
| Parameter | Værdier | Standard | SVG, PNG | PDF, EPS |
|---|---|---|---|---|
fg | Hex RRGGBB eller RGB | 000000 | tegnes | tegnes som en trykfarve |
bg | Hex som fg eller transparent | ffffff | tegnes | tegnes som en trykfarve |
ecc | L, M, Q, H | M | har effekt | har effekt |
- Skrivemåde: Der skelnes ikke mellem store og små bogstaver, og
#er valgfrit. Hvis det sendes med, skal det kodes som%23. - Ugyldige værdier tæller som ikke angivet.
?fg=lilareturnerer den farve, der er gemt på koden, eller den normale sorte, hvis der ikke er gemt nogen, med200og aldrig en fejl. Kun en eksplicit?fg=000000gennemtvinger sort. bg=transparentreturnerer en SVG, PDF eller EPS uden baggrund og en PNG med en ægte alfakanal. Underlaget, som koden placeres på, skal være lyst og efterlade en frizone på 4 moduler hele vejen rundt. En mørk kode på et mørkt underlag er ikke læsbar.- PDF og EPS skriver sort og grå som gråtone (kun sortplade) og enhver anden farve som CMYK i hele procenter, for eksempel
1F4E79som C74 M36 Y0 K53. Så snart der vælges en farve, ligger der en dækkende flade bag koden og dens frizone, hvid eller i farven frabg, ligesom i SVG-filen. Uden farver forbliver begge filer uændrede. Konvertering og begrænsninger: Farver i tryk. - Læsbarhed: Billedruten kontrollerer ikke kontrasten. Det anbefales at have mindst 4:1 og mørke moduler på en lys baggrund.
#1F4E79på hvid har 8,7:1,#ff6600på hvid kun 2,9:1. eccændrer punktmønstret, ikke indholdet. En trykt kode fungerer fortsat, men gamle og nye trykfiler må ikke blandes.QellerHgør koden mere robust, for eksempel på bølgepap. Et logo gennemtvinger altidH.- Med logo forbliver området bag logoet hvidt, selv ved en farvet eller transparent baggrund.
- Caching: Kun det faktiske standardbillede (sort på hvidt, fejlkorrektion M, intet logo) leveres som uforanderligt i 24 timer; enhver anden gengivelse i 5 minutter. For PDF og EPS tæller enhver angiven baggrund som en afvigelse:
bg=fffffftegner der en hvid udfyldning, som standardfilen ikke har. - Abonnement: Farver og fejlkorrektion er tilgængelige i alle abonnementer, også i det gratis.
# 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' });Gem farver på koden
PATCH /v1/codes/:id gemmer farver som appearance på koden. Billedruterne tegner dem derefter som standard, uden parametre.
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 noneSvar (HTTP 200, forkortet):
{ "data": { "id": "qr_a1b2c3d4", "short_code": "r7f3Kx", "appearance": { "foreground_color": "#1F4E79", "background_color": null } }, "meta": { "request_id": "req_xyz", "issues": [] }}- Værdier:
foreground_colorsom#RRGGBB,background_colorsom#RRGGBBellertransparent. Andre nøgler resulterer i400. - Sammenfletning: Et udeladt felt beholder sin gemte værdi.
nullnulstiller et felt,"appearance": nullnulstiller begge. Sort og hvid gemmes ikke; svaret viser dem somnull. - Ethvert kodesvar indeholder
appearance, ligesom webhookeneqr.createdogqr.updated. - Rækkefølge i billedruterne: først parameteren, derefter den gemte farve, derefter standarden.
?fg=000000leverer derfor den sorte trykfil af en farvet kode. - Indlejrede billeder: En billed-URL følger de gemte farver, så længe den ikke selv fastlægger dem med
fgogbg: en URL uden parametre for begge farver,?fg=000000for baggrunden,?ecc=Qligeledes for begge. Efter en farveændring kan en side, der indlejrer en sådan URL, stadig vise det gamle billede: i op til 24 timer, hvis URL’en indtil da leverede standardbilledet (sort på hvidt, fejlkorrektion M, uden logo), ellers i op til 5 minutter. Afhjælpningen er en egen parameter på URL’en, som ændrer sig med hver farveændring, f.eks.?v=2eller kodensupdated_atsom i dashboardet. Billedruterne ignorerer ukendte parametre. - Fejlkorrektion gemmes aldrig. Den vælges pr. download med
?ecc=. - Kun via
PATCH:POST /v1/codes, batch-kørslen og importen afviserappearancemed422. - PDF og EPS tegner gemte farver som trykfarver, præcis ligesom parametrene. Da hvid aldrig gemmes, får en kode med en gemt forgrundsfarve en hvid udfyldning der, ligesom i SVG.
Kontrastkontrol
API’en kontrollerer det par, der resulterer af anmodningen og den gemte værdi:
| Niveau | Hvornår | Svar |
|---|---|---|
blocked | Kontrast under 1,5:1 | 422, intet gemmes |
critical | under 2:1 eller lysstyrkeforskel under 0,30; en advarsel sammen med et logo; enhver transparent baggrund | 200 med meta.issues |
warning | under 4:1 eller lysstyrkeforskel under 0,50; lyse moduler på mørk baggrund | 200 med meta.issues |
| ok | alt andet | 200, meta.issues er tom |
Hver post i meta.issues har code, severity, field, message og valgfrit hints som contrast_ratio — samme form som overensstemmelsesmeddelelserne for et digitalt produktpas. En transparent baggrund blokeres aldrig, fordi en lys kode på mørk emballage er et reelt anvendelsestilfælde. Underlaget har dog stadig brug for en tydelig kontrast og en fri frizone på 4 moduler hele vejen rundt.
Upload og fjernelse af et logo (POST og DELETE /v1/codes/:id/logo) kontrollerer ligeledes de gemte farver og returnerer også resultaterne i meta.issues: med et logo bliver en advarsel til critical, uden et logo er det en advarsel igen.
Hvis en anden anmodning ændrer den samme kode i samme øjeblik, anvender API’en ændringerne på den nyeste tilstand. Først når dette mislykkes tre gange i træk, svarer den med 409; klienten indlæser derefter koden igen og gentager ændringen.
Logo
POST /v1/codes/:id/logo
Multipart-anmodning, feltet file: PNG, JPEG eller WebP, højst 1 MB, identificeret ud fra magic bytes. Normaliserer billedet til en gennemsigtig 512×512-PNG og erstatter et eksisterende logo.
curl -X POST https://qr3.app/v1/codes/qr_a1b2c3d4/logo \ -H "Authorization: Bearer qr3_sk_..." \Svar (HTTP 201): den opdaterede kode, med logo_file_id angivet.
DELETE /v1/codes/:id/logo
Fjerner logoet og sletter det gemte objekt. Idempotent — et kald uden et eksisterende logo returnerer stadig 200.
Hvis en anden anmodning ændrer den samme kodes logo i samme øjeblik (en anden upload eller en fjernelse), svarer POST og DELETE /v1/codes/:id/logo med 409 (errors/conflict) og ændrer intet; et uploadet billede kasseres. Indlæs koden igen, og prøv igen. To samtidige kald af DELETE /v1/codes/:id/logo er ikke en konflikt; begge returnerer 200.
Hvis det er angivet, indlejrer alle fire formater — qr.svg, qr.png, qr.pdf og qr.eps — logo-pixelene og hæver fejlkorrektionen til H. Den fulde kontrakt — herunder hvilken ændring (tilføjelse/fjernelse vs. udskiftning) der ændrer prikmønstret — samt udskrivningsvejledninger findes under Logo i QR-koden.
Kommentarer
Kommentarer muliggør feedback-loops mellem bureauer og kunder.
GET /v1/codes/:id/comments
POST /v1/codes/:id/comments
PATCH /v1/codes/:id/comments/:commentId
DELETE /v1/codes/:id/comments/:commentId
Dashboard-kommentarer tilskrives den bruger, der opretter dem (author_id); kommentarer oprettet via rene API-nøgler forbliver uden tilskrivning (author_id: null). En kommentar må kun slettes af forfatteren selv eller af en org_admin/ws_admin — rene API-nøgler kan kun slette ikke-tilskrevne API-kommentarer.
# 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 }'