Przejdź do głównej zawartości

API kodów QR

Przegląd

API kodów (Codes API) to serce qr3.app. Pozwala na tworzenie, aktualizowanie i usuwanie dynamicznych oraz statycznych kodów QR.

Bazowy URL: https://qr3.app/v1/codes

Wiążący kontrakt REST

Poniższy kontrakt dotyczy wszystkich klientów:

  • POST /v1/codes akceptuje wyłącznie typy url, vcard, wifi, email, sms i location. Pola są płaskie: url; co najmniej vcard_first_name lub vcard_last_name; wifi_ssid; email_to; sms_phone; albo oba location_lat i location_lng.
  • Tylko kody url mogą być dynamiczne. Żądania utworzenia mogą opcjonalnie zawierać expires_at jako znacznik czasu ISO 8601; ab_enabled, ab_target_url_b i ab_weight_a (cele A/B) są dozwolone dla dynamicznych kodów url; redirect_after_expiry nie jest częścią kontraktu tworzenia.
  • GET /v1/codes obsługuje tylko limit, cursor i status (live, paused, flagged, draft).
  • POST /v1/codes/batch akceptuje url, vcard i wifi. Limit wynosi 10 dla Free, 500 dla Pro i 1 000 rekordów dla Business/Agency/Enterprise na żądanie. Skanowanie URL działa synchronicznie dla maksymalnie 50 elementów URL; powyżej 50 wymagane jest skip_url_scan: true.

Tworzenie kodu QR

POST /v1/codes

Okno terminala
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
}'

Odpowiedź (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" }
}

Typy kodów QR

TypOpisPola wymagane
urlAdres URL strony internetowej (dynamiczny lub statyczny)url
vcardWizytówka (vCard 3.0)vcard_first_name lub vcard_last_name
wifiKonfiguracja Wi-Fiwifi_ssid
emailE-mail (mailto:)email_to
smsSMSsms_phone
locationLokalizacja (geo:)location_lat, location_lng

Tworzenie masowe (Batch)

POST /v1/codes/batch

Okno terminala
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
}'

Odpowiedź (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
}
}

Lista kodów QR

GET /v1/codes

Okno terminala
curl https://qr3.app/v1/codes?status=live&limit=20 \
-H "Authorization: Bearer qr3_sk_..."

Parametry zapytania (Query parameters):

ParametrTypDomyślnieOpis
cursorstring—Kursor do paginacji
limitinteger20Wyniki na stronę (maks. 100)
statusstring—Filtr: live, paused, flagged, draft

Pobieranie kodu QR

GET /v1/codes/:id

Okno terminala
curl https://qr3.app/v1/codes/qr_a1b2c3d4 \
-H "Authorization: Bearer qr3_sk_..."

Aktualizacja kodu 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.

Dynamiczne kody QR umożliwiają zmianę docelowego adresu URL w dowolnym momencie — bez konieczności ponownego drukowania kodu QR.

Okno terminala
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" }'

Strona docelowa (Landing page) i linki zewnętrzne

Dla dynamicznych kodów url możesz ustawić is_landing_page: true (podczas tworzenia lub za pomocą PATCH). Zeskanowanie kodu spowoduje wtedy wyświetlenie hostowanej przez qr3 strony z plikami publicznymi i linkami zewnętrznymi przypisanymi do kodu, zamiast bezpośredniego przekierowania. Linki zewnętrzne są przekazywane jako tablica links:

{
"is_landing_page": true,
"links": [
{ "label": "Datenblatt", "url": "https://example.com/datenblatt.pdf" },
{ "label": "Zertifikat", "url": "https://example.com/zertifikat.pdf" }
]
}
  • Od 0 do 20 linków na kod; label musi mieć od 1 do 100 znaków; url musi zaczynać się od http(s) (≤ 2048 znaków).
  • Każdy adres URL jest sprawdzany za pomocą Google Web Risk — niebezpieczny adres URL zwraca błąd 422.
  • Jeśli usługa Web Risk jest niedostępna podczas zapisywania, link zostanie mimo to zaakceptowany, ale zostanie oznaczony do ponownej weryfikacji. Codzienne zadanie ponownie sprawdza zapisane linki (oraz regularnie weryfikuje te wcześniej uznane za bezpieczne) i automatycznie wstrzymuje (pauses) kod, jeśli link zostanie później uznany za niebezpieczny.
  • "links": [] usuwa wszystkie linki. Zobacz przewodnik po stronach docelowych.

