Leia suas métricas pela API, MCP e webhooks
Leia cliques e leituras com GET /analytics e GET /events, peça-os pelo servidor MCP da CodeQR e receba os webhooks link.clicked e qrcode.scanned.

Ao final deste guia você consegue ler no seu próprio código os mesmos números que vê no Analytics — totais, série temporal, detalhamentos, top links, UTM —, listar eventos individuais, pedir tudo isso a um assistente de IA pelo servidor MCP e receber um webhook a cada clique ou leitura.
Disponibilidade
- Plano:
GET /analyticsem todos os planos, dentro da janela de período do plano (Free 30 dias, Starter 90, Pro 1 ano, Business+ sem limite).GET /eventsa partir do Pro. Webhookslink.clickedeqrcode.scanneda partir do Business. - Onde:
https://api.codeqr.io/analyticsehttps://api.codeqr.io/eventscom uma chave criada em Configurações → Chaves de API (escopoanalytics.read); o servidor MCP emhttps://mcp.codeqr.io/mcp; webhooks em Configurações → Webhooks. Referência completa dos campos: Retrieve analytics e Retrieve a list of events em docs.codeqr.io.
Antes de começar
- Autentique com
Authorization: Bearer <chave de API>. As chaves são por workspace; o workspace fica implícito. - Os agregados ficam em cache de dois a dez minutos, como no painel. Não consulte com mais frequência que isso.
- IDs:
linkIdeqrcodeIdsão os camposiddevolvidos por/linkse/qrcodes; você também pode endereçar um link pordomain+key+type=link(outype=qrcode). - Os exemplos abaixo rodaram num workspace real em 17/08/2026; só o domínio foi trocado por
go.example.com.
Passos
- Contagem.
GET https://api.codeqr.io/analytics?event=composite&groupBy=count&interval=24h&linkId=cmsxdw1ww0001ulo2n1new0ne
{"clicks":9,"scans":0,"views":0,"leads":0,"sales":0,"saleAmount":0}event é clicks, scans, views, leads, sales ou composite (todos os campos preenchidos). Sem linkId a mesma chamada devolve os totais do workspace.
- Série temporal.
GET https://api.codeqr.io/analytics?event=clicks&groupBy=timeseries&interval=24h&timezone=America/Sao_Paulo&linkId=cmsxdw1ww0001ulo2n1new0nedevolve um objeto por intervalo (por hora em24h, por dia em7de30d, por mês a partir de90d), cada um comstartnotimezonepedido:
[{"start":"2026-08-17T15:00:00.000+0000","clicks":9,"scans":0,"views":0,"leads":0,"sales":0,"saleAmount":0}]- Detalhamentos. Troque
groupByporcountries,cities,continents,devices,browsers,os,referers,referer_urls,top_links,top_qrcodes,top_urls(exigelinkId) ouutm_sources,utm_mediums,utm_campaigns,utm_contents,utm_terms:
GET /analytics?event=clicks&groupBy=referers&interval=24h&linkId=cmsxdw1ww0001ulo2n1new0ne
[{"referer":"(direct)","clicks":7,"leads":0,"sales":0,"saleAmount":0},{"referer":"mail.google.com","clicks":1,"leads":0,"sales":0,"saleAmount":0},{"referer":"instagram.com","clicks":1,"leads":0,"sales":0,"saleAmount":0}]
GET /analytics?event=clicks&groupBy=top_links&interval=24h
[{"link":"cmsxdw1ww0001ulo2n1new0ne","id":"cmsxdw1ww0001ulo2n1new0ne","domain":"go.example.com","key":"docs-analytics-utm","shortLink":"https://go.example.com/docs-analytics-utm","url":"https://example.com/newsletter?utm_source=newsletter&utm_medium=email&utm_campaign=august-2026","createdAt":"2026-08-17T15:23:49.808Z","clicks":9,"leads":0},{"link":"cmsxdw3qk0003bhs7k6msb5og","id":"cmsxdw3qk0003bhs7k6msb5og","domain":"go.example.com","key":"docs-analytics-plain","shortLink":"https://go.example.com/docs-analytics-plain","url":"https://example.com/promo","createdAt":"2026-08-17T15:23:52.172Z","clicks":2,"leads":0}]
GET /analytics?event=clicks&groupBy=utm_sources&interval=24h&linkId=cmsxdw1ww0001ulo2n1new0ne
[{"utm_source":"newsletter","clicks":9}]Os detalhamentos somam cliques, leituras e visitas a páginas; acrescente types=link, types=qrcode ou types=page para ficar com um tipo. Eles são devolvidos em todos os planos (o app desfoca alguns cartões, a API não).
- Filtros e períodos. Qualquer um de
domain,key,linkId,qrcodeId,tagIds,folderId,country,city,continent,device,browser,referer,url,utm_source…utm_termrestringe o resultado;intervalé24h,7d,30d,90d,ytd,1youall, ou enviestarteend(ISO 8601;endnão pode estar no futuro) comtimezone. Exemplo:GET /analytics?event=clicks&groupBy=count&interval=24h&country=BR&device=Mobile. - Eventos.
GET https://api.codeqr.io/events?event=clicks&interval=24h&linkId=cmsxdw1ww0001ulo2n1new0ne&limit=3(Pro e acima) devolve um objeto por clique, do mais recente para o mais antigo;pageelimit(padrão 100) paginam,order=ascinverte:
[{"event":"click","timestamp":"Mon Aug 17 2026 15:27:57 GMT+0000 (Coordinated Universal Time)","click":{"id":"iPjJ1eT6yjCB1mGw","url":"https://example.com/newsletter?utm_source=newsletter&utm_medium=email&utm_campaign=august-2026","continent":"SA","country":"BR","city":"Carnaíba","device":"Mobile","browser":"Mobile Safari","os":"iOS","referer":"mail.google.com","refererUrl":"","type":"link","ip":""},"link":{"id":"cmsxdw1ww0001ulo2n1new0ne","domain":"go.example.com","key":"docs-analytics-utm","url":"https://example.com/newsletter?utm_source=newsletter&utm_medium=email&utm_campaign=august-2026","shortLink":"https://go.example.com/docs-analytics-utm","clicks":9,"leads":0,"sales":0,"saleAmount":0,"lastClicked":"2026-08-17T15:27:57.000Z","createdAt":"2026-08-17T15:23:49.808Z","utm_source":"newsletter","utm_medium":"email","utm_campaign":"august-2026","publicStats":true,"tags":[]},"click_id":"iPjJ1eT6yjCB1mGw","link_id":"cmsxdw1ww0001ulo2n1new0ne","domain":"go.example.com","key":"docs-analytics-utm","url":"https://example.com/newsletter?utm_source=newsletter&utm_medium=email&utm_campaign=august-2026","continent":"SA","country":"BR","city":"Carnaíba","device":"Mobile","browser":"Mobile Safari","os":"iOS","type":"link","ip":""}]click.type é link, qrcode ou page; click.ip fica sempre vazio. Use types=qrcode para listar só leituras. event=leads e event=sales listam eventos de conversão quando o rastreamento de conversão está ligado.
- Erros que você vai encontrar.
400invalid_enum_value: interval: Invalid enum value. Expected '1h' | '24h' | '7d' | '30d' | '90d' | 'ytd' | '1y' | 'all' | 'all_unfiltered', received '2d';400custom: end: The end date cannot be in future.;403You can only get analytics for up to 30 days on a free plan. Upgrade to Starter, Pro, or Business to get analytics for longer periods.(e os equivalentes de Starter/Pro);403No permission: You need a higher plan.em/eventsabaixo do Pro;404Link not found.
O mesmo pelo servidor MCP
Conecte seu cliente de IA a https://mcp.codeqr.io/mcp (OAuth 2.0). Peça, por exemplo:
Quantas leituras meus QR codes tiveram nos últimos 7 dias, por país?
O cliente chama get_analytics com { "event": "scans", "groupBy": "countries", "interval": "7d" } e lê o JSON acima. get_analytics aceita event (clicks, scans, leads, sales, composite), groupBy (count, timeseries, countries, cities, devices, browsers, os, referers, top_links, top_qrcodes, top_urls) e, opcionalmente, linkId, qrcodeId, domain + key e interval (padrão 24h). start/end personalizados, timezone e os filtros de tag/país/dispositivo são só da API. A janela do plano vale: um workspace Free pedindo 1y recebe o 403 acima.
Webhooks e automações
- Webhooks: em Configurações → Webhooks, crie um endpoint e escolha o gatilho.
link.clickedeqrcode.scanned(epage.visited) são escolhidos por link, QR code ou página e estão disponíveis a partir do Business; os outros gatilhos (link.created,lead.created,sale.created, …) valem para o workspace todo a partir do Pro. Uma entrega delink.clickedé{ "id": "evt_…", "event": "link.clicked", "createdAt": "…", "data": { "eventName": "Link clicked", "interaction": { "timestamp", "click_id", "link_id", "url", "country", "city", "device", "browser", "os", "referer", "referer_url", "type", … }, "link": { … } } }— leia o clique emdata.interaction. O botão de enviar evento de teste ainda manda uma amostra antiga comdata.click; entregas reais usamdata.interaction. Assinatura e novas tentativas: docs.codeqr.io/concepts/webhooks/introduction. - Google Sheets: a receita com Pluga em Como registrar informações automaticamente em planilhas escreve uma linha por evento a partir de um webhook.
- Make e Zapier: o Zapier lista
link.clickedcomo gatilho (semqrcode.scanned); o Make não tem gatilho de clique — agende um módulo HTTP que chameGET /analytics?…&groupBy=count&interval=24hdiariamente e escreva o resultado onde precisar. - SDK:
npm install @codeqr/tse depoisconst client = new CodeQR({ token: process.env.CODEQR_API_KEY }); const totals = await client.analytics.retrieve({ event: 'composite', groupBy: 'count', interval: '30d' });
Confira se funciona
curl -s "https://api.codeqr.io/analytics?event=composite&groupBy=count&interval=24h" \
-H "Authorization: Bearer $CODEQR_API_KEY"
# {"clicks":68,"scans":16,"views":3,"leads":1,"sales":0,"saleAmount":0}Abra um dos seus links no celular, espere dois ou três minutos e rode a chamada de novo com &linkId=<id>: clicks é 1.
Solução de problemas
groupBy=top_urls devolve uma lista vazia
top_urls precisa de um link específico: acrescente linkId ou domain + key + type=link.
qrcodeId em /events devolve cliques de link
/events filtra só por link. Use types=qrcode para listar leituras e depois leia link_id / key em cada linha.
A resposta é 403 com uma mensagem de upgrade
O interval (ou start) é mais antigo que a janela do seu plano. Use um período menor ou faça upgrade; a mensagem diz qual plano abre o período.
A contagem é menor que a do painel
Confira event: clicks sozinho exclui leituras e visitas; o Total do painel é event=composite somado. Compare também o mesmo timezone e a mesma janela.