Pular para o conteúdo

GET /analytics/events

API · v1 · Produção · Revisado em · Markdown

Eventos individuais autorizados e paginados. Contrato v1 · disponível em produção e homologação · operação getAnalyticsEvents. Guia funcional · Índice · Schemas · Testar em sandbox.

Permissão: analytics:read. Sessão humana ou chave de servidor limitada ao proprietário e aos aplicativos autorizados. OAuth/MCP ainda não estão disponíveis. Uma chave de exemplo deve incluir somente esta permissão e as leituras necessárias ao seu fluxo, restrita a app_loja; emita-a na área autenticada de desenvolvedores.

Disponível em produção e homologação; sujeito às capacidades do app e à configuração do provedor. OAuth só será aceito após B1b. Campos desconhecidos rejeitados. Consulte os ADRs para regras semânticas além do JSON Schema.

Consulta não altera o recurso. Downloads revalidam autorização e têm prazo/estado conforme o guia.

Nome Local Obrigatório Tipo e restrições
appId query sim AppId; {“type”:“string”,“maxLength”:200,“minLength”:1,“pattern”:“^[A-Za-z0-9][A-Za-z0-9._~-]*$”}
start query sim AnalyticsInstant; {“type”:“string”,“format”:“date-time”,“pattern”:“T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:[Zz]|[+-]\d{2}:\d{2})$”}
end query sim AnalyticsInstant; {“type”:“string”,“format”:“date-time”,“pattern”:“T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:[Zz]|[+-]\d{2}:\d{2})$”}
timezone query não string; {“type”:“string”,“default”:“America/Sao_Paulo”,“maxLength”:100}
group query não all / main / operational; {“enum”:[“all”,“main”,“operational”],“default”:“all”}
linkId query não LinkId; {“type”:“string”,“maxLength”:500,“pattern”:“^[a-z0-9.-]+-(?:(?!-)[A-Za-z0-9._-])*-(?:(?!-)[A-Za-z0-9._-])+$”}
domain query não Domain; {“type”:“string”,“maxLength”:253,“pattern”:“^(?:a-z0-9?\.)+a-z0-9?$”}
prefix query não string; {“type”:“string”,“maxLength”:200}
campaignId query não string; {“type”:“string”,“format”:“uuid”}
folderId query não string; {“type”:“string”,“format”:“uuid”}
tagId query não string; {“type”:“string”,“format”:“uuid”}
device query não android / ios / desktop / unknown; {“enum”:[“android”,“ios”,“desktop”,“unknown”]}
source query não string; {“type”:“string”,“maxLength”:200}
country query não string; {“type”:“string”,“maxLength”:7}
eventType query não all / click / app_open / content_view / legacy_content_load; {“enum”:[“all”,“click”,“app_open”,“content_view”,“legacy_content_load”],“default”:“click”}
limit query não integer; {“type”:“integer”,“minimum”:1,“maximum”:100,“default”:50}
cursor query não Cursor; {“type”:“string”,“maxLength”:2048,“pattern”:“^c1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$”}

Paginação por cursor assinado; preserve credencial, concessão, filtros, ordem e limite. Cursor expira em 15 minutos. A lista mutável não fornece snapshot. Use pagination.nextCursor até hasMore=false.

Sem corpo. Envie os parâmetros na URL e os headers indicados.

Omitir campos opcionais usa o default documentado ou preserva o valor em PATCH. null só é aceito nos campos cujo schema permite null, com efeito de limpar/desvincular indicado no guia. Arrays enviados substituem a coleção quando o endpoint define atualização completa; não implicam merge. Identificadores/owner/app de um recurso existente não são transferidos por PATCH. Herança de templates/UTMs segue o guia, sem alterar links anteriores por cópia automática.

AGILINK_API_KEY deve ficar no servidor. Os placeholders abaixo são fictícios. Preserve Idempotency-Key e payload ao repetir uma intenção após timeout.