Usuwanie kodu QR

DELETE /v1/codes/:id

Soft-delete (miękkie usunięcie) — kod QR zostaje zarchiwizowany, a dane o skanowaniach zostają zachowane.

Drugie DELETE na tym samym kodzie zwraca 404, nawet jeśli oba zapytania dotrą w tym samym momencie. Webhook qr.deleted jest wysyłany dokładnie raz.

Okno terminala
curl -X DELETE https://qr3.app/v1/codes/qr_a1b2c3d4 \
-H "Authorization: Bearer qr3_sk_..."

Pobieranie obrazów kodów QR

Wszystkie formaty obrazów są publicznie dostępne — uwierzytelnianie nie jest wymagane.

FormatURLZastosowanie
SVG (wektorowy)/v1/codes/:code/qr.svgWeb, skalowanie, cyfrowe
PNG (rastrowy)/v1/codes/:code/qr.pngE-mail, prezentacje
PDF (wektorowy)/v1/codes/:code/qr.pdfDomyślnie: kwadratowy (tylko kod); ?format=a4 dla arkusza do druku
EPS (wektorowy)/v1/codes/:code/qr.epsProfesjonalne procesy drukowania (Adobe, drukarnie)

Opcjonalnie: ?size=N — rozmiar modułu w pikselach (2–20, domyślnie: 4) dla SVG, PNG i EPS. PDF korzysta ze stałego rozmiaru modułu.

Tylko PDF: ?format=a4|square — format strony (domyślnie: square — tylko kod + strefa ciszy (quiet zone), bez białego obszaru A4; a4 dla gotowego do druku arkusza A4)

Okno terminala
# SVG für Web
curl https://qr3.app/v1/codes/r7f3Kx/qr.svg
# PNG in hoher Auflösung
curl 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-Blatt
curl "https://qr3.app/v1/codes/r7f3Kx/qr.pdf?format=a4" -o qr-a4.pdf

Kolory i korekcja błędów

Wszystkie cztery ścieżki obrazów przyjmują trzy opcjonalne parametry. Mają one zastosowanie do tego konkretnego wywołania i mają pierwszeństwo przed kolorami zapisanymi w kodzie (następna sekcja).

ParametrWartościDomyślnieSVG, PNGPDF, EPS
fgHex RRGGBB lub RGB000000jest rysowanyjest rysowany jako kolor druku
bgHex jak fg lub transparentffffffjest rysowanyjest rysowany jako kolor druku
eccL, M, Q, HMdziaładziała
  • Wielkość liter: Wielkość liter nie ma znaczenia, znak # jest opcjonalny. Jest on przesyłany jako zakodowany %23.
  • Nieprawidłowe wartości są traktowane jako nieustawione. ?fg=lila zwraca kolor zapisany w kodzie, a jeśli nie zapisano żadnego, zwykłą czerń, z kodem 200 i nigdy błędem. Tylko wyraźne ?fg=000000 wymusza czerń.
  • bg=transparent zwraca obraz SVG, PDF lub EPS bez tła oraz PNG z prawdziwym kanałem alfa. Podłoże, na którym umieszczany jest kod, musi być jasne i pozostawiać wokół margines bezpieczeństwa (cichą strefę) o szerokości 4 modułów. Ciemny kod na ciemnym tle jest nieczytelny.
  • PDF i EPS zapisują czerń i szarość jako skalę szarości (tylko czarna płyta), a każdy inny kolor jako CMYK w pełnych procentach, na przykład 1F4E79 jako C74 M36 Y0 K53. Gdy tylko wybrany zostanie kolor, za kodem i jego cichą strefą umieszczane jest nieprzezroczyste tło, białe lub w kolorze bg, podobnie jak w SVG. Bez kolorów oba pliki pozostają niezmienione. Konwersja i ograniczenia: Kolory w druku.
  • Czytelność: Ścieżka obrazu nie sprawdza kontrastu. Zalecany jest stosunek co najmniej 4:1 oraz ciemne moduły na jasnym tle. #1F4E79 na białym tle ma stosunek 8,7:1, a #ff6600 na białym tle tylko 2,9:1.
  • ecc zmienia wzór punktów, a nie zawartość. Wydrukowany kod nadal działa, jednak nie wolno mieszać starych i nowych plików do druku. Q lub H sprawiają, że kod jest bardziej odporny na uszkodzenia, na przykład na tekturze falistej. Logo zawsze wymusza H.
  • Z logo obszar za logo pozostaje biały, nawet przy kolorowym lub przezroczystym tle.
  • Buforowanie: Tylko rzeczywisty standardowy obraz (czarny na białym, korekcja błędów M, bez logo) jest dostarczany jako niezmienny przez 24 godziny; każde inne renderowanie przez 5 minut. W przypadku PDF i EPS każde podane tło liczy się jako odstępstwo: bg=ffffff rysuje tam białe wypełnienie, którego nie ma w pliku standardowym.
  • Plan taryfowy: Kolory i korekcja błędów są dostępne w każdym planie, również w bezpłatnym.
