Abundera QR Pro API
Dokumentacja REST API dla pro.qr.abundera.ai. Tworzenie, edytowanie i analiza dynamicznych kodów QR w sposób programowy. Całość to JSON przez HTTPS, uwierzytelniony tokenem Bearer.
/docs/openapi.json, importuj do Postmana, Insomnii lub dowolnego klienta OpenAPI 3.1. Obejmuje 36 endpointów dla klientów: Kody, Analitykę, Grupy, Zespoły, Webhooki i Użytkowników. Endpointy administratora i webhooka Stripe są celowo wykluczone (tylko komunikacja między serwisami).Wprowadzenie
Abundera QR Pro API umożliwia programowe tworzenie, edytowanie i analizę dynamicznych kodów QR, wszystko, co deweloper chciałby zautomatyzować z panelu. Zarządzanie zespołem, rozliczenia i przepływy konta pozostają w interfejsie panelu; to API jest zakresem operacji na kodach na poziomie deweloperskim.
Podstawowy URL: https://pro.qr.abundera.ai/api
Format żądań: JSON (Content-Type: application/json) dla POST / PATCH / DELETE.
Format odpowiedzi: JSON (application/json; charset=utf-8).
Dostępność: Dostęp do API jest funkcją planu Business i wyższych. Plany Solo mogą korzystać z panelu, ale nie z API.
Uwierzytelnianie
Każde żądanie zawiera klucz API jako token Bearer:
Authorization: Bearer abnd_qrpro_...Tworzenie i unieważnianie kluczy odbywa się pod /account/keys (plan Business, Team lub Agency). Surowy token abnd_qrpro_... jest wyświetlany dokładnie raz podczas tworzenia, zapisz go natychmiast. Przechowujemy wyłącznie jego hash SHA-256; nie ma możliwości odzyskania utraconego klucza.
Żądania bez uwierzytelnienia zwracają 401 { "error": "not_signed_in" }. Nieprawidłowe lub unieważnione klucze zwracają 401 { "error": "invalid_api_key" }.
Klucze API są przypisane do użytkownika, który je utworzył. Jeśli ten użytkownik jest członkiem zespołu, poniższe endpointy automatycznie operują na kodach tego zespołu (kontekst bieżącego zespołu jest przechowywany na koncie użytkownika i zarządzany przez panel).
Limity zapytań
Egzekwowane per klucz API. Każda odpowiedź zawiera nagłówki X-RateLimit-Limit, X-RateLimit-Remaining i X-RateLimit-Reset (sekundy uniksowe, kiedy okno się resetuje).
| Plan | Limit | Okno |
|---|---|---|
| Business | 1 000 zapytań / dzień | Dzień UTC |
| Team | 10 000 zapytań / dzień | Dzień UTC |
| Agency | 50 000 zapytań / dzień | Dzień UTC |
| Solo | (403 insufficient_plan) | , |
Żądania przekraczające budżet zwracają 429 { "error": "rate_limited", "window": "day", "retry_at": 1234567890 } z nagłówkiem Retry-After w sekundach.
Skanowania nie są ograniczane, ścieżka przekierowań (aqr.net/{shortcode}) nie wymaga uwierzytelnienia i nie ma budżetu per skanowanie. Każdy plan ma jawny miesięczny limit skanowań (100 tys. / 1 mln / 10 mln / 30 mln). Po przekroczeniu limitu przekierowanie nadal działa; wysyłamy email, żebyś zdecydował, czy zaktualizować plan, czy przeczekać jednorazowy skok. Planujesz ponad ~10 mln skanowań dziennie? Napisz do nas, żebyśmy skoordynowali zasoby.
Błędy
Każda odpowiedź błędu to JSON z czytelnym maszynowo kodem error i, w stosownych przypadkach, dodatkowym kontekstem:
{ "error": "plan_limit", "plan": "business", "limit": 500, "current": 500 }| Status | Kod | Znaczenie |
|---|---|---|
| 400 | validation_error | Pole w treści nie przeszło walidacji. Odpowiedź zawiera field + message. |
| 401 | not_signed_in / invalid_api_key | Brakujący, nieprawidłowy lub unieważniony token Bearer. |
| 402 | plan_limit | Osiągnięto limit aktywnych i wstrzymanych kodów w twoim planie. Odpowiedź zawiera plan, limit, current. |
| 402 | plan_expired | Konto przekroczyło 90-dniowy okres karencji; zaktualizuj plan, żeby wznowić działanie. |
| 403 | insufficient_plan | Dostęp do API wymaga planu Business lub wyższego. Użytkownicy Solo napotykają ten błąd. |
| 403 | insufficient_role | Twoja rola w zespole nie pozwala na żądaną zmianę (wymagany admin lub wyżej). |
| 404 | not_found | Zasób nie istnieje lub nie jest widoczny w twoim zakresie. |
| 409 | code_not_editable | Kod ma status karencji lub wygasłego; reaktywuj go, żeby edytować. |
| 429 | rate_limited | Dzienny budżet planu przekroczony. Zob. Limity zapytań. |
| 500 | internal | Nieobsługiwany błąd serwera, napisz do wsparcia, jeśli da się odtworzyć. |
Kody
Dynamiczne kody QR: 7-znakowy skrót Base58, który przekierowuje przez aqr.net/{shortcode}. Każdy kod ma statyczny zapasowy QR do pobrania z panelu, jeśli kiedykolwiek przestaniesz płacić, wersja statyczna nadal działa bez przekierowania przez nasze serwery.
GET /api/codes
Lista wszystkich kodów w twoim bieżącym zakresie (osobistym lub zespołu, pod którym aktualnie działasz). Zwraca tablicę z podsumowaniem skanowań z 30 dni per kod.
$ curl -H "Authorization: Bearer abnd_qrpro_..." https://pro.qr.abundera.ai/api/codes
{
"codes": [
{ "id": "uuid", "shortcode": "aBc123x",
"url": "https://example.com/landing",
"label": "Q2 campaign", "tags": "q2,print",
"status": "active", "scans_30d": 1245,
"created_at": 1713288000, "updated_at": 1713370000 }
],
"plan": "business",
"plan_limit": 500,
"scope": { "type": "user" }
}POST /api/codes
Utwórz nowy kod dynamiczny. Limit aktywnych i wstrzymanych kodów twojego planu jest sprawdzany przed wstawieniem. Minimalna treść:
{ "url": "https://example.com/landing" }Pełna personalizacja (wszystko opcjonalne):
{ "url": "https://example.com/landing",
"label": "Spring campaign",
"tags": "q2,print",
"qr_type": "url",
"style_json": "{...}",
"logo_key": "instagram",
"frame_style": "scan-me",
"frame_text": "SCAN ME" }Zwraca 201 + utworzony rekord zawierający wygenerowany shortcode i short_url do druku.
GET /api/codes/{id}
Pobierz jeden kod. 404, jeśli nie należy do twojego zakresu.
PATCH /api/codes/{id}
Aktualizuj dowolne edytowalne pole. Najczęstsze użycie: zmiana docelowego URL już wydrukowanego kodu.
$ curl -X PATCH -H "Authorization: Bearer abnd_qrpro_..." -H "Content-Type: application/json" -d '{"url":"https://example.com/new-landing"}' https://pro.qr.abundera.ai/api/codes/uuidZmiany są propagowane do przekierowania w ciągu sekund. Prawidłowe wartości status dla PATCH: "active", "paused". Aby usunąć, użyj DELETE.
DELETE /api/codes/{id}
Miękkie usunięcie. Przejście do status=grace z grace_until = now + 90 days. Przekierowanie działa nadal przez cały okres karencji, to konkretna realizacja obietnicy cenowej bez uzależnienia. Po 90 dniach kod staje się expired, a przekierowanie zwraca 410 Gone.
POST /api/codes/import
Masowe tworzenie z tablicy (używane też przez przepływ „Zapisz do Pro" na qr.abundera.ai). Przyjmuje jeden kod lub tablicę. Limit planu jest sprawdzany raz przed całą partią.
Analityka
GET /api/codes/{id}/analytics
Parametry zapytania:
range=7d|30d|90d|1y|3y, ograniczone do retencji twojego planu (Solo 1 rok, Business 2 lata, Team/Agency 3 lata).granularity=day|hour, godzinowe tylko dla Team i Agency; maksymalne okno 7 dni dla godzinowych.
{
"range": "30d", "days": 30, "granularity": "day",
"total": 4321,
"timeseries": [
{ "bucket": "2026-04-01", "scans": 142 },
{ "bucket": "2026-04-02", "scans": 178 },
...
],
"by_country": [
{ "key": "US", "total": 3012 },
{ "key": "CA", "total": 402 },
{ "key": "Other", "total": 108 }
],
"by_device": [
{ "key": "mobile", "total": 3850 },
{ "key": "tablet", "total": 312 },
{ "key": "desktop", "total": 159 }
]
}Kraje z mniej niż 5 skanowaniami w oknie są grupowane w "Other" ze względów prywatności (zob. Model prywatności).
Klucze API
Tworzenie i unieważnianie kluczy odbywa się ze strony panelu /account/keys. Programowe samozarządzanie jest przez API tylko do odczytu, możesz wylistować klucze i je unieważnić, ale tworzenie nowego klucza wymaga panelu (kwestia jajka i kury: potrzebowałbyś klucza, żeby stworzyć klucz).
GET /api/keys
Lista twoich kluczy API. Nigdy nie zwraca surowego tokenu, tylko metadane.
{
"keys": [
{ "id": "uuid", "label": "Production server",
"created_at": 1713288000, "last_used_at": 1713370000 }
],
"allowed": true,
"plan": "business"
}DELETE /api/keys/{id}
Unieważnienie. Klucz przestaje działać natychmiast; każde żądanie go zawierające od tej chwili zwraca 401 invalid_api_key.
Eksport danych
GET /api/user/export
Pobierz archiwum ZIP zawierające pełny zestaw danych, codes.csv (każdy kod, w tym karencyjne i wygasłe), scans.csv (zagregowane dzienne zestawienie) i README.txt wyjaśniający format. Archiwum jest emitowane jako application/zip; przekieruj do pliku:
$ curl -H "Authorization: Bearer abnd_qrpro_..." -o abundera-qr-export.zip https://pro.qr.abundera.ai/api/user/exportReimportuj gdziekolwiek. To jest gwarancja przenośnego formatu, uzależnienie od dostawcy jest niemożliwe, jeśli jesteś właścicielem swoich danych.
Model prywatności
Agregat skanowań to cała historia prywatności. Co przechowujemy per skanowanie na ścieżce przekierowań:
code_id, który z twoich kodów został zeskanowanyday_bucket, data UTC (YYYY-MM-DD). Brak precyzji poniżej dnia w agregacie zwracanym tobie.country, ISO-3166-1 alfa-2 z nagłówka CloudflareCF-IPCountry. Bez miasta, bez regionu, bez wyszukiwania geo-IP.device_type,mobile/tablet/desktop/unknown, klasyfikowane na podstawie krótkiego wyrażenia regularnego User-Agent. Surowy ciąg UA jest odrzucany w momencie klasyfikacji.scan_count, licznik zagregowany, upsertowany przy każdym trafieniu.
Czego nie przechowujemy: adresów IP (hashowanych ani żadnych innych), surowych ciągów User-Agent, geolokalizacji na poziomie miasta, znaczników czasu poniżej dnia, refererów, ciasteczek, pikseli remarketingowych ani żadnego wektora identyfikującego jednostkę. Próg szumowy 5 tłumi małe agregaty przed re-identyfikacją.
Plany Team i Agency dodatkowo zapisują równoległy agregat godzinowy z hour_bucket (YYYY-MM-DD-HH UTC). Ten sam model prywatności, brak znaczników czasu poniżej godziny, ten sam próg szumowy, ten sam brak danych o indywidualnych skanujących.
Pełna historia: /manifesto/ i /no-lock-in/ na stronie bezpłatnego narzędzia.