Abundera QR Pro API
Référence REST API pour pro.qr.abundera.ai. Créez, modifiez et analysez des QR codes dynamiques par programmation. Tout repose sur JSON via HTTPS, authentifié par bearer token.
/docs/openapi.json, à importer dans Postman, Insomnia ou tout client OpenAPI 3.1. Couvre 36 endpoints clients sur Codes, Analytics, Groups, Teams, Webhooks et User. Les endpoints Admin et Stripe-webhook sont intentionnellement exclus (service-to-service uniquement).Introduction
L'API Abundera QR Pro vous permet de créer, modifier et analyser des QR codes dynamiques par programmation, tout ce qu'un développeur veut automatiser depuis le tableau de bord. La gestion d'équipe, la facturation et les flux de compte restent dans l'UI du tableau de bord ; cette API est limitée aux opérations de codes destinées aux développeurs.
URL de base : https://pro.qr.abundera.ai/api
Format des requêtes : JSON (Content-Type: application/json) sur POST / PATCH / DELETE.
Format des réponses : JSON (application/json; charset=utf-8).
Disponibilité : L'accès API est une fonctionnalité Business+. Les plans Solo peuvent utiliser le tableau de bord, mais pas l'API.
Authentification
Chaque requête porte une clé API en tant que bearer token :
Authorization: Bearer abnd_qrpro_...Créez et révoquez des clés sur /account/keys (niveau Business, Team ou Agency). Le token brut abnd_qrpro_... n'est affiché qu'une seule fois à la création, enregistrez-le immédiatement. Nous ne stockons que son hash SHA-256 ; il est impossible de récupérer une clé perdue.
Les requêtes non authentifiées renvoient 401 { "error": "not_signed_in" }. Les clés invalides ou révoquées renvoient 401 { "error": "invalid_api_key" }.
Les clés API sont limitées à l'utilisateur qui les a créées. Si cet utilisateur est membre d'une équipe, les endpoints ci-dessous opèrent automatiquement sur les codes de l'équipe (le contexte d'équipe actuel est stocké sur le compte utilisateur et géré via le tableau de bord).
Limites de débit
Appliquées par clé API. Chaque réponse inclut X-RateLimit-Limit, X-RateLimit-Remaining et X-RateLimit-Reset (horodatage unix de réinitialisation de la fenêtre).
| Plan | Limite | Fenêtre |
|---|---|---|
| Business | 1 000 requêtes / jour | Jour UTC |
| Team | 10 000 requêtes / jour | Jour UTC |
| Agency | 50 000 requêtes / jour | Jour UTC |
| Solo | (403 insufficient_plan) | , |
Les requêtes dépassant le budget renvoient 429 { "error": "rate_limited", "window": "day", "retry_at": 1234567890 } avec un header Retry-After en secondes.
Les scans ne sont pas limités en débit, le chemin de redirection (aqr.net/{shortcode}) n'a pas d'authentification ni de budget par scan. Chaque plan a un plafond mensuel de scans (100k / 1M / 10M / 30M). Si ce plafond est dépassé, la redirection continue de fonctionner ; nous vous envoyons un email pour que vous puissiez décider de monter en plan ou de traverser un pic ponctuel. Si vous prévoyez plus de ~10M de scans quotidiens, contactez-nous pour coordonner la capacité.
Erreurs
Chaque réponse d'erreur est du JSON avec un code error lisible par machine et, si pertinent, du contexte supplémentaire :
{ "error": "plan_limit", "plan": "business", "limit": 500, "current": 500 }| Statut | Code | Signification |
|---|---|---|
| 400 | validation_error | Champ du corps invalide. La réponse inclut field + message. |
| 401 | not_signed_in / invalid_api_key | Bearer token manquant, invalide ou révoqué. |
| 402 | plan_limit | Plafond de codes actifs+en pause atteint. La réponse inclut plan, limit, current. |
| 402 | plan_expired | Le compte a dépassé la fenêtre de grâce de 90 jours ; mettez à niveau pour reprendre. |
| 403 | insufficient_plan | L'accès API nécessite Business ou supérieur. Les utilisateurs Solo reçoivent cette erreur. |
| 403 | insufficient_role | Votre rôle dans l'équipe ne permet pas cette mutation (admin+ requis). |
| 404 | not_found | La ressource n'existe pas, ou n'est pas visible dans votre périmètre. |
| 409 | code_not_editable | Le code est en statut grâce ou expiré ; réactivez-le pour le modifier. |
| 429 | rate_limited | Budget quotidien du plan dépassé. Voir Limites de débit. |
| 500 | internal | Erreur serveur non gérée, contactez le support si elle est reproductible. |
Codes
QR codes dynamiques : un shortcode Base58 de 7 caractères qui redirige via aqr.net/{shortcode}. Chaque code dispose d'un QR de backup statique téléchargeable depuis le tableau de bord, si vous cessez de payer, la version statique continue de fonctionner sans toucher à notre redirection.
GET /api/codes
Liste tous les codes dans votre périmètre actuel (personnel, ou l'équipe sous laquelle vous agissez). Renvoie un tableau avec un récapitulatif de scans sur 30 jours par code.
$ 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
Crée un nouveau code dynamique. Le plafond de codes actifs+en pause de votre plan est vérifié avant l'insertion. Corps minimal :
{ "url": "https://example.com/landing" }Personnalisation complète (tout optionnel) :
{ "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" }Renvoie 201 + la ligne créée incluant le shortcode généré et le short_url à imprimer.
GET /api/codes/{id}
Récupère un code unique. 404 s'il n'est pas dans votre périmètre.
PATCH /api/codes/{id}
Met à jour n'importe quel champ modifiable. Utilisation la plus courante : changer l'URL de destination d'un code déjà imprimé.
$ 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/uuidLes modifications se propagent à la redirection en quelques secondes. Valeurs status valides pour PATCH : "active", "paused". Pour supprimer, utilisez DELETE.
DELETE /api/codes/{id}
Suppression douce. Passe en status=grace avec grace_until = maintenant + 90 jours. La redirection continue de fonctionner pendant toute la fenêtre de grâce, c'est la promesse de tarification sans verrouillage rendue concrète. Après 90 jours, le code devient expired et la redirection renvoie 410 Gone.
POST /api/codes/import
Création en masse depuis un tableau (également utilisé par le flux "Enregistrer dans Pro" sur qr.abundera.ai). Accepte un seul code ou un tableau. Le plafond du plan est vérifié une fois avant le traitement.
Analytics
GET /api/codes/{id}/analytics
Paramètres de requête :
range=7d|30d|90d|1y|3y, limité à la rétention de votre plan (Solo 1an, Business 2ans, Team/Agency 3ans).granularity=day|hour, la granularité horaire est réservée à Team et Agency ; fenêtre max de 7 jours pour l'horaire.
{
"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 }
]
}Les pays avec moins de 5 scans dans la fenêtre sont regroupés dans "Other" pour la confidentialité (voir Modèle de confidentialité).
Clés API
Créez et révoquez des clés depuis la page /account/keys du tableau de bord. La gestion programmatique est en lecture seule via l'API, vous pouvez lister vos clés et les révoquer, mais la création d'une nouvelle clé nécessite le tableau de bord (problème de l'œuf et de la poule : il vous faudrait une clé pour en créer une).
GET /api/keys
Liste vos clés API. Ne renvoie jamais le token brut, uniquement les métadonnées.
{
"keys": [
{ "id": "uuid", "label": "Production server",
"created_at": 1713288000, "last_used_at": 1713370000 }
],
"allowed": true,
"plan": "business"
}DELETE /api/keys/{id}
Révocation. La clé cesse de fonctionner immédiatement ; toute requête la portant renvoie ensuite 401 invalid_api_key.
Export de données
GET /api/user/export
Télécharge un ZIP contenant votre jeu de données complet, codes.csv (tous les codes, y compris grâce + expirés), scans.csv (récapitulatif quotidien agrégé) et un README.txt expliquant le format. L'archive est émise en application/zip ; redirigez-la vers un fichier :
$ curl -H "Authorization: Bearer abnd_qrpro_..." -o abundera-qr-export.zip https://pro.qr.abundera.ai/api/user/exportRéimportez n'importe où. C'est la garantie du format portable, aucun verrouillage n'est possible si vous possédez vos données.
Modèle de confidentialité
L'agrégat de scans est toute la politique de confidentialité. Ce que nous stockons par scan sur le chemin de redirection :
code_id, lequel de vos codes a été scannéday_bucket, date UTC (YYYY-MM-DD). Pas de précision infra-journalière sur l'agrégat renvoyé.country, ISO-3166-1 alpha-2 depuis le headerCF-IPCountryde Cloudflare. Pas de ville, pas de région, pas de géolocalisation IP.device_type,mobile/tablet/desktop/unknown, classifié par une courte regex User-Agent. La chaîne UA brute est supprimée lors de la classification.scan_count, compteur agrégé, mis à jour à chaque hit.
Ce que nous ne stockons pas : adresses IP (hachées ou non), chaînes User-Agent brutes, géolocalisation au niveau ville, horodatages infra-journaliers, referer, cookies, pixels de reciblage ou tout vecteur d'identification individuelle. Un plancher de bruit à 5 supprime la ré-identification à partir de petits agrégats.
Les niveaux Team et Agency écrivent en plus un agrégat horaire parallèle avec hour_bucket (YYYY-MM-DD-HH UTC). Même modèle de confidentialité, pas d'horodatage plus fin qu'une heure, même plancher de bruit, même absence de données sur le scanner individuel.
Lisez la présentation complète : /manifesto/ et /no-lock-in/ sur le site du Free Tool.