---
title: Integrar organização, QR e ciclo de vida
description: Contratos A4a, associação, revisão, regras e QR binário.
---

As [29 operações deste marco](/api/endpoints-a4a/) estão na API isolada `https://api.staging.agilink.io/v1`. A referência interativa contém os schemas completos. [Leia primeiro a semântica do produto](/produto/organizacao/).

## Criar e associar

Crie `/tags`, `/folders` ou `/campaigns` com `appId` e `name`. Campanha aceita `utm` com as cinco chaves documentadas. Tags/pastas não aceitam UTMs não vazias. Metadados incluem descrição e arquivamento. Listagem tem `appId`, `q`, `archived=all|true|false`, `limit` e cursor assinado. Atualizações/exclusões exigem ETag forte e UUID v4 de idempotência. Nomes duplicados e remoção com associações retornam 409.

`PATCH /links/{linkId}` aceita `folderId`, `campaignId`, `utm` e `lifecycle`, junto dos campos existentes. As associações usam UUID, ou null para retirar. `utm` substitui o objeto anterior; `{}` limpa. Não há cópia implícita de UTMs por associação: consulte a campanha e envie a cópia no patch. `lifecycle` substitui o objeto completo:

```json
{"lifecycle":{"archived":false,"paused":false,"startsAt":"2026-12-01T12:00:00Z","expiresAt":"2027-01-01T00:00:00Z","fallbackUrl":null}}
```

`PUT /links/{linkId}/tags` substitui `tagIds`, até vinte UUIDs únicos, usando a revisão do link. `PUT /links/{linkId}/routing-rules` substitui `rules`, até dez regras com IDs únicos e estáveis dentro do link. Ordem é prioridade; campos e exemplos em cada operação. A revisão devolvida é a nova revisão do link, compartilhada com patch/tags/regras/template. Duplicação de link pela operação existente copia campos básicos; organização, disponibilidade, regras e UTMs começam independentes e precisam ser atribuídas explicitamente.

Regras e lifecycle são validados por schema, URLs HTTPS sem credenciais e intervalo início < fim. Persistência e associações são transacionais; outbox no mesmo commit. O histórico tem paginação assinada e campos sanitizados. Excluir um app exige remover suas coleções/configurações dependentes; o histórico administrativo é eliminado com o app.

## Buscar e medir

`GET /links` acrescenta `folderId`, `campaignId`, `tagId`, `state=active|paused|scheduled|expired` e `archived=true|false`. Sem filtros, inclui todos. `GET /campaigns/{campaignId}/links` pagina os links da associação atual. Analytics de eventos aceita `campaignId`, `folderId`, `tagId` e mantém o contrato de período/timezone do A3c. `/analytics/campaigns/{campaignId}` retorna o mesmo resumo de eventos para aquela campanha. Recovery de tokens não aceita esses filtros e não é somado ao relatório de campanha.

A chave com `analytics:read` pode consultar a campanha do app concedido, sem obter seus metadados. Chaves de tags/QR precisam das permissões específicas, sem ganho implícito de `links:update`. Filtros não ampliam o app autorizado. Redução/revogação da credencial é revalidada.

## QR binário

`GET /links/{linkId}/qr?format=png|svg` gera um QR sem persistir. Pode receber `size`, `margin`, `errorCorrectionLevel`, `dark`, `light`, respeitando o schema `QrStyle`. Default: 512px, quatro módulos, M, azul escuro sobre branco. `POST /qr-codes` salva `appId`, `linkId`, `name` e opcionalmente o estilo completo. Vínculo é imutável. `GET /qr-codes/{qrId}/download?format=svg` usa o estilo salvo. PNG e SVG são corpos binários com Content-Type e Content-Disposition; não existe envelope JSON nesses downloads. Erros seguem o envelope administrativo, inclusive 422 para densidade/tamanho incompatível.

```sh
curl 'https://api.staging.agilink.io/v1/qr-codes/90000000-0000-4000-8000-000000000002/download?format=png' \
  --header 'Authorization: Bearer <credencial>' --output agilink-qr.png
```

Nenhum download gera clique, nem busca/baixa destino ou imagem externa. O gerador usa [node-qrcode](https://github.com/soldair/node-qrcode), versão fixada, sem logo externo. QR salvo impede excluir seu link. Excluir configuração de QR usa revisão/idempotência e retorna 204; imagens já distribuídas continuam válidas.

## Painel isolado

A página `/platform` é carregada separadamente e usa sessão Auth própria do staging. Defina a tríade pública `VITE_PLATFORM_API_URL`, `VITE_PLATFORM_AUTH_URL`, `VITE_PLATFORM_PUBLIC_KEY` com os destinos exatos do staging descritos no runbook; nunca service role. O menu aparece somente nessa configuração. Para trabalhar isolado do dashboard produtivo, use `npm run dev:platform-staging --prefix dashboard`: entrada própria, sem providers ou chamadas de dados produtivos. O servidor local usa um proxy fixo para a API de staging; não é necessário ampliar o CORS remoto. Builds continuam apontando diretamente ao host HTTPS permitido do staging. Não reutiliza o JWT produtivo do dashboard. Em produção, use https://developers.agilink.io/platform com a conta existente autorizada. A sessão fica em memória e é independente do painel principal. O painel mantém UUID da intenção em memória quando o resultado fica incerto; repetir os mesmos valores na mesma sessão reutiliza o recibo. Após recarregar a página, consulte o estado antes de tentar novamente.

Campos desconhecidos, queries repetidas e permissões insuficientes são rejeitados. Para 412, consulte o item e reaplique a intenção na revisão atual. Para timeout/503, preserve corpo/If-Match/chave; consulte publicação. Veja [erros e repetição](/api/errors/).