Okno terminala
# Dark blue code on white
curl "https://qr3.app/v1/codes/r7f3Kx/qr.svg?fg=1F4E79" -o qr-blue.svg
# Transparent PNG for a layout on a light surface
curl "https://qr3.app/v1/codes/r7f3Kx/qr.png?size=10&bg=transparent" -o qr-transparent.png
# More robust for corrugated board: error correction Q
curl "https://qr3.app/v1/codes/r7f3Kx/qr.pdf?ecc=Q" -o qr-q.pdf

Zapisywanie kolorów w kodzie

PATCH /v1/codes/:id zapisuje kolory jako appearance w kodzie. Ścieżki obrazów renderują je wtedy domyślnie, bez parametrów.

Okno terminala
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"}}'

Odpowiedź (HTTP 200, skrócona):

{
"data": {
"id": "qr_a1b2c3d4",
"short_code": "r7f3Kx",
"appearance": { "foreground_color": "#1F4E79", "background_color": null }
},
"meta": { "request_id": "req_xyz", "issues": [] }
}
  • Wartości: foreground_color jako #RRGGBB, background_color jako #RRGGBB lub transparent. Inne klucze powodują błąd 400.
  • Scalanie: Pominięte pole zachowuje swoją zapisaną wartość. null resetuje pole, "appearance": null oba. Czarny i biały nie są zapisywane; odpowiedź pokazuje je jako null.
  • Każda odpowiedź kodu zawiera appearance, podobnie jak webhooki qr.created i qr.updated.
  • Kolejność w ścieżkach obrazów: najpierw parametr, potem zapisany kolor, następnie domyślny. Dlatego ?fg=000000 zwraca czarny plik do druku dla kolorowego kodu.
  • Osadzone obrazy: Adres URL obrazu dopasowuje się do zapisanych kolorów, o ile sam nie określa ich za pomocą fg i bg: adres URL bez parametrów dla obu kolorów, ?fg=000000 dla tła, a ?ecc=Q również dla obu. Po zmianie kolorów strona, która osadza taki adres URL, może nadal wyświetlać stary obraz: do 24 godzin, jeśli adres URL do tego momentu zwracał standardowy obraz (czarny na białym, korekcja błędów M, bez logo), w przeciwnym razie do 5 minut. Rozwiązaniem jest dodanie do adresu URL własnego parametru, który zmienia się przy każdej zmianie koloru, np. ?v=2 lub updated_at kodu, tak jak w Dashboardzie. Ścieżki obrazów ignorują nieznane parametry.
  • Korekcja błędów nigdy nie jest zapisywana. Jest wybierana przy każdym pobieraniu za pomocą ?ecc=.
  • Tylko przez PATCH: POST /v1/codes, batch oraz import odrzucają appearance z błędem 422.
  • PDF i EPS rysują zapisane kolory jako kolory druku, dokładnie tak samo jak parametry. Ponieważ biel nigdy nie jest zapisywana, kod z zapisanym kolorem pierwszoplanowym otrzymuje tam białe wypełnienie, podobnie jak w SVG.

Weryfikacja kontrastu

