Stage percentiles and ended reasons over the Calls of a window
GET /v1/analytics/latency
| Property | Value |
|---|---|
| Operation | get_latency_report |
| Group | Call trace and analytics |
| Scope | calls:read |
| Route class | read |
| Idempotency | No Idempotency-Key |
| Audit | Not audited: A metadata read; the report carries counts and timings only. |
| Released in | 1.9.0 |
| Phase 0 host | Served (the hosted api pins 1.65.0) |
Stage percentiles, ended reasons and per-Agent timings over the caller Turns of the ended Calls of a window (ADR 0063). From 1.57.0 (workspace ADR 0048, observability-and-analytics.md section 5) it reads the latency rollups: window=custom with from and to reads a range, hourly rows up to 35 days and daily rows beyond, at most 760 days (range_too_long); the filters narrow it; group_by groups by the fixed dimensions of ANALYTICS_DIMENSIONS_BY_REPORT.latency, any other answering 422 validation_failed and the issue dimension_not_supported; and the answer adds every stage with p50, p90, p95 and p99 computed from bucket counts, its Turn count, whether it is significant and its adherence to the target, with the bucket counts under include_buckets=true. Verbose and test Calls are left out unless selected. A request of 1.56.0 answers as before; the route keeps calls:read.
Request
Set VOCAL_API to the base URL of your API and VOCAL_API_KEY to an API key with the calls:read scope (Authentication and keys). Replace each placeholder, such as agt_... or <name>, with your own value.
curl "$VOCAL_API/v1/analytics/latency" \
-H "Authorization: Bearer $VOCAL_API_KEY"const response = await fetch(`${process.env.VOCAL_API}/v1/analytics/latency`, {
headers: {
Authorization: `Bearer ${process.env.VOCAL_API_KEY}`,
},
});
console.log(response.status, await response.text());import os
import requests
response = requests.get(
f"{os.environ['VOCAL_API']}/v1/analytics/latency",
headers={
"Authorization": f"Bearer {os.environ['VOCAL_API_KEY']}",
},
)
print(response.status_code, response.text)Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
window | query | AnalyticsWindow | no | |
from | query | RequestTimestamp | no | With window=custom, the start of the range, inclusive (1.57.0). |
to | query | RequestTimestamp | no | With window=custom, the end of the range, exclusive (1.57.0). |
agent_id | query | AgentId | no | |
transport | query | CallTransport | no | |
agent_version | query | integer | no | Only the Calls pinned to this version of agent_id (1.57.0). |
direction | query | CallDirection | no | Only inbound or outbound Calls (1.57.0). |
language | query | LanguageTag | no | Only the Calls in this language (1.57.0). |
environment | query | Environment | no | Only the Calls of this environment (1.57.0). Absent: the API key's environment, or live for a Member session; an API key reads its own environment only. test Calls are rated as live ones and never billed or counted. |
provider | query | ProviderId | no | Only the Turns whose stage this Provider served (1.57.0). |
stage | query | LatencyStage | no | Only this stage (1.57.0). |
group_by | query | array of string | no | The fixed dimensions to group by, comma-separated, at most three (1.57.0). A dimension the route does not take is refused with 422 validation_failed and the issue dimension_not_supported. |
include_buckets | query | QueryFlag | no | true adds the sparse bucket counts of each stage (1.57.0). |
include_verbose | query | QueryFlag | no | true counts verbose Calls too, which are left out by default (1.57.0). |
Responses
| Status | Content type | Shape | Error codes |
|---|---|---|---|
200 | application/json | LatencyReport | |
400 | application/json | ErrorEnvelope | invalid_request |
401 | application/json | ErrorEnvelope | unauthenticated |
403 | application/json | ErrorEnvelope | forbidden |
422 | application/json | ErrorEnvelope | validation_failed |
429 | application/json | ErrorEnvelope | rate_limited |
500 | application/json | ErrorEnvelope | internal_error |
Fields of the 200 answer
The shape is LatencyReport.
| Field | Type | Required | Description |
|---|---|---|---|
by_agent | array of object | yes | |
calls | integer | yes | Ended Calls in the window. |
ended_reasons | map of integer | yes | The number of ended Calls of the window by ended reason. Every reason is present, so the api fills 0 for a reason no Call ended with, the reasons added in 1.19.0 (canceled, worker_lost), in 1.21.0 (finalize_failed), in 1.22.0 (refused_concurrency, refused_suspended, refused_spend_cap, refused_no_route), in 1.32.0 (recording_announcement_failed, disclosure_failed) in 1.38.0 (refused_unpriced, stage_unpriced) in 1.48.0 (policy_load_failed) in 1.58.0 (workflow_complete, prompt_compose_failed, max_turns) and in 1.61.0 (refused_opted_out, refused_destination, refused_compliance, schedule_expired, busy) included; a reader on an older version that knows fewer reasons must take this version first. |
endpoint_fallback_turns | integer | yes | |
from | string | yes | The start of the window, RFC 3339. |
granularity | AnalyticsGranularity | no | The rollup rows read. Added in 1.57.0 (roadmap slice 2.11); absent from an older api, which a reader treats as unknown. |
groups | array of LatencyGroup | no | One item per group of group_by; empty when the read named none. Added in 1.57.0 (roadmap slice 2.11); absent from an older api, which a reader treats as unknown. |
interrupted_turns | integer | yes | |
object | "latency_report" | yes | |
stage_stats | array of LatencyStageStats | no | Every stage with p50, p90, p95 and p99 from bucket counts, its Turn count and its adherence to the target. Added in 1.57.0 (roadmap slice 2.11); absent from an older api, which a reader treats as unknown. |
stages | object | yes | |
stages.endpoint_ms | Percentiles | yes | |
stages.leading_silence_ms | Percentiles | yes | |
stages.model_first_token_ms | Percentiles | yes | |
stages.stt_final_ms | Percentiles | yes | |
stages.tts_first_byte_ms | Percentiles | yes | |
stages.voice_to_voice_internal_ms | Percentiles | yes | |
to | string | yes | The end of the window, RFC 3339. |
turns | integer | yes | Caller Turns with stage metrics. |
verbose_included | boolean | no | True when the read counted verbose Calls (include_verbose=true). Added in 1.57.0 (roadmap slice 2.11); absent from an older api, which a reader treats as unknown. |
window | AnalyticsWindow | yes |