Pular para o conteúdo

Experiments API

A Experiments API expõe os mesmos experimentos canary e shadow gerenciados no dashboard Zeus, atrás de um contrato estável. Três endpoints: listar, criar e fazer rollback.

Todos os endpoints de escrita exigem o header de segurança X-Floopy-Confirm: experiments. Esta é uma porta deliberada e de baixo custo (sem novo escopo de auth) que bloqueia abuso acidental e oportunista a partir de uma key vazada.

Autenticação e gating (todos os três endpoints)

Seção intitulada “Autenticação e gating (todos os três endpoints)”
Authorization: Bearer <your-floopy-api-key>
  • Permissão: read_permission para GET, write_permission para POST.
  • Plano: Apenas Pro (has_test_ab).
  • Atrás do kill switch de canary por organização.

Lista os experimentos da organização do chamador.

GET https://api.floopy.ai/v1/experiments
[
{
"id": "5b3f9c1e-7a2b-4c3d-9e1f-0a1b2c3d4e5f",
"type": "canary",
"status": "active",
"traffic_pct": 5,
"baseline": { "provider": "openai", "model": "gpt-5.4" },
"candidate": { "provider": "openai", "model": "gpt-5.4-mini" },
"started_at": "2026-05-04T09:00:00Z",
"ended_at": null,
"summary": null
}
]
FieldTypeDescription
idUUIDId do experimento.
typestringcanary ou shadow.
statusstringdraft, active, completed, ou rolled_back.
traffic_pctnumberPercentual de tráfego elegível direcionado ao candidato (0..=100).
baseline.provider, baseline.modelstringO lado de controle.
candidate.provider, candidate.modelstringO lado da variante.
started_atISO8601 | nullQuando o experimento foi ativado.
ended_atISO8601 | nullQuando o experimento terminou (ou sofreu rollback).
summaryobject | nullSumário agregado de qualidade e custo, populado após o fim do experimento.
StatusCodeQuando
403read_permission / plan_requiredPermissão ou flag de plano ausente.
5xxinternalFalha upstream.
Terminal window
curl -s -H "Authorization: Bearer $FLOOPY_API_KEY" \
"https://api.floopy.ai/v1/experiments" | jq .

Cria um novo experimento canary ou shadow. Limite do body: 8 KiB.

POST https://api.floopy.ai/v1/experiments
Authorization: Bearer <your-floopy-api-key>
Content-Type: application/json
X-Floopy-Confirm: experiments
{
"type": "canary",
"baseline": { "provider": "openai", "model": "gpt-5.4" },
"candidate": { "provider": "openai", "model": "gpt-5.4-mini" },
"traffic_pct": 5,
"stop_rule": { "max_regression": 0.02, "min_n": 200 }
}
FieldTypeRequiredConstraints
typestringYescanary ou shadow.
baseline.providerstringYesId de provider existente.
baseline.modelstringYesId de modelo existente.
candidate.providerstringYesId de provider existente. Deve diferir do par baseline.
candidate.modelstringYesId de modelo existente.
traffic_pctnumberYes0..=100.
stop_rule.max_regressionnumberNoTeto de queda da qualidade composta, [0, 0.5].
stop_rule.min_nintegerNoContagem mínima de amostras antes que o experimento possa completar.

O body é deny_unknown_fields — chaves desconhecidas retornam 400 invalid_body.

Retorna a linha criada, formato idêntico ao item do GET.

StatusCodeQuando
400missing_confirmationX-Floopy-Confirm: experiments ausente ou com valor errado.
400invalid_bodyFalha na validação de schema, ou chaves desconhecidas.
400invalid_traffic_pcttraffic_pct fora de [0, 100].
403write_permission / plan_requiredPermissão ou flag de plano ausente.
409active_already_existsJá existe um experimento ativo para o mesmo par (baseline, candidate).
429rate_limitedAcima do orçamento por organização.
5xxinternalFalha upstream.
Terminal window
curl -s -X POST \
-H "Authorization: Bearer $FLOOPY_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Floopy-Confirm: experiments" \
-d '{
"type": "canary",
"baseline": {"provider":"openai","model":"gpt-5.4"},
"candidate": {"provider":"openai","model":"gpt-5.4-mini"},
"traffic_pct": 5,
"stop_rule": {"max_regression": 0.02, "min_n": 200}
}' \
"https://api.floopy.ai/v1/experiments"

Força um experimento em execução de volta para sua baseline imediatamente.

POST https://api.floopy.ai/v1/experiments/{id}/rollback
Authorization: Bearer <your-floopy-api-key>
X-Floopy-Confirm: experiments

Sem request body.

Retorna a linha do experimento no estado rolled_back. Idempotente — chamar rollback em um experimento já revertido retorna 200 com a linha existente, e não 409.

StatusCodeQuando
400missing_confirmationHeader de confirmação ausente ou errado.
403write_permission / plan_requiredPermissão ou flag de plano ausente.
404not_foundNenhum experimento com esse id na organização do chamador. Bytes idênticos para consultas cross-tenant.
409completed_cannot_rollbackO experimento já está completed e não pode sofrer rollback.
5xxinternalFalha upstream.
Terminal window
EXP_ID="5b3f9c1e-7a2b-4c3d-9e1f-0a1b2c3d4e5f"
curl -s -X POST \
-H "Authorization: Bearer $FLOOPY_API_KEY" \
-H "X-Floopy-Confirm: experiments" \
"https://api.floopy.ai/v1/experiments/$EXP_ID/rollback" | jq .

Todo evento do ciclo de vida do experimento (created, started, rolled_back, completed, error) é persistido em routing_experiment_events com actor_api_key_id. Estes eventos aparecem no sidecar do export de decisões e na página de Experimentos do Zeus. O evento de auditoria experiment_rolled_back nunca sofre throttle — todo rollback produz uma linha.