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/codesakceptuje wyłącznie typyurl,vcard,wifi,email,smsilocation. Pola są płaskie:url; co najmniejvcard_first_namelubvcard_last_name;wifi_ssid;email_to;sms_phone; albo obalocation_latilocation_lng.- Tylko kody
urlmogą być dynamiczne. Żądania utworzenia mogą opcjonalnie zawieraćexpires_atjako znacznik czasu ISO 8601;ab_enabled,ab_target_url_biab_weight_a(cele A/B) są dozwolone dla dynamicznych kodówurl;redirect_after_expirynie jest częścią kontraktu tworzenia. GET /v1/codesobsługuje tylkolimit,cursoristatus(live,paused,flagged,draft).POST /v1/codes/batchakceptujeurl,vcardiwifi. 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 jestskip_url_scan: true.
Tworzenie kodu 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,q1Odpowiedź (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
| Typ | Opis | Pola wymagane |
|---|---|---|
url | Adres URL strony internetowej (dynamiczny lub statyczny) | url |
vcard | Wizytówka (vCard 3.0) | vcard_first_name lub vcard_last_name |
wifi | Konfiguracja Wi-Fi | wifi_ssid |
email | E-mail (mailto:) | email_to |
sms | SMS | sms_phone |
location | Lokalizacja (geo:) | location_lat, location_lng |
Tworzenie masowe (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 }'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
curl https://qr3.app/v1/codes?status=live&limit=20 \ -H "Authorization: Bearer qr3_sk_..."Parametry zapytania (Query parameters):
| Parametr | Typ | Domyślnie | Opis |
|---|---|---|---|
cursor | string | — | Kursor do paginacji |
limit | integer | 20 | Wyniki na stronę (maks. 100) |
status | string | — | Filtr: live, paused, flagged, draft |
Pobieranie kodu QR
GET /v1/codes/:id
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.
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;
labelmusi mieć od 1 do 100 znaków;urlmusi zaczynać się odhttp(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.
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.
| Format | URL | Zastosowanie |
|---|---|---|
| SVG (wektorowy) | /v1/codes/:code/qr.svg | Web, skalowanie, cyfrowe |
| PNG (rastrowy) | /v1/codes/:code/qr.png | E-mail, prezentacje |
| PDF (wektorowy) | /v1/codes/:code/qr.pdf | Domyślnie: kwadratowy (tylko kod); ?format=a4 dla arkusza do druku |
| EPS (wektorowy) | /v1/codes/:code/qr.eps | Profesjonalne 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)
# 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.pdfKolory 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).
| Parametr | Wartości | Domyślnie | SVG, PNG | PDF, EPS |
|---|---|---|---|---|
fg | Hex RRGGBB lub RGB | 000000 | jest rysowany | jest rysowany jako kolor druku |
bg | Hex jak fg lub transparent | ffffff | jest rysowany | jest rysowany jako kolor druku |
ecc | L, M, Q, H | M | działa | dział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=lilazwraca kolor zapisany w kodzie, a jeśli nie zapisano żadnego, zwykłą czerń, z kodem200i nigdy błędem. Tylko wyraźne?fg=000000wymusza czerń. bg=transparentzwraca 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
1F4E79jako C74 M36 Y0 K53. Gdy tylko wybrany zostanie kolor, za kodem i jego cichą strefą umieszczane jest nieprzezroczyste tło, białe lub w kolorzebg, 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.
#1F4E79na białym tle ma stosunek 8,7:1, a#ff6600na białym tle tylko 2,9:1. ecczmienia wzór punktów, a nie zawartość. Wydrukowany kod nadal działa, jednak nie wolno mieszać starych i nowych plików do druku.QlubHsprawiają, że kod jest bardziej odporny na uszkodzenia, na przykład na tekturze falistej. Logo zawsze wymuszaH.- 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=ffffffrysuje 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.
# 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' });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.
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 noneOdpowiedź (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_colorjako#RRGGBB,background_colorjako#RRGGBBlubtransparent. Inne klucze powodują błąd400. - Scalanie: Pominięte pole zachowuje swoją zapisaną wartość.
nullresetuje pole,"appearance": nulloba. Czarny i biały nie są zapisywane; odpowiedź pokazuje je jakonull. - Każda odpowiedź kodu zawiera
appearance, podobnie jak webhookiqr.creatediqr.updated. - Kolejność w ścieżkach obrazów: najpierw parametr, potem zapisany kolor, następnie domyślny. Dlatego
?fg=000000zwraca 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ą
fgibg: adres URL bez parametrów dla obu kolorów,?fg=000000dla tła, a?ecc=Qró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=2lubupdated_atkodu, 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ąappearancez błędem422. - 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:
| Poziom | Kiedy | Odpowiedź |
|---|---|---|
blocked | Kontrast poniżej 1,5:1 | 422, nic nie zostaje zapisane |
critical | poniżej 2:1 lub różnica jasności poniżej 0,30; ostrzeżenie w połączeniu z logo; każde przezroczyste tło | 200 z meta.issues |
warning | poniżej 4:1 lub różnica jasności poniżej 0,50; jasne moduły na ciemnym tle | 200 z meta.issues |
| ok | wszystko inne | 200, 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ę.
Logo
POST /v1/codes/:id/logo
Żą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.
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.
DELETE /v1/codes/:id/logo
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.
# 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 }'