Abundera QR Pro/ Documentation

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.

Dernière mise à jour : 2026-04-18 · support@abundera.ai · Spec OpenAPI 3.1 (JSON) · SDKs officiels (TS / Python / Go)

Spec lisible par machine :/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).

PlanLimiteFenêtre
Business1 000 requêtes / jourJour UTC
Team10 000 requêtes / jourJour UTC
Agency50 000 requêtes / jourJour 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 }
StatutCodeSignification
400validation_errorChamp du corps invalide. La réponse inclut field + message.
401not_signed_in / invalid_api_keyBearer token manquant, invalide ou révoqué.
402plan_limitPlafond de codes actifs+en pause atteint. La réponse inclut plan, limit, current.
402plan_expiredLe compte a dépassé la fenêtre de grâce de 90 jours ; mettez à niveau pour reprendre.
403insufficient_planL'accès API nécessite Business ou supérieur. Les utilisateurs Solo reçoivent cette erreur.
403insufficient_roleVotre rôle dans l'équipe ne permet pas cette mutation (admin+ requis).
404not_foundLa ressource n'existe pas, ou n'est pas visible dans votre périmètre.
409code_not_editableLe code est en statut grâce ou expiré ; réactivez-le pour le modifier.
429rate_limitedBudget quotidien du plan dépassé. Voir Limites de débit.
500internalErreur 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/uuid

Les 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/export

Ré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 header CF-IPCountry de 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.