GET /v1/export/decisions
Faça streaming de cada decisão de uma janela como JSON-Lines (NDJSON), uma linha por linha, terminado por uma única linha de trailer inline que carrega um checksum SHA-256 sobre o body. Projetado como o “matador de lock-in”: você pode sair a qualquer momento, com todos os dados que a Floopy usou para otimizar em seu nome.
Endpoint
Seção intitulada “Endpoint”GET https://api.floopy.ai/v1/export/decisionsAutenticação
Seção intitulada “Autenticação”Authorization: Bearer <your-floopy-api-key>- Permissão:
read_permission. - Flag de plano:
has_audit_apieplan_features.log_retention_days >= 30. Disponível nos planos Pro e Enterprise. - Atrás do kill switch de canary por organização.
Query parameters
Seção intitulada “Query parameters”| Field | Type | Required | Constraints | Default |
|---|---|---|---|---|
from | ISO8601 | Yes | Início inclusivo. | — |
to | ISO8601 | Yes | Fim inclusivo. to - from ≤ 90 dias. | — |
format | string | No | Atualmente apenas jsonl. Qualquer outro valor retorna 415. | jsonl |
Uma checagem pré-execução de contagem estimada de linhas rejeita exports cujo conjunto de resultados excederia floopy_export_max_rows (default 5_000_000) com 400 estimated_payload_too_large.
Resposta (200)
Seção intitulada “Resposta (200)”Content-Type: application/x-ndjson- Um objeto JSON por linha, formato idêntico a
GET /v1/decisions/{request_id}(com a projeção fixaEXPORT_FIELDS— bodies nunca são exportados). - A última linha é um trailer JSONL inline que carrega metadados de integridade e agregação.
Quando qualquer decisão na janela teve used_shared_pool_prior == true, a resposta também carrega:
Floopy-Aggregation-Notice: contains-shared-pool-influenced-decisionsIsso é uma dica — o sinal autoritativo vive no campo aggregation_signal_present do trailer.
Linha do trailer
Seção intitulada “Linha do trailer”A última linha do stream é o trailer. Ela é detectada pela chave marcadora literal _floopy_export_trailer: true.
{ "_floopy_export_trailer": true, "outcome": "completed", "row_count": 12345, "byte_count": 18234567, "checksum_sha256": "5f4dcc3b5aa765d61d8327deb882cf99b8adb1c1d2c95b4f9e2c3a4d5e6f7a8b", "aggregation_signal_present": false}| Field | Type | Description |
|---|---|---|
_floopy_export_trailer | boolean | Sempre true. Use esta chave como marcador para a linha do trailer. |
outcome | string | completed, deadline_exceeded, error, ou client_disconnect. |
row_count | integer | Número de linhas de dados enviadas antes do trailer. |
byte_count | integer | Número de bytes do body enviados antes do trailer (apenas linhas de dados). |
checksum_sha256 | hex string | SHA-256 sobre os bytes do body que precedem o trailer (cada linha de dado incluindo seu \n terminador). |
aggregation_signal_present | boolean | true se pelo menos uma linha carregou used_shared_pool_prior == true. |
O checksum é calculado sobre os bytes do body descomprimidos excluindo a própria linha do trailer. Um mismatch no lado do consumidor indica uma transferência truncada ou corrupção em trânsito.
Verificando o trailer
Seção intitulada “Verificando o trailer”Um consumidor pode verificar a integridade localmente separando a linha do trailer, recalculando o SHA-256 sobre o restante e comparando.
RESPONSE=$(curl -s \ -H "Authorization: Bearer $FLOOPY_API_KEY" \ "https://api.floopy.ai/v1/export/decisions?from=$FROM&to=$TO")
# The trailer is the last line containing the marker key.TRAILER_LINE=$(echo "$RESPONSE" | tail -n 1)BODY=$(echo "$RESPONSE" | sed '$d') # all but the last line
CLAIMED=$(echo "$TRAILER_LINE" | jq -r '.checksum_sha256')COMPUTED=$(printf '%s\n' "$BODY" | shasum -a 256 | awk '{print $1}')
if [ "$CLAIMED" = "$COMPUTED" ]; then echo "OK"else echo "TAMPERED — claimed=$CLAIMED computed=$COMPUTED" exit 1fi
echo "outcome=$(echo "$TRAILER_LINE" | jq -r '.outcome') rows=$(echo "$TRAILER_LINE" | jq -r '.row_count')"Notas:
- No Linux substitua
shasum -a 256porsha256sum. - O gateway termina cada linha de dado com
\n, eprintf '%s\n're-anexa um único newline final para que o recálculo combine com o que o gateway hashou. - Se o
outcomedo trailer fordeadline_exceeded,error, ouclient_disconnect, o export foi interrompido. O checksum continua válido para o body efetivamente entregue, mas o dataset está incompleto; reemita a requisição com uma janela mais estreita.
| Status | error code | Quando |
|---|---|---|
400 | invalid_range | from/to ausentes, ou from >= to. |
400 | range_too_wide | to - from > 90 days. |
400 | estimated_payload_too_large | A estimativa pré-execução de linhas excede floopy_export_max_rows. |
403 | plan_required (feature: "audit_api" ou "audit_api_retention") | O plano não tem a flag ou não atinge o piso de retenção de 30 dias. |
404 | not_found | Kill switch desligado para esta organização, ou endpoint não montado. Bytes idênticos por design. |
415 | unsupported_format | format diferente de jsonl. |
429 | export_in_progress | Outro export já está em execução para esta organização; carrega retry_after_seconds e Retry-After. |
5xx | internal | Falha upstream. |
Exemplo curl
Seção intitulada “Exemplo curl”FROM="2026-04-01T00:00:00Z"TO="2026-05-01T00:00:00Z"curl -s -H "Authorization: Bearer $FLOOPY_API_KEY" \ "https://api.floopy.ai/v1/export/decisions?from=$FROM&to=$TO" \ > decisions.jsonltail -n 1 decisions.jsonl | jq .Limites e comportamento
Seção intitulada “Limites e comportamento”- Um export concorrente por organização. A próxima chamada retorna
429 export_in_progressaté o export em andamento finalizar (ou o deadline de 30 minutos disparar). - Deadline de tempo de parede de 30 minutos. Quando disparado, o trailer carrega
outcome: "deadline_exceeded". A linha do log de auditoria registraaborted_quota. - Projeção fixa de campos. Exports usam uma allowlist fixa de colunas — bodies (
request_body,response_body) nunca são exportados. - Um único start a cada 5 minutos por organização além do lock, para manter a taxa de início limitada.
Veja também
Seção intitulada “Veja também”- GET /v1/decisions — listagem paginada para janelas mais estreitas.
- Metodologia de Confidence.
- Metodologia Baseline-vs-Floopy.