GET /v1/optimization/verification
This endpoint answers one question on the caller’s own traffic, with their own numbers: does Floopy actually verify the savings story for this route, in the last 7 days? It is the API behind the dashboard’s Verification Status card on the Baseline-vs-Floopy page.
The answer is one of four states — verified, not_verified, insufficient_data, regression_detected — derived from a tenant-scoped aggregation over your request log, with the underlying baseline and floopy numbers returned alongside so you can audit the verdict.
Endpoint
Section titled “Endpoint”GET https://api.floopy.ai/v1/optimization/verification?route_id=<uuid>&window=7dAuthentication
Section titled “Authentication”Authorization: Bearer <your-floopy-api-key>- Permission:
read_permission. - Available on all plans.
- Our team is currently rolling this endpoint out gradually and validating data quality before broad availability — contact support for early access.
Query parameters
Section titled “Query parameters”| Field | Type | Required | Constraints |
|---|---|---|---|
route_id | string (UUID v4) | Yes | The id of the route whose performance you want to verify. Validated as a v4 UUID at the deserializer; malformed input returns 400 invalid_route_id. |
window | string | Yes | Closed enum: 7d. v2 ships with a single fixed window; other windows are explicitly out of scope. |
A successful call pre-fetches the route configuration scoped by the caller’s organization. If the route does not belong to the caller’s org, the response is 404 with bytes identical to a non-existent route; the analytics store is not queried.
Response (200)
Section titled “Response (200)”{ "route_id": "5b3f9c1e-7a2b-4c3d-9e1f-0a1b2c3d4e5f", "window": "7d", "status": "verified", "baseline": { "samples": 4218, "avg_cost_micro_usd": 412, "composite_quality": 0.812, "p50_latency_ms": 612 }, "floopy": { "samples": 17392, "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 }}Field reference
Section titled “Field reference”| Field | Type | Description |
|---|---|---|
route_id | UUID | Echoes the route_id query parameter. |
window | string | Echoes the window query parameter (always 7d in v2). |
status | string | Closed enum: verified, not_verified, insufficient_data, regression_detected. See Verification status methodology. |
baseline.samples | integer | Number of fallback (non-Floopy) requests on the route in the window. Counted from request-log rows where fallback_used = 1 and routing_rule_id = route_id. |
baseline.avg_cost_micro_usd | number | Mean cost_micro_usd over baseline.samples. |
baseline.composite_quality | number | Mean composite quality score in [0.0, 1.0] over the same rows. |
baseline.p50_latency_ms | number | Median end-to-end latency in milliseconds. |
floopy.samples | integer | Number of Floopy-routed requests on the route in the window. Counted where fallback_used = 0 and the routing strategy is one of the Floopy strategies (closed allowlist: feedback_driven, smart_cost, weighted, round_robin, latency_based). |
floopy.avg_cost_micro_usd | number | Mean cost over floopy.samples. |
floopy.composite_quality | number | Mean composite quality in [0.0, 1.0]. |
floopy.p50_latency_ms | number | Median latency. |
delta.cost_pct | number | Percentage change in cost: (floopy − baseline) / baseline * 100. Negative means Floopy is cheaper. |
delta.quality_abs | number | Absolute change in composite quality: floopy − baseline. Negative means Floopy is lower-quality. |
delta.p50_latency_ms | number | Absolute change in p50 latency in milliseconds. |
When status == "insufficient_data", the baseline and floopy blocks are still populated with whatever was observed, but delta is omitted because the comparison is not meaningful below the sample floor.
When status == "regression_detected", the response is populated normally; the verdict is set by the bucketed regression signal from /v1/decisions over the same window, not by the cost/quality numbers in this response.
Status semantics
Section titled “Status semantics”| Status | When |
|---|---|
verified | Both panels meet samples >= SAMPLE_FLOOR (100), no recent regressions on the route, and (baseline.composite_quality − floopy.composite_quality) <= QUALITY_TOLERANCE (0.03). |
not_verified | Both panels meet the sample floor, no regressions, but Floopy quality is below baseline quality by more than QUALITY_TOLERANCE. |
insufficient_data | Either panel has fewer than SAMPLE_FLOOR = 100 rows in the window. The honest answer when there is not enough traffic to make a verdict. |
regression_detected | The bucketed recent_regressions signal over the route is non-zero in the 7-day window. The endpoint refuses to call the route “verified” while a regression is in flight, regardless of the cost/quality numbers. |
The constants are pinned in code (SAMPLE_FLOOR = 100, QUALITY_TOLERANCE = 0.03) and documented on Baseline-vs-Floopy methodology.
Aggregation notice header
Section titled “Aggregation notice header”If any decision in the 7-day window has used_shared_pool_prior == true, the response includes the header:
Floopy-Aggregation-Notice: shared-pool-influencedThis tells you that cross-tenant priors influenced at least one decision feeding the verification verdict. The numbers are kept; the provenance is surfaced. See Confidence methodology for the underlying mechanism.
Response cache and Cache-Control
Section titled “Response cache and Cache-Control”The endpoint Redis-caches the response per (organization_id, route_id, window) for 60 seconds. The Cache-Control: max-age=60 response header is echoed so HTTP intermediaries can honour the same TTL. Verification numbers shift slowly; the cache is sized for that cadence.
A cache hit returns the same payload byte-for-byte, including the Floopy-Aggregation-Notice header when applicable.
Errors
Section titled “Errors”| Status | error code | When |
|---|---|---|
400 | invalid_route_id | route_id is missing or not a valid UUID v4. |
400 | invalid_window | window is missing or not in {7d}. |
403 | read_permission | Key lacks read_permission. |
403 | plan_required | The endpoint is not included on the caller’s plan. |
404 | not_found | No route exists in the caller’s org for that route_id. Bytes are identical to a cross-tenant lookup so existence is not leaked. |
429 | rate_limited | Exceeded 60 req/min/org or 20 req/min/key. Carries Retry-After. |
503 | upstream_timeout | The analytics aggregation exceeded the 5 s wall-clock timeout. Carries Retry-After: 60. |
5xx | internal | Upstream failure. |
Curl example
Section titled “Curl example”curl -s -H "Authorization: Bearer $FLOOPY_API_KEY" \ "https://api.floopy.ai/v1/optimization/verification?route_id=5b3f9c1e-7a2b-4c3d-9e1f-0a1b2c3d4e5f&window=7d" \ -iThe -i flag prints the response headers so you can see Cache-Control: max-age=60 and any Floopy-Aggregation-Notice.
Rate limits
Section titled “Rate limits”- 60 requests / minute / organization.
- 20 requests / minute / API key.
Both windows are evaluated atomically. The lower per-key cap exists because verification numbers shift slowly — there is no signal to be had from polling at high cadence.
Audit trail
Section titled “Audit trail”Every successful response writes an optimization.verification_read event to the audit log with:
actor_api_key_id— the API key id that called the endpoint.resource_id— theroute_id.status— the closed-enum verification status (verified,not_verified,insufficient_data,regression_detected).
The event is throttled per (organization_id, key_id, route_id) for 60 seconds so a polling client does not flood the audit log.
See also
Section titled “See also”- Baseline-vs-Floopy methodology — how the comparison is constructed, including verification status semantics.
- Confidence methodology — bucketed regression signal that drives
regression_detected. - GET /v1/decisions/{request_id} — single decision audit, including
evidence.