Abundera QR Pro/ Documentation

API Abundera QR Pro

Referência da REST API em pro.qr.abundera.ai. Crie, edite e analise QR codes dinâmicos via código. Tudo é JSON sobre HTTPS, autenticado via bearer token.

Última atualização: 2026-04-18 · support@abundera.ai · OpenAPI 3.1 spec (JSON) · Official SDKs (TS / Python / Go)

Spec legível por máquina:/docs/openapi.json, importe no Postman, Insomnia ou qualquer cliente OpenAPI 3.1. Cobre 36 endpoints voltados ao cliente em Códigos, Analytics, Grupos, Times, Webhooks e Usuário. Endpoints admin + webhook Stripe são excluídos intencionalmente (somente service-to-service).

Introdução

A API do Abundera QR Pro permite criar, editar e analisar QR codes dinâmicos via código, tudo que um desenvolvedor quer automatizar a partir do painel. Gerenciamento de times, cobrança e fluxos de conta ficam na interface do painel; esta API é voltada a operações de código para desenvolvedores.

URL base: https://pro.qr.abundera.ai/api

Formato da requisição: JSON (Content-Type: application/json) on POST / PATCH / DELETE.

Formato da resposta: JSON (application/json; charset=utf-8).

Disponibilidade: Acesso à API é um recurso Business+. Planos Solo podem usar o painel, mas não a API.

Autenticação

Cada requisição carrega uma chave de API como bearer token:

Authorization: Bearer abnd_qrpro_...

Crie e revogue chaves em /account/keys (planos Business, Team ou Agency). O token bruto abnd_qrpro_... é exibido apenas uma vez na criação, guarde-o imediatamente. Armazenamos apenas seu hash SHA-256; não há como recuperar uma chave perdida.

Requisições não autenticadas retornam 401 { "error": "not_signed_in" }. Chaves inválidas ou revogadas retornam 401 { "error": "invalid_api_key" }.

As chaves de API têm escopo do usuário que as criou. Se esse usuário for membro de um time, os endpoints abaixo operam nos códigos do time automaticamente (o contexto do time atual é armazenado na conta do usuário e gerenciado pelo painel).

Limites de taxa

Aplicados por chave de API. Cada resposta traz X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (segundos Unix quando a janela se renova).

PlanoLimiteJanela
Business1.000 requisições / diadia UTC
Team10.000 requisições / diadia UTC
Agency50.000 requisições / diadia UTC
Solo(403 insufficient_plan),

Requisições acima do limite retornam 429 { "error": "rate_limited", "window": "day", "retry_at": 1234567890 } com um cabeçalho Retry-After em segundos.

Scans não têm limite de taxa, o caminho de redirecionamento (aqr.net/{shortcode}) não tem autenticação nem orçamento por scan. Cada plano tem um limite mensal explícito de scans (100k / 1M / 10M / 30M). Ao ultrapassar o limite, o redirecionamento continua funcionando; enviamos um e-mail para você decidir se quer fazer upgrade ou absorver um pico pontual. Planejando mais de ~10M de scans diários? Fale conosco para coordenar capacidade.

Erros

Toda resposta de erro é JSON com um código error legível por máquina e, quando relevante, contexto adicional:

{ "error": "plan_limit", "plan": "business", "limit": 500, "current": 500 }
StatusCódigoSignificado
400validation_errorCampo do body falhou na validação. A resposta inclui field + message.
401not_signed_in / invalid_api_keyBearer token ausente, inválido ou revogado.
402plan_limitNo limite de códigos ativos+pausados do seu plano. A resposta inclui plan, limit, current.
402plan_expiredA conta ultrapassou o período de carência de 90 dias; faça upgrade para retomar.
403insufficient_planAcesso à API requer Business ou superior. Usuários Solo recebem este erro.
403insufficient_roleSeu papel no time não permite a mutação solicitada (admin+ necessário).
404not_foundO recurso não existe ou não está visível no seu escopo.
409code_not_editableO código está em status de carência ou expirado; reative para editar.
429rate_limitedPer-plan daily budget exceeded. See Limites de taxa.
500internalErro de servidor não tratado, envie e-mail ao suporte se for reproduzível.

Códigos

QR codes dinâmicos: um shortcode Base58 de 7 caracteres que redireciona por aqr.net/{shortcode}. Cada código tem um QR de backup estático que você pode baixar pelo painel, se parar de pagar, a versão estática continua funcionando sem depender do nosso redirecionamento.

GET /api/codes