Janela do terminal
curl --request GET 'https://api.staging.agilink.io/v1/analytics/events?appId=app_loja&start=2026-10-01T00%3A00%3A00Z&end=2026-10-02T00%3A00%3A00Z' \
--header 'Authorization: Bearer <credencial>'
// Node.js 22+. Defina AGILINK_API_KEY no ambiente do servidor.
const response = await fetch('https://api.staging.agilink.io/v1/analytics/events?appId=app_loja&start=2026-10-01T00%3A00%3A00Z&end=2026-10-02T00%3A00%3A00Z', {
method: 'GET',
headers: {
"Authorization": `Bearer ${process.env.AGILINK_API_KEY}`
},
redirect: 'error', signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error('HTTP '+response.status+' requestId='+response.headers.get('X-Request-Id'));
const result = await response.json();
console.log(result);
# Python 3.10+; pip install requests
import os
import requests
headers = {
"Authorization": "Bearer " + os.environ["AGILINK_API_KEY"]
}
response = requests.request(
'GET', 'https://api.staging.agilink.io/v1/analytics/events?appId=app_loja&start=2026-10-01T00%3A00%3A00Z&end=2026-10-02T00%3A00%3A00Z',
headers=headers,
timeout=30, allow_redirects=False)
if not 200 <= response.status_code < 300:
raise RuntimeError(f'HTTP {response.status_code}; requestId={response.headers.get("X-Request-Id")}')
result = response.json()
print(result)

Sucesso. Exemplo fictício.

Header Significado Exemplo
X-Request-Id Identificador gerado pelo servidor, inclusive para falhas e replays. conforme resposta
Cache-Control Respostas administrativas não podem ser armazenadas. no-store, no-transform
{
"data": {
"appId": "app_loja",
"period": {
"start": "2026-10-01T00:00:00Z",
"end": "2026-10-02T00:00:00Z",
"timezone": "America/Sao_Paulo",
"startInclusive": true,
"endExclusive": true
},
"filters": {
"campaignId": null,
"folderId": null,
"tagId": null,
"group": "all",
"linkId": null,
"domain": null,
"prefix": null,
"device": null,
"source": null,
"country": null,
"eventType": "all"
},
"generatedAt": "2026-10-02T12:00:00Z",
"coverage": {
"source": "event_rows",
"grouping": "current_link_group",
"deletedLinks": "excluded",
"historicalAggregates": "not_merged",
"uniqueVisitors": "distinct_click_hash_estimate",
"nativeTrust": "client_reported",
"completenessGuaranteed": false,
"limitations": [
"Totais calculados das linhas disponíveis; agregados históricos não são somados.",
"Abertura não comprova instalação."
]
},
"events": [
{
"id": "80000000-0000-4000-8000-000000000001",
"appId": "app_loja",
"linkId": "go.example.com~-ofertas~-tenis",
"type": "click",
"producer": "worker",
"trust": "worker_observed",
"occurredAt": "2026-10-01T01:00:00Z",
"receivedAt": "2026-10-01T01:00:00Z",
"device": "android",
"source": "direct",
"country": "BR",
"entryMethod": "unknown",
"openId": null,
"parentEventId": null
}
]
},
"pagination": {
"hasMore": false,
"nextCursor": null
},
"meta": {
"requestId": "req_00000000000040008000000000000001"
}
}
Campo Tipo Obrigatório Significado e limites
data AnalyticsEvents sim Resultado tipado da operação.
data.appId AppId sim Aplicativo proprietário; precisa estar autorizado.
data.period AnalyticsPeriod sim Valor tipado; formato e restrições completos no schema abaixo.
data.period.start AnalyticsInstant sim Valor tipado; formato e restrições completos no schema abaixo.
data.period.end AnalyticsInstant sim Valor tipado; formato e restrições completos no schema abaixo.
data.period.timezone string sim Valor tipado; formato e restrições completos no schema abaixo. Até 100 caracteres
data.period.startInclusive objeto sim Valor tipado; formato e restrições completos no schema abaixo.
data.period.endExclusive objeto sim Valor tipado; formato e restrições completos no schema abaixo.
data.filters AnalyticsFilters sim Valor tipado; formato e restrições completos no schema abaixo.
data.filters.campaignId string ou null sim Valor tipado; formato e restrições completos no schema abaixo.
data.filters.folderId string ou null sim Valor tipado; formato e restrições completos no schema abaixo.
data.filters.tagId string ou null sim Valor tipado; formato e restrições completos no schema abaixo.
data.filters.group all / main / operational sim Grupo main/operational; diferente de pasta/campanha.
data.filters.linkId LinkId ou null sim Identidade composta do link.
data.filters.domain Domain ou null sim Hostname, sem protocolo ou caminho.
data.filters.prefix string ou null sim Prefixo de caminho, sem barras.
data.filters.device android / ios / desktop / unknown ou null sim Valor tipado; formato e restrições completos no schema abaixo.
data.filters.source string ou null sim Valor tipado; formato e restrições completos no schema abaixo.
data.filters.country string ou null sim Valor tipado; formato e restrições completos no schema abaixo.
data.filters.eventType all / click / app_open / content_view / legacy_content_load sim Valor tipado; formato e restrições completos no schema abaixo.
data.generatedAt string sim Valor tipado; formato e restrições completos no schema abaixo. date-time
data.coverage AnalyticsCoverage sim Valor tipado; formato e restrições completos no schema abaixo.
data.coverage.source event_rows / retained_recovery_tokens sim Valor tipado; formato e restrições completos no schema abaixo.
data.coverage.grouping objeto sim Valor tipado; formato e restrições completos no schema abaixo.
data.coverage.deletedLinks objeto sim Valor tipado; formato e restrições completos no schema abaixo.
data.coverage.historicalAggregates objeto sim Valor tipado; formato e restrições completos no schema abaixo.
data.coverage.uniqueVisitors objeto sim Valor tipado; formato e restrições completos no schema abaixo.
data.coverage.nativeTrust objeto sim Valor tipado; formato e restrições completos no schema abaixo.
data.coverage.completenessGuaranteed objeto sim Valor tipado; formato e restrições completos no schema abaixo.
data.coverage.limitations array sim Valor tipado; formato e restrições completos no schema abaixo. Até 1000 itens
data.events array sim Valor tipado; formato e restrições completos no schema abaixo. Até 1000 itens
data.events[].id OpaqueId sim Identificador estável do recurso.
data.events[].appId AppId sim Aplicativo proprietário; precisa estar autorizado.
data.events[].linkId LinkId sim Identidade composta do link.
data.events[].type click / app_open / content_view / legacy_content_load sim Valor tipado; formato e restrições completos no schema abaixo.
data.events[].producer legacy_unknown / worker / flutter_sdk / pilot_legacy sim Valor tipado; formato e restrições completos no schema abaixo.
data.events[].trust worker_observed / client_reported / legacy_unknown sim Valor tipado; formato e restrições completos no schema abaixo.
data.events[].occurredAt string sim Valor tipado; formato e restrições completos no schema abaixo. date-time
data.events[].receivedAt string ou null sim Valor tipado; formato e restrições completos no schema abaixo.
data.events[].device string sim Valor tipado; formato e restrições completos no schema abaixo. Até 7 caracteres
data.events[].source string sim Valor tipado; formato e restrições completos no schema abaixo. Até 200 caracteres
data.events[].country string sim Valor tipado; formato e restrições completos no schema abaixo. Até 7 caracteres
data.events[].entryMethod string sim Valor tipado; formato e restrições completos no schema abaixo. Até 200 caracteres
data.events[].openId string ou null sim Valor tipado; formato e restrições completos no schema abaixo.
data.events[].parentEventId OpaqueId ou null sim Valor tipado; formato e restrições completos no schema abaixo.
pagination Pagination sim Continuação da lista; não é snapshot.
pagination.nextCursor Cursor ou null sim Cursor assinado; conserve filtros, credencial e limite.
pagination.hasMore boolean sim Indica se há continuação.
meta Meta sim Correlação e informações da resposta.
meta.requestId RequestId sim Identificador de correlação gerado pelo servidor.

Respeite Retry-After quando existir. Leituras podem ser repetidas após falhas transitórias. Não faça retry automático ilimitado.

Status Significado
400 Cabeçalho, query, cursor ou JSON inválido.
401 Credencial inválida, expirada ou revogada.
403 Operação sem permissão ou capacidade desabilitada.
404 Recurso inexistente ou fora dos aplicativos autorizados.
422 JSON bem formado com dados de domínio inválidos.
429 Quota excedida. Respeitar Retry-After.
500 Falha interna. Use requestId para diagnóstico.
503 Dependência indisponível; resultado da mutação pode ser incerto.
{
"error": {
"code": "unauthenticated",
"message": "Credencial inválida, expirada ou revogada.",
"requestId": "req_00000000000040008000000000000001",
"documentationUrl": "https://docs.agilink.io/api/errors/#unauthenticated"
}
}
{
"error": {
"code": "insufficient_permission",
"message": "Operação sem permissão ou capacidade desabilitada.",
"requestId": "req_00000000000040008000000000000001",
"documentationUrl": "https://docs.agilink.io/api/errors/#insufficient-permission"
}
}
{
"error": {
"code": "rate_limited",
"message": "Quota excedida. Respeitar Retry-After.",
"requestId": "req_00000000000040008000000000000001",
"documentationUrl": "https://docs.agilink.io/api/errors/#rate-limited"
}
}
Schema de request
{
"description": "Sem corpo"
}
Schema de response
{
"type": "object",
"additionalProperties": false,
"properties": {
"data": {
"$ref": "#/components/schemas/AnalyticsEvents"
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
},
"meta": {
"$ref": "#/components/schemas/Meta"
}
},
"required": [
"data",
"pagination",
"meta"
]
}

Convenções e limites · Erros · Receitas completas · Guia funcional.