Pular para o conteúdo
Entrar Começar

GET /v1/experiments/{id}/results

Le os resultados agregados de um unico experimento de roteamento. O endpoint roda duas agregacoes sobre o log de requisicoes — uma para o lado baseline do experimento, outra para o lado candidate — limitados ao tempo de vida do experimento, e retorna agregados de custo, qualidade e latencia mais os deltas entre eles.

E a API por tras da pagina de detalhe de experimento no dashboard Floopy, incluindo o loop de polling usado pelo passo “shadow-setup” do onboarding.

GET https://api.floopy.ai/v1/experiments/{id}/results
Authorization: Bearer <sua-chave-floopy>
  • Permissao: read_permission.
  • Apenas plano Pro.
  • Estamos liberando esse endpoint por organizacao enquanto validamos a qualidade. Fale com o suporte caso sua organizacao ainda nao esteja habilitada.
CampoTipoObrigatorioRestricoes
idstring (UUID v4)SimO id do experimento. Validado como UUID v4 no extractor de path; entrada invalida retorna 400 invalid_experiment_id e nenhuma chamada ao banco e feita.

Uma chamada bem-sucedida primeiro busca o registro do experimento com escopo na organizacao do chamador. Se o experimento nao pertence a org do chamador, a resposta e 404 com bytes identicos a um experimento inexistente; a camada de analytics nao e consultada.

A janela de agregacao e limitada pelo tempo de vida do experimento, nao por um parametro window fornecido pelo cliente:

  • Limite inferior (sempre aplicado): request_created_at >= experiment.started_at.
  • Limite superior (somente quando o experimento nao esta mais active): request_created_at <= experiment.ended_at.

Para um experimento active, o limite superior e aberto — toda nova requisicao que o experimento ve entra na proxima leitura. Para um experimento completed ou rolled_back, a janela esta congelada em [started_at, ended_at].

Isso significa que dois polls consecutivos do mesmo experimento podem retornar numeros diferentes se o experimento ainda esta ativo e ha trafego entrando.

{
"experiment_id": "5b3f9c1e-7a2b-4c3d-9e1f-0a1b2c3d4e5f",
"type": "shadow",
"status": "active",
"started_at": "2026-05-01T09:00:00Z",
"ended_at": null,
"baseline": {
"samples": 9412,
"avg_cost_micro_usd": 412,
"composite_quality": 0.812,
"p50_latency_ms": 612
},
"candidate": {
"samples": 9412,
"avg_cost_micro_usd": 226,
"composite_quality": 0.804,
"p50_latency_ms": 588
},
"delta": {
"cost_pct": -45.1,
"quality_abs": -0.008,
"p50_latency_ms": -24
}
}
CampoTipoDescricao
experiment_idUUIDEcoa o id do path.
typestringcanary ou shadow.
statusstringdraft, active, completed ou rolled_back.
started_atISO8601 | nullQuando o experimento foi ativado. Limite inferior da janela de agregacao.
ended_atISO8601 | nullQuando o experimento terminou. Limite superior quando presente; null para experimentos ativos.
baselineobjectAgregado sobre o (provider, model) baseline do experimento dentro da janela.
candidateobjectAgregado sobre o (provider, model) candidate do experimento na mesma janela.
delta.cost_pctnumber(candidate − baseline) / baseline * 100. Negativo significa que o candidato e mais barato.
delta.quality_absnumbercandidate − baseline na qualidade composta em [0.0, 1.0].
delta.p50_latency_msnumbercandidate − baseline na latencia p50 em milissegundos.

Para um experimento shadow, as linhas do candidate sao pontuadas em paralelo com o trafego baseline ao vivo; a resposta visivel ao usuario sempre vem da baseline. Para um experimento canary, ambos os lados servem trafego real em proporcao ao traffic_pct.

Quando nenhum dos lados acumulou linhas ainda (experimento recem-ativado), os blocos baseline e candidate retornam zeros; delta e omitido.

O endpoint armazena a resposta em Redis por (organization_id, experiment_id) durante 30 segundos. Nao ha cabecalho Cache-Control ecoado — o cache e interno ao gateway.

Um TTL de 30 segundos e curto o suficiente para que UIs movidas a polling (o passo de shadow-setup do onboarding faz polling a cada 20 s) vejam numeros frescos o bastante, e longo o suficiente para que a camada de analytics nao seja consultada a cada render.

StatusCodigo errorQuando
400invalid_experiment_idO id do path nao e UUID v4 valido. Nenhuma chamada ao banco e feita.
403read_permissionA chave nao tem read_permission.
403plan_requiredO endpoint nao esta incluido no plano do chamador.
404not_foundNao existe registro de experimento na org do chamador para esse id. Bytes identicos a um lookup cross-tenant.
429rate_limitedExcedeu 60 req/min/org ou 20 req/min/chave. Carrega Retry-After.
503upstream_timeoutA agregacao de analytics excedeu o timeout de 5 s.
5xxinternalFalha upstream.
Terminal window
curl -s -H "Authorization: Bearer $FLOOPY_API_KEY" \
"https://api.floopy.ai/v1/experiments/5b3f9c1e-7a2b-4c3d-9e1f-0a1b2c3d4e5f/results" | jq .
  • 60 requisicoes / minuto / organizacao.
  • 20 requisicoes / minuto / chave de API.

Ambas as janelas sao avaliadas atomicamente. O loop de polling do dashboard respeita esses caps espacando requisicoes a 20 s nos primeiros 10 minutos e 60 s depois, e pausando completamente enquanto a aba do browser esta oculta.

Toda resposta bem-sucedida grava um evento experiment_results_read no log de auditoria, throttled por (organization_id, key_id, experiment_id) durante 60 segundos.