Lista todos os códigos no seu escopo atual (pessoal ou o time em que você está atuando). Retorna um array com o rollup de scans dos últimos 30 dias por código.

$ 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

Cria um novo código dinâmico. O limite de códigos ativos+pausados do seu plano é verificado antes do insert. Body mínimo:

{ "url": "https://example.com/landing" }

Personalização completa (todos opcionais):

{ "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" }

Retorna 201 + a linha criada incluindo o shortcode gerado e o short_url que você imprime.

GET /api/codes/{id}

Busca um único código. 404 se não estiver no seu escopo.

PATCH /api/codes/{id}

Atualiza qualquer campo mutável. O uso mais comum: alterar a URL de destino de um código já impresso.

$ 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

As alterações se propagam ao redirecionamento em segundos. Valores válidos de status para PATCH: "active", "paused". Para excluir, use DELETE.

DELETE /api/codes/{id}

Exclusão suave. Transita para status=grace com grace_until = now + 90 dias. O redirecionamento continua funcionando por todo o período de carência, esta é a promessa concreta de preço sem lock-in. Após 90 dias o código fica expired e o redirecionamento retorna 410 Gone.

POST /api/codes/import

Criação em lote a partir de um array (também usado pelo fluxo "Salvar no Pro" em qr.abundera.ai). Aceita um único payload de código ou um array. O limite do plano é verificado uma vez antes do lote.

Analytics

GET /api/codes/{id}/analytics

Parâmetros de query:

  • range=7d|30d|90d|1y|3y, limitado à retenção do seu plano (Solo 1y, Business 2y, Team/Agency 3y).
  • granularity=day|hour, granularidade por hora é exclusiva de Team e Agency; janela máxima de 7 dias para hourly.
{
  "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 }
  ]
}

Countries with fewer than 5 scans in the window are folded into "Other" for privacy (see Modelo de privacidade).

Chaves de API

Crie e revogue chaves na página /account/keys do painel. O auto-gerenciamento programático é somente leitura via API, você pode listar e revogar suas chaves, mas criar uma nova chave requer o painel (ovo e galinha: você precisaria de uma chave para criar outra).

GET /api/keys

Lista suas chaves de API. Nunca retorna o token bruto, apenas metadados.

{
  "keys": [
    { "id": "uuid", "label": "Production server",
      "created_at": 1713288000, "last_used_at": 1713370000 }
  ],
  "allowed": true,
  "plan": "business"
}

DELETE /api/keys/{id}

Revoga a chave. Ela para de funcionar imediatamente; qualquer requisição que a use retorna 401 invalid_api_key a partir daí.

Exportação de dados

GET /api/user/export

Baixa um ZIP com seu conjunto de dados completo, codes.csv (todos os códigos, incluindo carência + expirados), scans.csv (rollup diário agregado), e um README.txt explicando o formato. O arquivo é emitido como application/zip; redirecione para um arquivo:

$ curl -H "Authorization: Bearer abnd_qrpro_..." \
       -o abundera-qr-export.zip \
       https://pro.qr.abundera.ai/api/user/export

Reimporte em qualquer lugar. Esta é a garantia de formato portátil, não há lock-in possível se você possui seus dados.

Modelo de privacidade

O agregado de scans é toda a história de privacidade. O que armazenamos por scan no caminho de redirecionamento:

  • code_id, qual dos seus códigos foi escaneado
  • day_bucket, data UTC (YYYY-MM-DD). Sem precisão sub-dia no agregado retornado para você.
  • country, ISO-3166-1 alpha-2 do cabeçalho CF-IPCountry do Cloudflare. Sem cidade, sem região, sem lookup geo-IP.
  • device_type, mobile / tablet / desktop / unknown, classificado por uma regex curta de User-Agent. A string UA bruta é descartada na classificação.
  • scan_count, contador agregado, atualizado por upsert a cada hit.

O que não armazenamos: endereços IP (hashed ou não), strings User-Agent brutas, geo em nível de cidade, timestamps sub-dia, referer, cookies, pixels de retargeting ou qualquer vetor de identificação individual. Um piso de ruído de 5 suprime a re-identificação por agregados pequenos.

Os planos Team e Agency escrevem adicionalmente um agregado por hora paralelo com hour_bucket (YYYY-MM-DD-HH UTC). Mesmo modelo de privacidade, sem timestamps mais finos que uma hora, mesmo piso de ruído, mesma ausência de dados individuais do usuário.

Leia a história completa: /manifesto/ e /no-lock-in/ no site da ferramenta gratuita.