API weryfikuje parę wynikającą z zapytania i zapisanej wartości:

PoziomKiedyOdpowiedź
blockedKontrast poniżej 1,5:1422, nic nie zostaje zapisane
criticalponiżej 2:1 lub różnica jasności poniżej 0,30; ostrzeżenie w połączeniu z logo; każde przezroczyste tło200 z meta.issues
warningponiżej 4:1 lub różnica jasności poniżej 0,50; jasne moduły na ciemnym tle200 z meta.issues
okwszystko inne200, meta.issues jest puste

Każdy wpis w meta.issues zawiera code, severity, field, message oraz opcjonalnie hints, takie jak contrast_ratio — ta sama forma, co komunikaty o zgodności cyfrowego paszportu produktu. Przezroczyste tło nigdy nie jest blokowane, ponieważ jasny kod na ciemnym opakowaniu to rzeczywisty przypadek użycia. Podłoże nadal wymaga jednak wyraźnego kontrastu oraz wolnej strefy ciszy o szerokości 4 modułów wokół kodu.

Przesyłanie i usuwanie logo (POST i DELETE /v1/codes/:id/logo) w ten sam sposób sprawdza zapisane kolory i również zwraca wyniki w meta.issues: z logo ostrzeżenie staje się critical, bez logo ponownie jest to tylko ostrzeżenie.

Jeśli inne zapytanie modyfikuje ten sam kod w tym samym momencie, API stosuje zmiany do najnowszego stanu. Dopiero gdy to nie powiedzie się trzy razy z rzędu, odpowiada błędem 409; klient musi wtedy ponownie załadować kod i powtórzyć zmianę.


Żądanie multipart, pole file: PNG, JPEG lub WebP, maksymalnie 1 MB, rozpoznawane na podstawie magic bytes. Normalizuje obraz do przezroczystego formatu 512×512-PNG i zastępuje istniejące logo.

Okno terminala
curl -X POST https://qr3.app/v1/codes/qr_a1b2c3d4/logo \
-H "Authorization: Bearer qr3_sk_..." \

Odpowiedź (HTTP 201): zaktualizowany kod z ustawionym logo_file_id.

Usuwa logo i kasuje zapisany obiekt. Idempotentne — wywołanie bez istniejącego logo nadal zwraca 200.

Jeśli inne zapytanie modyfikuje logo tego samego kodu w tym samym momencie (drugie przesłanie lub usunięcie), POST i DELETE /v1/codes/:id/logo odpowiadają błędem 409 (errors/conflict) i nic nie zmieniają; przesłany obraz jest odrzucany. Załaduj kod ponownie i spróbuj jeszcze raz. Dwa jednoczesne wywołania DELETE /v1/codes/:id/logo nie stanowią konfliktu; oba zwracają 200.

Jeśli jest ustawione, wszystkie cztery formaty — qr.svg, qr.png, qr.pdf i qr.eps — osadzają piksele logo i podnoszą poziom korekcji błędów do H. Pełna specyfikacja działania — w tym informacja o tym, która zmiana (dodanie/usunięcie vs. zastąpienie) modyfikuje wzór punktów — oraz wskazówki dotyczące druku znajdują się w sekcji Logo w kodzie QR.


Komentarze

Komentarze umożliwiają wymianę opinii (pętle informacji zwrotnej) między agencjami a klientami.

GET /v1/codes/:id/comments

POST /v1/codes/:id/comments

PATCH /v1/codes/:id/comments/:commentId

DELETE /v1/codes/:id/comments/:commentId

Komentarze utworzone w panelu (Dashboard) są przypisywane do tworzącego je użytkownika (author_id); komentarze utworzone za pomocą zwykłego klucza API pozostają nieprzypisane (author_id: null). Komentarz może usunąć wyłącznie jego autor lub org_admin/ws_admin — zwykłe klucze API mogą usuwać tylko nieprzypisane komentarze utworzone przez API.

Okno terminala
# Kommentar hinzufügen
curl -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 auflisten
curl "https://qr3.app/v1/codes/qr_a1b2c3d4/comments?resolved=false" \
-H "Authorization: Bearer qr3_sk_..."
# Kommentar als erledigt markieren
curl -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 }'