{"openapi": "3.1.0", "info": {"title": "CallQA API", "version": "1.0.0", "description": "\nEverything you can do in the CallQA dashboard, from code: manage scenarios, trigger test runs\nfrom CI, fetch results and traces, replay calls.\n\nDeveloper guides: [/docs/](/docs/).\n\n## Authentication\nCreate a key in **Developer > API keys** (admins only) and send it as a bearer token:\n\n    Authorization: Bearer cqa_<prefix>_<secret>\n\nKeys belong to one organization and carry scopes: `read` (results, scenarios), `write`\n(create/edit), `run` (trigger runs and replays), `admin` (billing, members, keys, webhooks;\nimplies all others). A key can be restricted to a list of IP networks.\n\n## Errors\nErrors are JSON `{\"detail\": \"...\", \"code\": \"...\"}`. `code` is stable and machine readable:\n`unauthorized` (401), `missing_scope`, `feature_not_in_plan`, `ip_not_allowed` (403),\n`not_found` (404), `invalid_request` (422), `rate_limited` (429, see `Retry-After`)...\nObjects of other organizations answer `404`, like objects that do not exist.\n\n## Rate limits\n120 requests per minute per key by default.\n\n## Scenario grammar\nScenarios follow a versioned grammar (`schema_version`), published as JSON Schema at\n`GET /scenarios/schema`. The YAML shown on callqa.dev imports as is.\n"}, "paths": {"/api/v1/me": {"get": {"operationId": "me_get", "summary": "Who am I", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MeOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "The organization, plan and scopes of the API key used for the call.", "tags": ["Organization"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/members": {"get": {"operationId": "members_list", "summary": "List members", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/MemberOut"}, "title": "Response", "type": "array"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Organization"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/invitations": {"post": {"operationId": "invitations_create", "summary": "Invite a member", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"additionalProperties": true, "title": "Response", "type": "object"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Sends an invitation email valid 7 days. Seats are limited by the plan: when they are all taken (pending invitations count), 403 `feature_not_in_plan` with `required_plan` and `upgrade_url`.", "tags": ["Organization"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/InvitationIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/members/{member_id}": {"patch": {"operationId": "members_update_role", "summary": "Change a member's role", "parameters": [{"in": "path", "name": "member_id", "schema": {"title": "Member Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MemberOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Organization"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RoleIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "members_remove", "summary": "Remove a member", "parameters": [{"in": "path", "name": "member_id", "schema": {"title": "Member Id", "type": "integer"}, "required": true}], "responses": {"204": {"description": "No Content"}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Organization"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/targets": {"get": {"operationId": "targets_list", "summary": "List target numbers", "parameters": [{"in": "query", "name": "include_archived", "schema": {"default": false, "title": "Include Archived", "type": "boolean"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TargetOut"}, "title": "Response", "type": "array"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Targets"], "security": [{"ApiKeyAuth": []}]}, "post": {"operationId": "targets_create", "summary": "Register a target number", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TargetOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "The number is classified (country, line type). Premium-rate, shared-cost and emergency numbers are refused. A new number starts `unverified`: verify it (`POST /targets/{id}/verification/start`) before running tests on it.", "tags": ["Targets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TargetIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/targets/{target_id}": {"get": {"operationId": "targets_get", "summary": "Get a target", "parameters": [{"in": "path", "name": "target_id", "schema": {"format": "uuid", "title": "Target Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TargetOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Targets"], "security": [{"ApiKeyAuth": []}]}, "patch": {"operationId": "targets_update", "summary": "Update a target", "parameters": [{"in": "path", "name": "target_id", "schema": {"format": "uuid", "title": "Target Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TargetOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "The phone number itself cannot change: register a new target.", "tags": ["Targets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TargetPatch"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "targets_delete", "summary": "Delete a target (admin)", "parameters": [{"in": "path", "name": "target_id", "schema": {"format": "uuid", "title": "Target Id", "type": "string"}, "required": true}], "responses": {"204": {"description": "No Content"}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Targets"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/targets/{target_id}/verification": {"get": {"operationId": "targets_verification_get", "summary": "Verification status", "parameters": [{"in": "path", "name": "target_id", "schema": {"format": "uuid", "title": "Target Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VerificationOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "\n**Why**: CallQA only calls numbers you control. Verification proves it; until then a number\nwith a signed attestation only gets the *sandbox* (3 calls per 24 h, one at a time, 3 minutes\nmax, no schedule or CI run).\n\n**Default flow (`spoken_code`)**:\n1. `POST /targets/{id}/verification/start` (sign the attestation in the same request the\n   first time). The response holds a 6-digit `code`, shown **once** and never stored in clear.\n2. Add the `phrase` (\"Verification code 4 8 2 1 9 3.\") to the line's greeting, or to the\n   agent prompt (\"if someone asks for a verification code, answer 4 8 2 1 9 3\").\n3. `POST /targets/{id}/verification/call`: we call the number, say \"Verification, please.\"\n   if the line waits for the caller to speak, and listen for 20 s.\n\n**IVR menu in front of the code**: give `dtmf_gate` to `start` (for example `\"1w2\"`): after\nthe answer we wait 1 s, press the keys (`w` = 0.5 s pause), then listen. The keys are\nremembered on the number for the next verification. `renew: true` verifies a `verified`\nnumber again without leaving `verified`.\n4. Poll `GET /targets/{id}/verification` until `status` is `verified`. On failure it stays\n   `pending`: `last_attempt.failure_hint` says what to fix, `last_attempt.heard_digits` what\n   we understood, `last_attempt.sip_status` why a line that never answered did not (480\n   unavailable, 486 busy, 603 declined...); `POST .../verification/retry` issues a new code.\n\n**Limits**: a code lives 24 h and is used by a single call; 3 failed attempts in 24 h lock the\nnumber for 24 h (a call the line does not answer counts: `attempts_left`, and\n`attempts_reset_at` tells when the oldest one stops counting); 10 verification calls per\norganization and 24 h, one at a time. A verification is valid 180 days, then the number is\n`expired` and must be verified again.\n\n**Attestation** (version `2026-09-26-v2-draft`), signed once per number and\nagain when a new version becomes mandatory (`attestation_outdated`); the placeholders are\nfilled in when you sign:\n\n> I, {signer_name}, confirm that I am authorized to act on behalf of {organization_name} (the \"Organization\") and I certify, on behalf of the Organization, that:\n> \n> 1. The Organization is the subscriber of the phone number {phone_number}, or holds a prior written authorization from its subscriber to have it called by automated systems using artificial or synthetic voices, for testing purposes. The Organization will keep that authorization and provide it to CallQA on request.\n> 2. This number is not an emergency number, a premium rate or special number, or the personal line of a person who has not agreed in writing to receive these calls.\n> 3. The calls will only be used to test the telephone system that answers this number. They will not be used for marketing, sales, surveys, or to reach any third party.\n> 4. Where a person may answer or listen to these calls, the Organization has informed that person in advance and obtained any consent required by law for automated calls, for the use of an AI voice, and for the recording and transcription of the calls.\n> 5. The calls, their content and any test data comply with the laws that apply to them, including laws on automated and artificial voice calls (such as the US Telephone Consumer Protection Act), telemarketing, call recording and data protection, and with the CallQA Terms of Service and Acceptable Use Policy.\n> 6. If the Organization stops controlling this number, it will stop calling it and remove it from CallQA without delay.\n> \n> I understand that CallQA relies on this attestation to place the calls, that it records my name, email, IP address and the date and time of this signature as evidence, that it may suspend calls to this number at any time, and that the Organization is responsible for any claim resulting from calls placed at its request, as set out in the Terms of Service.\n", "tags": ["Targets"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/targets/{target_id}/verification/attest": {"post": {"operationId": "targets_verification_attest", "summary": "Sign the attestation", "parameters": [{"in": "path", "name": "target_id", "schema": {"format": "uuid", "title": "Target Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VerificationOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "422": {"$ref": "#/components/responses/InvalidRequest"}}, "description": "Required once per number before verifying, and again when a new attestation version becomes mandatory. On its own it only opens the sandbox. The signed text, your name, email or API key, IP and time are kept as evidence. Text: see `GET /targets/{id}/verification`.", "tags": ["Targets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AttestIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/targets/{target_id}/verification/start": {"post": {"operationId": "targets_verification_start", "summary": "Start a verification (new code)", "parameters": [{"in": "path", "name": "target_id", "schema": {"format": "uuid", "title": "Target Id", "type": "string"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VerificationCodeOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "422": {"$ref": "#/components/responses/InvalidRequest"}}, "description": "\n**Why**: CallQA only calls numbers you control. Verification proves it; until then a number\nwith a signed attestation only gets the *sandbox* (3 calls per 24 h, one at a time, 3 minutes\nmax, no schedule or CI run).\n\n**Default flow (`spoken_code`)**:\n1. `POST /targets/{id}/verification/start` (sign the attestation in the same request the\n   first time). The response holds a 6-digit `code`, shown **once** and never stored in clear.\n2. Add the `phrase` (\"Verification code 4 8 2 1 9 3.\") to the line's greeting, or to the\n   agent prompt (\"if someone asks for a verification code, answer 4 8 2 1 9 3\").\n3. `POST /targets/{id}/verification/call`: we call the number, say \"Verification, please.\"\n   if the line waits for the caller to speak, and listen for 20 s.\n\n**IVR menu in front of the code**: give `dtmf_gate` to `start` (for example `\"1w2\"`): after\nthe answer we wait 1 s, press the keys (`w` = 0.5 s pause), then listen. The keys are\nremembered on the number for the next verification. `renew: true` verifies a `verified`\nnumber again without leaving `verified`.\n4. Poll `GET /targets/{id}/verification` until `status` is `verified`. On failure it stays\n   `pending`: `last_attempt.failure_hint` says what to fix, `last_attempt.heard_digits` what\n   we understood, `last_attempt.sip_status` why a line that never answered did not (480\n   unavailable, 486 busy, 603 declined...); `POST .../verification/retry` issues a new code.\n\n**Limits**: a code lives 24 h and is used by a single call; 3 failed attempts in 24 h lock the\nnumber for 24 h (a call the line does not answer counts: `attempts_left`, and\n`attempts_reset_at` tells when the oldest one stops counting); 10 verification calls per\norganization and 24 h, one at a time. A verification is valid 180 days, then the number is\n`expired` and must be verified again.\n\n**Attestation** (version `2026-09-26-v2-draft`), signed once per number and\nagain when a new version becomes mandatory (`attestation_outdated`); the placeholders are\nfilled in when you sign:\n\n> I, {signer_name}, confirm that I am authorized to act on behalf of {organization_name} (the \"Organization\") and I certify, on behalf of the Organization, that:\n> \n> 1. The Organization is the subscriber of the phone number {phone_number}, or holds a prior written authorization from its subscriber to have it called by automated systems using artificial or synthetic voices, for testing purposes. The Organization will keep that authorization and provide it to CallQA on request.\n> 2. This number is not an emergency number, a premium rate or special number, or the personal line of a person who has not agreed in writing to receive these calls.\n> 3. The calls will only be used to test the telephone system that answers this number. They will not be used for marketing, sales, surveys, or to reach any third party.\n> 4. Where a person may answer or listen to these calls, the Organization has informed that person in advance and obtained any consent required by law for automated calls, for the use of an AI voice, and for the recording and transcription of the calls.\n> 5. The calls, their content and any test data comply with the laws that apply to them, including laws on automated and artificial voice calls (such as the US Telephone Consumer Protection Act), telemarketing, call recording and data protection, and with the CallQA Terms of Service and Acceptable Use Policy.\n> 6. If the Organization stops controlling this number, it will stop calling it and remove it from CallQA without delay.\n> \n> I understand that CallQA relies on this attestation to place the calls, that it records my name, email, IP address and the date and time of this signature as evidence, that it may suspend calls to this number at any time, and that the Organization is responsible for any claim resulting from calls placed at its request, as set out in the Terms of Service.\n", "tags": ["Targets"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/VerificationStartIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/targets/{target_id}/verification/retry": {"post": {"operationId": "targets_verification_retry", "summary": "Retry with a new code", "parameters": [{"in": "path", "name": "target_id", "schema": {"format": "uuid", "title": "Target Id", "type": "string"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VerificationCodeOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "422": {"$ref": "#/components/responses/InvalidRequest"}}, "description": "After a failed attempt (or to replace the active code): issues a new code and cancels the previous one. Put the new phrase in the greeting or prompt before calling again.", "tags": ["Targets"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/VerificationStartIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/targets/{target_id}/verification/call": {"post": {"operationId": "targets_verification_call", "summary": "Place the verification call", "parameters": [{"in": "path", "name": "target_id", "schema": {"format": "uuid", "title": "Target Id", "type": "string"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VerificationCallOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "429": {"description": "Too Many Requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "422": {"$ref": "#/components/responses/InvalidRequest"}}, "description": "Calls the number once for the active `spoken_code` code (after pressing its `dtmf_gate` keys, if any). The call is free. Poll `GET .../verification` (or the call) for the result.", "tags": ["Targets"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/VerificationCallIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/targets/{target_id}/verify": {"post": {"operationId": "targets_verify", "summary": "Sign the attestation (legacy)", "parameters": [{"in": "path", "name": "target_id", "schema": {"format": "uuid", "title": "Target Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TargetOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Kept for existing clients: same as `POST .../verification/attest`, returns the target. The attestation does **not** verify the number; see `POST .../verification/start`.", "tags": ["Targets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VerifyIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/schema": {"get": {"operationId": "scenarios_schema", "summary": "Scenario JSON Schema", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"additionalProperties": true, "title": "Response", "type": "object"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "JSON Schema of the scenario grammar (generated from callqa_spec).", "tags": ["Scenarios"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/validate": {"post": {"operationId": "scenarios_validate", "summary": "Validate a scenario without saving", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"additionalProperties": true, "title": "Response", "type": "object"}}}}, "422": {"description": "Unprocessable Content", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioInvalid"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Body: a scenario document. The full grammar is published as JSON Schema at `GET /api/v1/scenarios/schema`. The landing-page shorthand (`phone`, `persona` as text, `must_include`, `must_not`, `max_latency_ms` at top level) is accepted. Unknown fields are rejected unless they start with `x_` (kept verbatim).", "tags": ["Scenarios"], "requestBody": {"content": {"application/json": {"schema": {"additionalProperties": true, "title": "Doc", "type": "object"}, "example": {"name": "Book appointment - edge case", "phone": "+14155550100", "schedule": "every day at 09:00 UTC", "call_window": "09:00-18:00 America/New_York", "persona": "Impatient customer, speaks fast, has accent", "goal": "Book a haircut for tomorrow 2pm", "test_data": {"credit_card": "4242 4242 4242 4242", "customer_id": "TEST-9921"}, "must_include": ["confirm date and time", "provide booking reference"], "must_not": ["hang up before confirmation", "hallucinate availability"], "max_latency_ms": 2000}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/generate": {"post": {"operationId": "scenarios_generate", "summary": "Generate scenarios from a description", "parameters": [], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerationJobOut"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Proposes scenario documents (not saved). Review them, then POST the ones you keep to /scenarios. Invalid proposals are filtered out.\n\nGeneration takes 10 to 60 seconds, so it runs in the background: the answer is `202` with a job; poll `GET /generation-jobs/{id}` (its `url`) until `status` is `done` (then read `result`) or `error`.", "tags": ["Scenarios"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/{scenario_id}/variants/derive": {"post": {"operationId": "variants_derive", "summary": "Auto-derive variants", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerationJobOut"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Adds AUTO test cases (edge cases, personas, accents, error paths) when the job completes. Requires the auto-derived coverage feature (Growth and up).\n\nGeneration takes 10 to 60 seconds, so it runs in the background: the answer is `202` with a job; poll `GET /generation-jobs/{id}` (its `url`) until `status` is `done` (then read `result`) or `error`.", "tags": ["Scenarios"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DeriveIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios": {"get": {"operationId": "scenarios_list", "summary": "List scenarios", "parameters": [{"in": "query", "name": "tag", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Tag"}, "required": false}, {"in": "query", "name": "include_archived", "schema": {"default": false, "title": "Include Archived", "type": "boolean"}, "required": false}, {"in": "query", "name": "q", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Q"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ScenarioSummary"}, "title": "Response", "type": "array"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Scenarios"], "security": [{"ApiKeyAuth": []}]}, "post": {"operationId": "scenarios_create", "summary": "Create a scenario", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioOut"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Unprocessable Content", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioInvalid"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Body: a scenario document. The full grammar is published as JSON Schema at `GET /api/v1/scenarios/schema`. The landing-page shorthand (`phone`, `persona` as text, `must_include`, `must_not`, `max_latency_ms` at top level) is accepted. Unknown fields are rejected unless they start with `x_` (kept verbatim).\n\nA target number that does not exist yet is registered as `unverified`.", "tags": ["Scenarios"], "requestBody": {"content": {"application/json": {"schema": {"additionalProperties": true, "title": "Doc", "type": "object"}, "example": {"name": "Book appointment - edge case", "phone": "+14155550100", "schedule": "every day at 09:00 UTC", "call_window": "09:00-18:00 America/New_York", "persona": "Impatient customer, speaks fast, has accent", "goal": "Book a haircut for tomorrow 2pm", "test_data": {"credit_card": "4242 4242 4242 4242", "customer_id": "TEST-9921"}, "must_include": ["confirm date and time", "provide booking reference"], "must_not": ["hang up before confirmation", "hallucinate availability"], "max_latency_ms": 2000}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/import": {"post": {"operationId": "scenarios_import", "summary": "Import a scenario from YAML", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioOut"}}}}, "200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioOut"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Unprocessable Content", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioInvalid"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Send the YAML as the raw body (`Content-Type: application/yaml`). If a non-archived scenario with the same `name` exists it is updated (upsert), otherwise created.", "tags": ["Scenarios"], "security": [{"ApiKeyAuth": []}], "requestBody": {"content": {"application/yaml": {"schema": {"type": "string"}, "example": "name: \"Book appointment - edge case\"\nphone: \"+14155550100\"\nschedule: \"every day at 09:00 UTC\"\npersona: \"Impatient customer, speaks fast, has accent\"\ngoal: \"Book a haircut for tomorrow 2pm\"\nmust_include:\n  - \"confirm date and time\"\nmust_not:\n  - \"hallucinate availability\"\nmax_latency_ms: 2000\n"}}}}}, "/api/v1/scenarios/{scenario_id}": {"get": {"operationId": "scenarios_get", "summary": "Get a scenario", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Scenarios"], "security": [{"ApiKeyAuth": []}]}, "put": {"operationId": "scenarios_replace", "summary": "Replace a scenario", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioOut"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Unprocessable Content", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioInvalid"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Body: a scenario document. The full grammar is published as JSON Schema at `GET /api/v1/scenarios/schema`. The landing-page shorthand (`phone`, `persona` as text, `must_include`, `must_not`, `max_latency_ms` at top level) is accepted. Unknown fields are rejected unless they start with `x_` (kept verbatim).\n\nVariants are matched by title: existing ones keep their id (and their history).", "tags": ["Scenarios"], "requestBody": {"content": {"application/json": {"schema": {"additionalProperties": true, "title": "Doc", "type": "object"}, "example": {"name": "Book appointment - edge case", "phone": "+14155550100", "schedule": "every day at 09:00 UTC", "call_window": "09:00-18:00 America/New_York", "persona": "Impatient customer, speaks fast, has accent", "goal": "Book a haircut for tomorrow 2pm", "test_data": {"credit_card": "4242 4242 4242 4242", "customer_id": "TEST-9921"}, "must_include": ["confirm date and time", "provide booking reference"], "must_not": ["hang up before confirmation", "hallucinate availability"], "max_latency_ms": 2000}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "scenarios_delete", "summary": "Delete a scenario (admin)", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}], "responses": {"204": {"description": "No Content"}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Scenarios"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/{scenario_id}/export": {"get": {"operationId": "scenarios_export", "summary": "Export as YAML or JSON", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}, {"in": "query", "name": "format", "schema": {"default": "yaml", "title": "Format", "type": "string"}, "required": false}], "responses": {"200": {"description": "OK"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "`format=yaml` (default) or `format=json`. Round-trips with /import.", "tags": ["Scenarios"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/{scenario_id}/archive": {"post": {"operationId": "scenarios_archive", "summary": "Archive a scenario", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioSummary"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Archived scenarios stop their schedule and are hidden from lists; their history is kept. Members may archive; only admins delete.", "tags": ["Scenarios"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/{scenario_id}/variants": {"get": {"operationId": "variants_list", "summary": "List variants", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/VariantOut"}, "title": "Response", "type": "array"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Scenarios"], "security": [{"ApiKeyAuth": []}]}, "post": {"operationId": "variants_create", "summary": "Add a variant (test case)", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VariantOut"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Unprocessable Content", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioInvalid"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "404": {"$ref": "#/components/responses/NotFound"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Scenarios"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VariantIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/{scenario_id}/variants/from-bundle": {"post": {"operationId": "variants_from_bundle", "summary": "Turn a call into a regression test", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VariantOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Unprocessable Content", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioInvalid"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Imports a replay bundle (or a call of yours) as a MANUAL variant: the \"Add to regression suite\" button.", "tags": ["Scenarios"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FromBundleIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/variants/{variant_id}": {"patch": {"operationId": "variants_update", "summary": "Update a variant", "parameters": [{"in": "path", "name": "variant_id", "schema": {"format": "uuid", "title": "Variant Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VariantOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"description": "Unprocessable Content", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScenarioInvalid"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Scenarios"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VariantPatch"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "variants_delete", "summary": "Delete a variant (admin)", "parameters": [{"in": "path", "name": "variant_id", "schema": {"format": "uuid", "title": "Variant Id", "type": "string"}, "required": true}], "responses": {"204": {"description": "No Content"}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Scenarios"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/generation-jobs/{job_id}": {"get": {"operationId": "generation_jobs_get", "summary": "Get a generation job", "parameters": [{"in": "path", "name": "job_id", "schema": {"format": "uuid", "title": "Job Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerationJobOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Scenarios"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/generation-jobs/from-call/{call_id}": {"post": {"operationId": "generation_jobs_from_call", "summary": "Suggest a regression variant from a call", "parameters": [{"in": "path", "name": "call_id", "schema": {"format": "uuid", "title": "Call Id", "type": "string"}, "required": true}], "responses": {"202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerationJobOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Proposes one MANUAL variant (not saved) that reproduces what went wrong in a judged call. Add it with POST /scenarios/{id}/variants.\n\nGeneration takes 10 to 60 seconds, so it runs in the background: the answer is `202` with a job; poll `GET /generation-jobs/{id}` (its `url`) until `status` is `done` (then read `result`) or `error`.", "tags": ["Scenarios"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/{scenario_id}/runs": {"post": {"operationId": "runs_trigger", "summary": "Trigger a run (CI friendly)", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}, {"in": "query", "name": "wait", "schema": {"default": false, "title": "Wait", "type": "boolean"}, "required": false}, {"in": "query", "name": "timeout", "schema": {"default": 600, "title": "Timeout", "type": "integer"}, "required": false}, {"in": "query", "name": "threshold", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Threshold"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunOut"}}}}, "201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunOut"}}}}, "202": {"description": "Accepted", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "412": {"description": "Precondition Failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Queues one call per enabled variant (or the listed ones).\n\n**CI usage**: `?wait=true&threshold=80` holds the request until the run finishes (`timeout` seconds, default 600, capped at 90) and answers:\n* `200` finished and passed (score >= threshold, no failed, error or blocked call);\n* `412` finished and failed;\n* `202` **still running** at the timeout: poll `GET /runs/{id}`.\n\nWithout `wait` the answer is `201` with the queued run.\n\n`curl --fail` alone is **not** a safe gate: it treats `202` as a success, so a slow run would pass. Check the status code:\n\n```bash\ncode=$(curl -sS -o run.json -w '%{http_code}' -X POST --max-time 960 \\\n  -H \"Authorization: Bearer $CALLQA_API_KEY\" \\\n  \"https://app.callqa.dev/api/v1/scenarios/$SCENARIO/runs?wait=true&timeout=900&threshold=80\")\n[ \"$code\" = \"200\" ] || exit 1\n```\n\nThe wait is asynchronous on the server (no worker is held), but proxies in front of your runner may cut a request open for minutes: the CLI polls instead.", "tags": ["Runs"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/TriggerIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/runs": {"get": {"operationId": "runs_list", "summary": "List runs", "parameters": [{"in": "query", "name": "scenario_id", "schema": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Scenario Id"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "since", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Since"}, "required": false}, {"in": "query", "name": "environment", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Environment"}, "required": false}, {"in": "query", "name": "version_id", "schema": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Version Id"}, "required": false}, {"in": "query", "name": "tag", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Tag"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Page_RunOut_"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Filter by `scenario_id`, `status`, `since`, `environment` (slug, name or id), `version_id` (runs attributed to the version) and `tag`.", "tags": ["Runs"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/runs/{run_id}": {"get": {"operationId": "runs_get", "summary": "Get a run", "parameters": [{"in": "path", "name": "run_id", "schema": {"format": "uuid", "title": "Run Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Runs"], "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "runs_delete", "summary": "Delete a run and its calls", "parameters": [{"in": "path", "name": "run_id", "schema": {"format": "uuid", "title": "Run Id", "type": "string"}, "required": true}], "responses": {"204": {"description": "No Content"}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Admin scope. Deletes the run and all its calls (trace, transcript, result, bundles) for good. Refused (`409 run_not_finished`) while a call of the run is queued or in progress: cancel it first. Billing lines are kept without the calls' content. Audited.", "tags": ["Runs"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/runs/{run_id}/cancel": {"post": {"operationId": "runs_cancel", "summary": "Cancel the calls not dialed yet", "parameters": [{"in": "path", "name": "run_id", "schema": {"format": "uuid", "title": "Run Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RunOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Runs"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/calls": {"get": {"operationId": "calls_list", "summary": "List calls", "parameters": [{"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "verdict", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Verdict"}, "required": false}, {"in": "query", "name": "run_id", "schema": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Run Id"}, "required": false}, {"in": "query", "name": "since", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Since"}, "required": false}, {"in": "query", "name": "environment", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Environment"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Page_CallOut_"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Filter by `status` (e.g. `error`, `blocked_insufficient_credit`), `verdict`, `run_id`, `since`, `environment`.", "tags": ["Calls"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/calls/{call_id}": {"get": {"operationId": "calls_get", "summary": "Get a call", "parameters": [{"in": "path", "name": "call_id", "schema": {"format": "uuid", "title": "Call Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CallDetailOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Includes the ResolvedRun, the result (verdicts with evidence, metrics, score) and the transcript.", "tags": ["Calls"], "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "calls_delete", "summary": "Delete a call", "parameters": [{"in": "path", "name": "call_id", "schema": {"format": "uuid", "title": "Call Id", "type": "string"}, "required": true}], "responses": {"204": {"description": "No Content"}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Admin scope. Deletes the call, its trace, transcript, result and bundles for good. Refused with `409` while the call is not finished (`call_not_finished`) and for number verification calls, kept as evidence (`verification_record`). Billing lines are kept without the call's content. Audited.", "tags": ["Calls"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/calls/{call_id}/events": {"get": {"operationId": "calls_events", "summary": "Call trace", "parameters": [{"in": "path", "name": "call_id", "schema": {"format": "uuid", "title": "Call Id", "type": "string"}, "required": true}, {"in": "query", "name": "after_seq", "schema": {"default": -1, "title": "After Seq", "type": "integer"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 200, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Page_EventOut_"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "The append-only event trace (callqa_spec.CallEvent), by seq.", "tags": ["Calls"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/calls/{call_id}/bundle": {"get": {"operationId": "calls_bundle", "summary": "Export a replay bundle", "parameters": [{"in": "path", "name": "call_id", "schema": {"format": "uuid", "title": "Call Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"additionalProperties": true, "title": "Response", "type": "object"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "A self-contained JSON file (callqa_spec.ReplayBundle): resolved run, runtime (models, voices, settings), full trace and result. Replay it with `POST /replays` or import it as a regression test with `POST /scenarios/{id}/variants/from-bundle`.", "tags": ["Calls"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/calls/{call_id}/recording": {"get": {"operationId": "calls_recording", "summary": "Download the call audio", "parameters": [{"in": "path", "name": "call_id", "schema": {"format": "uuid", "title": "Call Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}, "206": {"description": "Partial Content"}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "The stereo WAV of the call (16 bit PCM, 16 kHz): left track our test caller, right track your line. Sample 0 is the `dialing` event: a trace instant `t_ms` is at `(t_ms - recording.start_ms) / 1000` seconds. Supports HTTP `Range`. `404` when the organization does not record audio, or once the recording expired (audio retention).", "tags": ["Calls"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/replays": {"post": {"operationId": "replays_create", "summary": "Replay a call", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CallOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Creates a new call with exactly the same ResolvedRun (and by default the same runtime). The bundle's target must be a number of your organization; normal checks apply (verification, credit, concurrency).", "tags": ["Calls"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReplayIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/tags": {"get": {"operationId": "tags_list", "summary": "List or search tags", "parameters": [{"in": "query", "name": "q", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Q"}, "required": false}, {"in": "query", "name": "limit", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Limit"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TagSuggestion"}, "title": "Response", "type": "array"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Tags are free keywords (a code name, a customer, a team) on scenarios, runs, versions and numbers; CallQA gives them no meaning of its own. With `q`, the autocomplete: names starting with `q` first, then containing it, most used first, at most `limit` (default 10, max 50).", "tags": ["Tags"], "security": [{"ApiKeyAuth": []}]}, "post": {"operationId": "tags_create", "summary": "Create a tag", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TagOut"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Tags"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TagIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/tags/bulk": {"post": {"operationId": "tags_bulk", "summary": "Tag or untag many objects", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TagBulkOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Adds `add` and removes `remove` on every listed scenario, run, version and number (by id). Tags to add are created when new. An id of another organization answers `404 unknown_object` and nothing is changed.", "tags": ["Tags"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TagBulkIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/tags/{tag_id}": {"get": {"operationId": "tags_get", "summary": "Get a tag", "parameters": [{"in": "path", "name": "tag_id", "schema": {"title": "Tag Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TagOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Tags"], "security": [{"ApiKeyAuth": []}]}, "patch": {"operationId": "tags_update", "summary": "Update a tag", "parameters": [{"in": "path", "name": "tag_id", "schema": {"title": "Tag Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TagOut"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Renaming a tag keeps it on its scenarios and runs.", "tags": ["Tags"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TagPatch"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "tags_delete", "summary": "Delete a tag (admin)", "parameters": [{"in": "path", "name": "tag_id", "schema": {"title": "Tag Id", "type": "integer"}, "required": true}], "responses": {"204": {"description": "No Content"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Tags"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/versions": {"get": {"operationId": "versions_list", "summary": "List versions", "parameters": [{"in": "query", "name": "environment", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Environment"}, "required": false}, {"in": "query", "name": "tag", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Tag"}, "required": false}, {"in": "query", "name": "q", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Q"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Page_VersionOut_"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Newest first. `environment` (slug, name or id) keeps one environment, `tag` the versions carrying a tag, `q` a part of the label, git ref or sha.", "tags": ["Versions"], "security": [{"ApiKeyAuth": []}]}, "post": {"operationId": "versions_create", "summary": "Create a version", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VersionOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "A version of your code in one environment, from `deployed_at` (default now). Runs of that environment are attributed to it until the next version. `409 already_exists` when the label exists in the environment. CI can instead send `version` when it triggers a run.", "tags": ["Versions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VersionIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/versions/{version_id}": {"get": {"operationId": "versions_get", "summary": "Get a version", "parameters": [{"in": "path", "name": "version_id", "schema": {"format": "uuid", "title": "Version Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VersionOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Versions"], "security": [{"ApiKeyAuth": []}]}, "patch": {"operationId": "versions_update", "summary": "Update a version", "parameters": [{"in": "path", "name": "version_id", "schema": {"format": "uuid", "title": "Version Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VersionOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Versions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VersionPatch"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "versions_delete", "summary": "Delete a version (admin)", "parameters": [{"in": "path", "name": "version_id", "schema": {"format": "uuid", "title": "Version Id", "type": "string"}, "required": true}], "responses": {"204": {"description": "No Content"}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Its runs are kept; they fall back to the previous version of the environment.", "tags": ["Versions"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/versions/{version_id}/promote": {"post": {"operationId": "versions_promote", "summary": "Promote a version to another environment", "parameters": [{"in": "path", "name": "version_id", "schema": {"format": "uuid", "title": "Version Id", "type": "string"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VersionOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "The same code in the next environment (staging to production), from `deployed_at` (default now): label, git fields, notes, number and tags travel with it. `409 already_exists` when the label is already there.", "tags": ["Versions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VersionPromoteIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/releases": {"get": {"operationId": "releases_list", "summary": "List releases (deprecated)", "parameters": [{"in": "query", "name": "environment", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Environment"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ReleaseOut"}, "title": "Response", "type": "array"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "**Deprecated** since 2026-09-27, removed on 2027-03-31.\n\nUse `GET /versions`.", "tags": ["Versions"], "security": [{"ApiKeyAuth": []}], "deprecated": true}, "post": {"operationId": "releases_create", "summary": "Tag a release (deprecated)", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReleaseOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "**Deprecated** since 2026-09-27, removed on 2027-03-31.\n\nUse `POST /versions`.", "tags": ["Versions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReleaseIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}], "deprecated": true}}, "/api/v1/releases/{release_id}": {"get": {"operationId": "releases_get", "summary": "Get a release (deprecated)", "parameters": [{"in": "path", "name": "release_id", "schema": {"format": "uuid", "title": "Release Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReleaseOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "**Deprecated** since 2026-09-27, removed on 2027-03-31.\n\nUse `GET /versions/{id}`.", "tags": ["Versions"], "security": [{"ApiKeyAuth": []}], "deprecated": true}, "patch": {"operationId": "releases_update", "summary": "Update a release (deprecated)", "parameters": [{"in": "path", "name": "release_id", "schema": {"format": "uuid", "title": "Release Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReleaseOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "**Deprecated** since 2026-09-27, removed on 2027-03-31.\n\nUse `PATCH /versions/{id}`.", "tags": ["Versions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReleasePatch"}}}, "required": true}, "security": [{"ApiKeyAuth": []}], "deprecated": true}, "delete": {"operationId": "releases_delete", "summary": "Delete a release (deprecated, admin)", "parameters": [{"in": "path", "name": "release_id", "schema": {"format": "uuid", "title": "Release Id", "type": "string"}, "required": true}], "responses": {"204": {"description": "No Content"}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "**Deprecated** since 2026-09-27, removed on 2027-03-31.\n\nUse `DELETE /versions/{id}`.", "tags": ["Versions"], "security": [{"ApiKeyAuth": []}], "deprecated": true}}, "/api/v1/releases/{release_id}/promote": {"post": {"operationId": "releases_promote", "summary": "Promote a release (deprecated)", "parameters": [{"in": "path", "name": "release_id", "schema": {"format": "uuid", "title": "Release Id", "type": "string"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReleaseOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "**Deprecated** since 2026-09-27, removed on 2027-03-31.\n\nUse `POST /versions/{id}/promote`.", "tags": ["Versions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PromoteIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}], "deprecated": true}}, "/api/v1/environments": {"get": {"operationId": "environments_list", "summary": "List environments", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/EnvironmentOut"}, "title": "Response", "type": "array"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "In promotion order. Every organization has one default environment (`is_default`), used by runs and versions that name none.", "tags": ["Environments"], "security": [{"ApiKeyAuth": []}]}, "post": {"operationId": "environments_create", "summary": "Create an environment", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvironmentOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Environments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvironmentIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/environments/stability": {"get": {"operationId": "environments_stability", "summary": "Stability per environment (Growth and up)", "parameters": [{"in": "query", "name": "days", "schema": {"default": 30, "title": "Days", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/StabilityOut"}, "title": "Response", "type": "array"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Over the last `days` (7, 30 or 90): tests, pass rate, average score, p95 latency, flaky test cases and last run of each environment.", "tags": ["Environments"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/environments/compare": {"get": {"operationId": "environments_compare", "summary": "Compare environments (Growth and up)", "parameters": [{"in": "query", "name": "a", "schema": {"title": "A", "type": "string"}, "required": true}, {"in": "query", "name": "b", "schema": {"title": "B", "type": "string"}, "required": true}, {"in": "query", "name": "a_version", "schema": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "A Version"}, "required": false}, {"in": "query", "name": "b_version", "schema": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "B Version"}, "required": false}, {"in": "query", "name": "scenario_id", "schema": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Scenario Id"}, "required": false}, {"in": "query", "name": "days", "schema": {"default": 30, "title": "Days", "type": "integer"}, "required": false}, {"in": "query", "name": "a_release", "schema": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "A Release"}, "required": false}, {"in": "query", "name": "b_release", "schema": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "B Release"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CompareOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "403": {"description": "Forbidden", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Side `a` vs side `b` (for example `a=staging&b=production`): overall KPIs, per scenario, and the test cases whose last verdict differs. Narrow a side to one version with `a_version` / `b_version` (version id), and to one scenario with `scenario_id`. Without a version, a side covers the last `days` days. `a_release` / `b_release` are the deprecated names of `a_version` / `b_version`.", "tags": ["Environments"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/environments/{env_id}": {"get": {"operationId": "environments_get", "summary": "Get an environment", "parameters": [{"in": "path", "name": "env_id", "schema": {"title": "Env Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvironmentOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "By id or slug.", "tags": ["Environments"], "security": [{"ApiKeyAuth": []}]}, "patch": {"operationId": "environments_update", "summary": "Update an environment", "parameters": [{"in": "path", "name": "env_id", "schema": {"title": "Env Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvironmentOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Environments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvironmentPatch"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "environments_delete", "summary": "Delete an environment (admin)", "parameters": [{"in": "path", "name": "env_id", "schema": {"title": "Env Id", "type": "string"}, "required": true}], "responses": {"204": {"description": "No Content"}, "404": {"$ref": "#/components/responses/NotFound"}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Refused (`409 environment_in_use`) while runs or versions belong to it, and for the default environment (`409 default_required`).", "tags": ["Environments"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/environments/{env_id}/numbers": {"put": {"operationId": "environments_set_number", "summary": "Set the number dialed in an environment", "parameters": [{"in": "path", "name": "env_id", "schema": {"title": "Env Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EnvironmentOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Runs of this environment dial `number_id` instead of `target_id`. Both are numbers of your organization, each verified on its own.", "tags": ["Environments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/NumberIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/environments/{env_id}/scenarios": {"get": {"operationId": "environments_scenarios", "summary": "Scenarios of an environment", "parameters": [{"in": "path", "name": "env_id", "schema": {"title": "Env Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/BindingOut"}, "title": "Response", "type": "array"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "The scenarios activated in (or bound to) this environment.", "tags": ["Environments"], "security": [{"ApiKeyAuth": []}]}, "post": {"operationId": "environments_scenarios_bulk", "summary": "Bind, pause or unbind many scenarios", "parameters": [{"in": "path", "name": "env_id", "schema": {"title": "Env Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkBindingOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "One call for a multi-select or a drag and drop: `enable`, `disable` or `remove` the listed scenarios in this environment, optionally with the same `schedule`, `timezone`, `call_window` for all. An id of another organization answers `404` and nothing changes.", "tags": ["Environments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkBindingIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/{scenario_id}/environments": {"get": {"operationId": "scenario_environments_list", "summary": "Environments of a scenario", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/BindingOut"}, "title": "Response", "type": "array"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Where the scenario runs, with the schedule, the call window and the number dialed in each environment.", "tags": ["Environments"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/{scenario_id}/environments/{env_id}": {"put": {"operationId": "scenario_environments_set", "summary": "Activate or schedule a scenario in an environment", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}, {"in": "path", "name": "env_id", "schema": {"title": "Env Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BindingOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Creates the binding when needed. Fields left out keep their value. Each environment has its own schedule and window.", "tags": ["Environments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BindingIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "scenario_environments_delete", "summary": "Remove a scenario from an environment", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}, {"in": "path", "name": "env_id", "schema": {"title": "Env Id", "type": "string"}, "required": true}], "responses": {"204": {"description": "No Content"}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Deletes the binding and its schedule. Past runs are kept.", "tags": ["Environments"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/matrix": {"get": {"operationId": "matrix_get", "summary": "What runs where, and what passes", "parameters": [{"in": "query", "name": "environment", "schema": {"items": {"type": "string"}, "title": "Environment", "type": "array"}, "required": false}, {"in": "query", "name": "tag", "schema": {"items": {"type": "string"}, "title": "Tag", "type": "array"}, "required": false}, {"in": "query", "name": "scenario_id", "schema": {"items": {"format": "uuid", "type": "string"}, "title": "Scenario Id", "type": "array"}, "required": false}, {"in": "query", "name": "q", "schema": {"default": "", "title": "Q", "type": "string"}, "required": false}, {"in": "query", "name": "bound_only", "schema": {"default": false, "title": "Bound Only", "type": "boolean"}, "required": false}, {"in": "query", "name": "trend_runs", "schema": {"default": 5, "title": "Trend Runs", "type": "integer"}, "required": false}, {"in": "query", "name": "versions", "schema": {"default": 5, "title": "Versions", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MatrixOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "For every scenario x environment: activated or not, schedule, last completed run (verdict, score, version), trend of the last `trend_runs` runs; for the last `versions` versions of each environment: the scenarios that pass, warn, fail or were not tested. Filters: `environment` and `tag` (repeat them), `scenario_id` (repeat), `q` (part of a scenario name), `bound_only`.", "tags": ["Environments"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/webhooks": {"get": {"operationId": "webhooks_list", "summary": "List webhook endpoints", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WebhookOut"}, "title": "Response", "type": "array"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Payloads are JSON `{id, type, created, data}` signed with HMAC-SHA256:\n\n`CallQA-Signature: t=<unix ts>,v1=<hex hmac_sha256(secret, \"<ts>.<raw body>\")>`\n\nDuring a secret rotation the header carries one `v1` per valid secret: accept the delivery if **any** `v1` matches. Verify in constant time and reject timestamps older than 5 minutes. Failed deliveries are retried after 1 min, 5 min, 30 min, 2 h and 6 h.\n\nEvents: `call.completed`, `call.failed`, `call.blocked`, `call.regressed`, `call.recovered`, `suite_run.started`, `suite_run.completed`, `suite_run.failed`, `score.dropped`, `version.created`, `version.promoted`, `release.created`, `release.promoted`, `wallet.low_balance`", "tags": ["Webhooks"], "security": [{"ApiKeyAuth": []}]}, "post": {"operationId": "webhooks_create", "summary": "Create a webhook endpoint", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WebhookCreated"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Payloads are JSON `{id, type, created, data}` signed with HMAC-SHA256:\n\n`CallQA-Signature: t=<unix ts>,v1=<hex hmac_sha256(secret, \"<ts>.<raw body>\")>`\n\nDuring a secret rotation the header carries one `v1` per valid secret: accept the delivery if **any** `v1` matches. Verify in constant time and reject timestamps older than 5 minutes. Failed deliveries are retried after 1 min, 5 min, 30 min, 2 h and 6 h.\n\nEvents: `call.completed`, `call.failed`, `call.blocked`, `call.regressed`, `call.recovered`, `suite_run.started`, `suite_run.completed`, `suite_run.failed`, `score.dropped`, `version.created`, `version.promoted`, `release.created`, `release.promoted`, `wallet.low_balance`", "tags": ["Webhooks"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WebhookIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/webhooks/{webhook_id}": {"get": {"operationId": "webhooks_get", "summary": "Get a webhook endpoint", "parameters": [{"in": "path", "name": "webhook_id", "schema": {"format": "uuid", "title": "Webhook Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WebhookOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Webhooks"], "security": [{"ApiKeyAuth": []}]}, "patch": {"operationId": "webhooks_update", "summary": "Update a webhook endpoint", "parameters": [{"in": "path", "name": "webhook_id", "schema": {"format": "uuid", "title": "Webhook Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WebhookOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Change the URL, the events, the description, or pause it (`enabled: false`). The signing secret does not change: use `rotate-secret`.", "tags": ["Webhooks"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WebhookPatch"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "webhooks_delete", "summary": "Delete a webhook endpoint", "parameters": [{"in": "path", "name": "webhook_id", "schema": {"format": "uuid", "title": "Webhook Id", "type": "string"}, "required": true}], "responses": {"204": {"description": "No Content"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Webhooks"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/webhooks/{webhook_id}/rotate-secret": {"post": {"operationId": "webhooks_rotate_secret", "summary": "Rotate the signing secret", "parameters": [{"in": "path", "name": "webhook_id", "schema": {"format": "uuid", "title": "Webhook Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WebhookCreated"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Returns the new secret (shown once). During `grace_period_hours` (default 24, at most 168) every delivery is signed with both secrets (two `v1` in `CallQA-Signature`), so you can deploy the new one without losing events.", "tags": ["Webhooks"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/SecretRotateIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/webhooks/{webhook_id}/deliveries": {"get": {"operationId": "webhooks_deliveries", "summary": "Delivery log of an endpoint", "parameters": [{"in": "path", "name": "webhook_id", "schema": {"format": "uuid", "title": "Webhook Id", "type": "string"}, "required": true}, {"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Page_DeliveryOut_"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Webhooks"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/webhooks/{webhook_id}/test": {"post": {"operationId": "webhooks_test", "summary": "Send a test event now", "parameters": [{"in": "path", "name": "webhook_id", "schema": {"format": "uuid", "title": "Webhook Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DeliveryOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Webhooks"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/alert-channels": {"get": {"operationId": "alert_channels_list", "summary": "List alert channels", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AlertChannelOut"}, "title": "Response", "type": "array"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Alert channels warn people in **Slack** (incoming webhook) or by **email** when a run run completes and one of the channel's rules matches: the run failed (`on_failure`), its score is under `on_score_below`, or a call's p95 latency is above `on_latency_p95_above_ms`. One message per channel and run at most, sent within seconds by the dispatcher and retried after 1, 5 and 30 minutes.\n\nThe Slack webhook URL is a secret: it must be an `https://hooks.slack.com/` URL, and it is never returned in full. For machine integrations, use webhooks.", "tags": ["Alerts"], "security": [{"ApiKeyAuth": []}]}, "post": {"operationId": "alert_channels_create", "summary": "Create an alert channel", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AlertChannelOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Alert channels warn people in **Slack** (incoming webhook) or by **email** when a run run completes and one of the channel's rules matches: the run failed (`on_failure`), its score is under `on_score_below`, or a call's p95 latency is above `on_latency_p95_above_ms`. One message per channel and run at most, sent within seconds by the dispatcher and retried after 1, 5 and 30 minutes.\n\nThe Slack webhook URL is a secret: it must be an `https://hooks.slack.com/` URL, and it is never returned in full. For machine integrations, use webhooks.", "tags": ["Alerts"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AlertChannelIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/alert-channels/{channel_id}": {"get": {"operationId": "alert_channels_get", "summary": "Get an alert channel", "parameters": [{"in": "path", "name": "channel_id", "schema": {"title": "Channel Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AlertChannelOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Alerts"], "security": [{"ApiKeyAuth": []}]}, "patch": {"operationId": "alert_channels_update", "summary": "Update an alert channel", "parameters": [{"in": "path", "name": "channel_id", "schema": {"title": "Channel Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AlertChannelOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Only the fields you send change. `null` on a threshold removes that rule. The kind cannot change.", "tags": ["Alerts"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AlertChannelPatch"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "alert_channels_delete", "summary": "Delete an alert channel", "parameters": [{"in": "path", "name": "channel_id", "schema": {"title": "Channel Id", "type": "integer"}, "required": true}], "responses": {"204": {"description": "No Content"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Alerts"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/alert-channels/{channel_id}/test": {"post": {"operationId": "alert_channels_test", "summary": "Send a test alert", "parameters": [{"in": "path", "name": "channel_id", "schema": {"title": "Channel Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AlertTestOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Sends a test message now and tells whether it went through. Limited to 5 per minute per channel.", "tags": ["Alerts"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/api-keys": {"get": {"operationId": "api_keys_list", "summary": "List API keys", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ApiKeyOut"}, "title": "Response", "type": "array"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["API keys & logs"], "security": [{"ApiKeyAuth": []}]}, "post": {"operationId": "api_keys_create", "summary": "Create an API key", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ApiKeyCreated"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "The full key is returned once; only a hash is stored. `allowed_cidrs` restricts where it can be used from.", "tags": ["API keys & logs"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ApiKeyIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/api-keys/{key_id}": {"get": {"operationId": "api_keys_get", "summary": "Get an API key", "parameters": [{"in": "path", "name": "key_id", "schema": {"title": "Key Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ApiKeyOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["API keys & logs"], "security": [{"ApiKeyAuth": []}]}, "patch": {"operationId": "api_keys_update", "summary": "Rename or restrict an API key", "parameters": [{"in": "path", "name": "key_id", "schema": {"title": "Key Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ApiKeyOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Scopes cannot change: create a new key instead.", "tags": ["API keys & logs"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ApiKeyPatch"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}, "delete": {"operationId": "api_keys_revoke", "summary": "Revoke an API key", "parameters": [{"in": "path", "name": "key_id", "schema": {"title": "Key Id", "type": "integer"}, "required": true}], "responses": {"204": {"description": "No Content"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["API keys & logs"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/api-keys/{key_id}/rotate": {"post": {"operationId": "api_keys_rotate", "summary": "Rotate an API key", "parameters": [{"in": "path", "name": "key_id", "schema": {"title": "Key Id", "type": "integer"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ApiKeyCreated"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Creates a replacement with the same name, scopes, networks and expiry, returned once. The old key keeps working for `grace_period_hours` (default 24, at most 168, 0 revokes it now), then expires: deploy the new one in between.", "tags": ["API keys & logs"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/KeyRotateIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/api-logs": {"get": {"operationId": "api_logs_list", "summary": "API request journal", "parameters": [{"in": "query", "name": "since", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Since"}, "required": false}, {"in": "query", "name": "status_code", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Status Code"}, "required": false}, {"in": "query", "name": "key_prefix", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Key Prefix"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 100, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Page_ApiLogOut_"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Every authenticated API request of your organization (method, path, status, duration, key, IP). Bodies are never stored.", "tags": ["API keys & logs"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/audit-log": {"get": {"operationId": "audit_log_list", "summary": "Audit log (admin)", "parameters": [{"in": "query", "name": "action", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Action"}, "required": false}, {"in": "query", "name": "actor_api_key_prefix", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Actor Api Key Prefix"}, "required": false}, {"in": "query", "name": "since", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Since"}, "required": false}, {"in": "query", "name": "until", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Until"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Page_AuditOut_"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Who did what in your organization, newest first: members, keys, webhooks, alert channels, billing, number verification, deletions. Never contains secrets. Filter by `action` (exact, or a prefix ending with `.` such as `webhook.`), `actor_api_key_prefix` and `since` / `until`.", "tags": ["Organization"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/exports": {"post": {"operationId": "exports_create", "summary": "Request an export", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExportOut"}}}}, "200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExportOut"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "A full export of your organization (admin scope): a zip of JSON files with the organization and members, numbers and attestations, scenarios and test cases, runs, one file per call (trace, transcript, result), releases, tags, audit log, legal acceptances, usage and wallet ledger. Secrets are never exported. The archive is built in the background: poll `GET /exports/{id}` until `status` is `done`, then download `download_url` (signed, valid 24 hours, no API key needed). Archives are deleted after 7 days. If an export is already being built, it is returned (200).", "tags": ["Organization"], "security": [{"ApiKeyAuth": []}]}, "get": {"operationId": "exports_list", "summary": "List exports", "parameters": [{"in": "query", "name": "limit", "schema": {"default": 20, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Page_ExportOut_"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Organization"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/exports/{export_id}": {"get": {"operationId": "exports_get", "summary": "Get an export", "parameters": [{"in": "path", "name": "export_id", "schema": {"format": "uuid", "title": "Export Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ExportOut"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "`download_url` is set when `status` is `done` (a fresh 24 h link on every call).", "tags": ["Organization"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/calls/{call_id}/llm-export": {"get": {"operationId": "calls_llm_export", "summary": "Export a call for an LLM", "parameters": [{"in": "path", "name": "call_id", "schema": {"format": "uuid", "title": "Call Id", "type": "string"}, "required": true}, {"in": "query", "name": "format", "schema": {"default": "markdown", "enum": ["markdown", "json"], "title": "Format", "type": "string"}, "required": false}], "responses": {"200": {"description": "The report.", "content": {"text/markdown": {"schema": {"type": "string"}}, "application/json": {"schema": {"type": "object"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "A report made to be pasted into an LLM (a chat assistant or a coding agent) that will fix your voice agent: the scenario, the results, every failed check with the judge's quote, a readable transcript (AGENT = your agent, CALLER = our test caller), metrics, the judge's recommendations and a primer asking for a fix.\n\n`format=markdown` (default) answers `text/markdown`; `format=json` answers the same document as compact JSON (`format: \"callqa.llm_report\"`, `version`, `level`).", "tags": ["Exports for LLMs"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/runs/{run_id}/llm-export": {"get": {"operationId": "runs_llm_export", "summary": "Export a run for an LLM", "parameters": [{"in": "path", "name": "run_id", "schema": {"format": "uuid", "title": "Run Id", "type": "string"}, "required": true}, {"in": "query", "name": "format", "schema": {"default": "markdown", "enum": ["markdown", "json"], "title": "Format", "type": "string"}, "required": false}], "responses": {"200": {"description": "The report.", "content": {"text/markdown": {"schema": {"type": "string"}}, "application/json": {"schema": {"type": "object"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "A report made to be pasted into an LLM (a chat assistant or a coding agent) that will fix your voice agent: the scenario, the results, every failed check with the judge's quote, a readable transcript (AGENT = your agent, CALLER = our test caller), metrics, the judge's recommendations and a primer asking for a fix.\n\n`format=markdown` (default) answers `text/markdown`; `format=json` answers the same document as compact JSON (`format: \"callqa.llm_report\"`, `version`, `level`). The failed calls (up to 5) are detailed.", "tags": ["Exports for LLMs"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/scenarios/{scenario_id}/llm-export": {"get": {"operationId": "scenarios_llm_export", "summary": "Export a scenario for an LLM", "parameters": [{"in": "path", "name": "scenario_id", "schema": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "required": true}, {"in": "query", "name": "format", "schema": {"default": "markdown", "enum": ["markdown", "json"], "title": "Format", "type": "string"}, "required": false}], "responses": {"200": {"description": "The report.", "content": {"text/markdown": {"schema": {"type": "string"}}, "application/json": {"schema": {"type": "object"}}}}, "404": {"$ref": "#/components/responses/NotFound"}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "A report made to be pasted into an LLM (a chat assistant or a coding agent) that will fix your voice agent: the scenario, the results, every failed check with the judge's quote, a readable transcript (AGENT = your agent, CALLER = our test caller), metrics, the judge's recommendations and a primer asking for a fix.\n\n`format=markdown` (default) answers `text/markdown`; `format=json` answers the same document as compact JSON (`format: \"callqa.llm_report\"`, `version`, `level`). Covers the scenario YAML, its last 5 runs, the checks that fail most and the last 3 failed calls.", "tags": ["Exports for LLMs"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/wallet": {"get": {"operationId": "wallet_get", "summary": "Wallet balance", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WalletOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Calls beyond the monthly quota are paid from a **prepaid wallet**, at your plan's overage price times the destination weight. Credit is reserved before a call is dialed and the unused part is released after. When the wallet cannot cover a call, the call is not placed and ends with status `blocked_insufficient_credit`: top up with `POST /wallet/checkout`. Top-ups are between $20 and $5,000 (`amount_cents` 2000 to 500000).", "tags": ["Billing"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/wallet/transactions": {"get": {"operationId": "wallet_transactions", "summary": "Wallet ledger", "parameters": [{"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Page_WalletTxOut_"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Append-only ledger: every balance change has a line.", "tags": ["Billing"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/wallet/checkout": {"post": {"operationId": "wallet_checkout", "summary": "Top up the wallet", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CheckoutOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Calls beyond the monthly quota are paid from a **prepaid wallet**, at your plan's overage price times the destination weight. Credit is reserved before a call is dialed and the unused part is released after. When the wallet cannot cover a call, the call is not placed and ends with status `blocked_insufficient_credit`: top up with `POST /wallet/checkout`. Top-ups are between $20 and $5,000 (`amount_cents` 2000 to 500000).\n\nReturns a Stripe Checkout URL. The wallet is credited when Stripe confirms the payment (webhook), not before.", "tags": ["Billing"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CheckoutIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/usage": {"get": {"operationId": "usage_get", "summary": "Quota usage this month", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UsageOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Quota periods are calendar months (UTC). `held` = units reserved by calls in progress.", "tags": ["Billing"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/billing/forecast": {"get": {"operationId": "billing_forecast", "summary": "Forecast of the month", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ForecastOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "What the enabled schedules will consume until the quota resets (1st of next month, UTC), per schedule and environment: runs left x test cases x destination weight x average 10 minute slices observed over 30 days (maximum duration when a scenario never ran). Compared with the quota, bonus calls, overage settings and cap. Manual, API and CI runs are not forecast.", "tags": ["Billing"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/billing/referral": {"get": {"operationId": "billing_referral", "summary": "Your referral link", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReferralOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Both organizations get the bonus calls when the referred one starts its first paid subscription. Referring yourself (a member of your organization, the same Stripe customer) or an existing customer gives nothing.", "tags": ["Billing"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/billing/settings": {"get": {"operationId": "billing_settings_get", "summary": "Overage, spend cap and alerts", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BillingSettingsOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Paid overage on/off, its monthly cap (wallet spend), what happens at the limit, and the `wallet.low_balance` threshold.", "tags": ["Billing"], "security": [{"ApiKeyAuth": []}]}, "patch": {"operationId": "billing_settings_update", "summary": "Change overage, the spend cap or the low balance threshold (admin)", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BillingSettingsOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Only the fields you send change; `null` removes the cap or turns `wallet.low_balance` off. When the cap is reached, new calls are not placed (`blocked_insufficient_credit`, block reason `spend_cap_reached`) until the next month or a higher cap. `allow_paid_overage: false` stops calls once the quota and bonus calls are used (`overage_disabled`); `on_limit: pause_schedules` also pauses the schedules until the 1st of next month.", "tags": ["Billing"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BillingSettingsPatch"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/plans": {"get": {"operationId": "plans_list", "summary": "Public plans", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PlanPublicOut"}, "title": "Response", "type": "array"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Plans you can subscribe to with `POST /billing/subscription/checkout`.", "tags": ["Billing"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/billing/subscription": {"get": {"operationId": "subscription_get", "summary": "Current subscription", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SubscriptionOut"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "tags": ["Billing"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/billing/subscription/checkout": {"post": {"operationId": "subscription_checkout", "summary": "Subscribe to a plan", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CheckoutOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "409": {"description": "Conflict", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Returns a Stripe Checkout URL for a first subscription. If your organization already has an active Stripe subscription the answer is `409` (`subscription_exists`): change plan, interval or payment method in the billing portal (`POST /billing/portal`).", "tags": ["Billing"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SubscriptionCheckoutIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/billing/portal": {"post": {"operationId": "billing_portal", "summary": "Open the billing portal", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CheckoutOut"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Returns a Stripe billing portal URL: change or cancel the plan, update the payment method, download invoices.", "tags": ["Billing"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/PortalIn"}, {"type": "null"}]}}}, "required": false}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/support/tickets": {"get": {"operationId": "support_tickets_list", "summary": "List support tickets", "parameters": [{"in": "query", "name": "status", "schema": {"anyOf": [{"enum": ["open", "waiting_customer", "answered", "closed"], "type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 20, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Page_TicketOut_"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Ask the CallQA team: a bug, a question, feedback, a billing matter or an abuse report. A person of the team answers, usually within a few hours on business days; the answer is emailed to the author (and to the organization's admins when an API key opened the ticket) and readable here. Statuses: `open` (the team has to answer), `waiting_customer` (the team waits for you), `answered`, `closed`. A reply reopens a ticket.\n\nNever paste a secret (API key, password, token): anything that looks like one is replaced by `[redacted secret]` before it is stored.", "tags": ["Support"], "security": [{"ApiKeyAuth": []}]}, "post": {"operationId": "support_tickets_create", "summary": "Open a support ticket", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TicketDetail"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "422": {"description": "Unprocessable Content", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Ask the CallQA team: a bug, a question, feedback, a billing matter or an abuse report. A person of the team answers, usually within a few hours on business days; the answer is emailed to the author (and to the organization's admins when an API key opened the ticket) and readable here. Statuses: `open` (the team has to answer), `waiting_customer` (the team waits for you), `answered`, `closed`. A reply reopens a ticket.\n\nNever paste a secret (API key, password, token): anything that looks like one is replaced by `[redacted secret]` before it is stored.\n\nAt most 20 new tickets a day per organization (429 `rate_limited` beyond).", "tags": ["Support"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TicketIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/support/tickets/{ticket_id}": {"get": {"operationId": "support_tickets_get", "summary": "Get a support ticket", "parameters": [{"in": "path", "name": "ticket_id", "schema": {"format": "uuid", "title": "Ticket Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TicketDetail"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "The ticket and every message, oldest first: the answers of the CallQA team have `author` `staff`.", "tags": ["Support"], "security": [{"ApiKeyAuth": []}]}}, "/api/v1/support/tickets/{ticket_id}/messages": {"post": {"operationId": "support_tickets_reply", "summary": "Reply to a support ticket", "parameters": [{"in": "path", "name": "ticket_id", "schema": {"format": "uuid", "title": "Ticket Id", "type": "string"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TicketDetail"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "Adds a message and reopens the ticket (status `open`): the team is alerted. Never paste a secret.", "tags": ["Support"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageIn"}}}, "required": true}, "security": [{"ApiKeyAuth": []}]}}, "/api/v1/support/tickets/{ticket_id}/close": {"post": {"operationId": "support_tickets_close", "summary": "Close a support ticket", "parameters": [{"in": "path", "name": "ticket_id", "schema": {"format": "uuid", "title": "Ticket Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TicketDetail"}}}}, "401": {"$ref": "#/components/responses/Unauthorized"}, "403": {"$ref": "#/components/responses/Forbidden"}, "404": {"$ref": "#/components/responses/NotFound"}, "422": {"$ref": "#/components/responses/InvalidRequest"}, "429": {"$ref": "#/components/responses/RateLimited"}}, "description": "When the matter is solved. A later reply reopens it.", "tags": ["Support"], "security": [{"ApiKeyAuth": []}]}}}, "components": {"schemas": {"MeOut": {"properties": {"org_id": {"format": "uuid", "title": "Org Id", "type": "string"}, "org_name": {"title": "Org Name", "type": "string"}, "org_slug": {"title": "Org Slug", "type": "string"}, "api_key_prefix": {"title": "Api Key Prefix", "type": "string"}, "scopes": {"items": {"type": "string"}, "title": "Scopes", "type": "array"}, "plan": {"$ref": "#/components/schemas/PlanOut"}, "subscription_status": {"title": "Subscription Status", "type": "string"}, "allowed_countries": {"items": {"type": "string"}, "title": "Allowed Countries", "type": "array"}}, "required": ["org_id", "org_name", "org_slug", "api_key_prefix", "scopes", "plan", "subscription_status", "allowed_countries"], "title": "MeOut", "type": "object"}, "PlanOut": {"properties": {"code": {"examples": ["growth"], "title": "Code", "type": "string"}, "name": {"title": "Name", "type": "string"}, "included_calls_per_month": {"title": "Included Calls Per Month", "type": "integer"}, "overage_price_cents": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Wallet price of one extra call unit.", "title": "Overage Price Cents"}, "max_seats": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Seats"}, "max_countries": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Countries"}, "max_concurrent_calls": {"title": "Max Concurrent Calls", "type": "integer"}, "features": {"additionalProperties": {"type": "boolean"}, "title": "Features", "type": "object"}}, "required": ["code", "name", "included_calls_per_month", "overage_price_cents", "max_seats", "max_countries", "max_concurrent_calls", "features"], "title": "PlanOut", "type": "object"}, "MemberOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "email": {"title": "Email", "type": "string"}, "role": {"enum": ["admin", "member", "guest"], "title": "Role", "type": "string"}, "joined_at": {"format": "date-time", "title": "Joined At", "type": "string"}}, "required": ["id", "email", "role", "joined_at"], "title": "MemberOut", "type": "object"}, "Error": {"properties": {"detail": {"description": "Human readable explanation. Can change: do not parse it.", "title": "Detail", "type": "string"}, "code": {"description": "Stable machine-readable code, e.g. `missing_scope`, `feature_not_in_plan`, `not_found`. See the errors guide.", "examples": ["feature_not_in_plan"], "title": "Code", "type": "string"}, "feature": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "`feature_not_in_plan`: the plan feature that is missing, e.g. `release_compare`.", "title": "Feature"}, "required_plan": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Plan errors: the cheapest plan that includes the feature or lifts the limit.", "examples": ["growth"], "title": "Required Plan"}, "upgrade_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Plan errors: page where an admin upgrades in one click (Stripe, prorated), then comes back.", "title": "Upgrade Url"}}, "required": ["detail", "code"], "title": "Error", "type": "object"}, "InvitationIn": {"properties": {"email": {"examples": ["jane@example.com"], "title": "Email", "type": "string"}, "role": {"default": "member", "enum": ["admin", "member", "guest"], "title": "Role", "type": "string"}}, "required": ["email"], "title": "InvitationIn", "type": "object"}, "RoleIn": {"properties": {"role": {"enum": ["admin", "member", "guest"], "title": "Role", "type": "string"}}, "required": ["role"], "title": "RoleIn", "type": "object"}, "TargetOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "name": {"title": "Name", "type": "string"}, "phone": {"title": "Phone", "type": "string"}, "country": {"title": "Country", "type": "string"}, "line_type": {"title": "Line Type", "type": "string"}, "kind": {"title": "Kind", "type": "string"}, "platform": {"title": "Platform", "type": "string"}, "language": {"title": "Language", "type": "string"}, "description": {"title": "Description", "type": "string"}, "verification_status": {"enum": ["unverified", "pending", "verified", "expired", "locked", "suspended"], "title": "Verification Status", "type": "string"}, "verification_method": {"title": "Verification Method", "type": "string"}, "verified_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Verified At"}, "verification_expires_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Verification Expires At"}, "attested": {"description": "The legal attestation is signed (sandbox calls).", "title": "Attested", "type": "boolean"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "name", "phone", "country", "line_type", "kind", "platform", "language", "description", "verification_status", "verification_method", "verified_at", "verification_expires_at", "attested", "created_at"], "title": "TargetOut", "type": "object"}, "TargetIn": {"properties": {"name": {"examples": ["Booking bot (staging)"], "maxLength": 120, "title": "Name", "type": "string"}, "phone": {"description": "E.164 number, e.g. +14155550100.", "examples": ["+14155550100"], "title": "Phone", "type": "string"}, "kind": {"default": "unknown", "enum": ["ai_agent", "ivr", "iva", "human", "unknown"], "title": "Kind", "type": "string"}, "platform": {"default": "", "examples": ["vapi"], "title": "Platform", "type": "string"}, "language": {"default": "en-US", "title": "Language", "type": "string"}, "description": {"default": "", "title": "Description", "type": "string"}}, "required": ["name", "phone"], "title": "TargetIn", "type": "object"}, "TargetPatch": {"properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "kind": {"anyOf": [{"enum": ["ai_agent", "ivr", "iva", "human", "unknown"], "type": "string"}, {"type": "null"}], "title": "Kind"}, "platform": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Platform"}, "language": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Language"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}}, "title": "TargetPatch", "type": "object"}, "ActiveCode": {"properties": {"attempt_id": {"format": "uuid", "title": "Attempt Id", "type": "string"}, "method": {"title": "Method", "type": "string"}, "status": {"enum": ["pending", "calling"], "title": "Status", "type": "string"}, "expires_at": {"format": "date-time", "title": "Expires At", "type": "string"}, "call_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Call Id"}, "call_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Call Status"}, "dtmf_gate": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Keys pressed after the answer.", "title": "Dtmf Gate"}}, "required": ["attempt_id", "method", "status", "expires_at", "call_id", "call_status"], "title": "ActiveCode", "type": "object"}, "LastAttempt": {"properties": {"attempt_id": {"format": "uuid", "title": "Attempt Id", "type": "string"}, "method": {"title": "Method", "type": "string"}, "status": {"enum": ["succeeded", "failed", "error", "expired", "calling"], "title": "Status", "type": "string"}, "outcome": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "matched, not_heard, not_answered, wrong_code, call_not_placed...", "title": "Outcome"}, "heard_digits": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Digits we understood (the code is masked with * when it matched).", "title": "Heard Digits"}, "sip_status": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "When the line never answered: the SIP final answer of the destination (480 unavailable, 408 no answer, 486 busy, 603 declined, 404 unknown number...).", "examples": [480], "title": "Sip Status"}, "sip_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "The carrier's short reason for `sip_status`.", "examples": ["Temporarily Unavailable"], "title": "Sip Reason"}, "failure_hint": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "What to fix before the next attempt, in plain words (null when the attempt did not fail). Show it to the user as is.", "title": "Failure Hint"}, "call_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Call Id"}, "finished_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Finished At"}, "dtmf_gate": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Keys pressed after the answer.", "title": "Dtmf Gate"}}, "required": ["attempt_id", "method", "status", "outcome", "heard_digits", "call_id", "finished_at"], "title": "LastAttempt", "type": "object"}, "Sandbox": {"properties": {"calls_left_24h": {"title": "Calls Left 24H", "type": "integer"}, "max_concurrent_calls": {"title": "Max Concurrent Calls", "type": "integer"}, "max_duration_s": {"title": "Max Duration S", "type": "integer"}, "schedules_and_ci": {"title": "Schedules And Ci", "type": "boolean"}}, "required": ["calls_left_24h", "max_concurrent_calls", "max_duration_s", "schedules_and_ci"], "title": "Sandbox", "type": "object"}, "VerificationOut": {"properties": {"status": {"enum": ["unverified", "pending", "verified", "expired", "locked", "suspended"], "title": "Status", "type": "string"}, "method": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Method"}, "verified_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Verified At"}, "expires_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Re-verification needed after this date.", "title": "Expires At"}, "locked_until": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Locked Until"}, "suspended_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Suspended Reason"}, "attested": {"title": "Attested", "type": "boolean"}, "attested_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Attested At"}, "attestation_version": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Version of the signed text.", "title": "Attestation Version"}, "attestation_current_version": {"description": "Version to sign today.", "title": "Attestation Current Version", "type": "string"}, "attestation_outdated": {"default": false, "description": "Signed under a text that is no longer accepted: sign again, calls to this number are blocked until then.", "title": "Attestation Outdated", "type": "boolean"}, "attempts_left": {"description": "Failed attempts allowed before a 24 h lock. A call that is not answered counts too.", "title": "Attempts Left", "type": "integer"}, "attempts_max": {"default": 3, "description": "Failed attempts allowed per number in 24 h.", "title": "Attempts Max", "type": "integer"}, "attempts_reset_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the oldest failed attempt stops counting (24 h after it ended) and one attempt comes back; null when none counts.", "title": "Attempts Reset At"}, "dtmf_gate": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Keys remembered for the next verification call (IVR menu).", "title": "Dtmf Gate"}, "active_code": {"anyOf": [{"$ref": "#/components/schemas/ActiveCode"}, {"type": "null"}]}, "last_attempt": {"anyOf": [{"$ref": "#/components/schemas/LastAttempt"}, {"type": "null"}]}, "sandbox": {"anyOf": [{"$ref": "#/components/schemas/Sandbox"}, {"type": "null"}], "description": "Limits while the number is not verified (attestation signed)."}, "inbound_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Number to call for `inbound_dtmf`.", "title": "Inbound Number"}}, "required": ["status", "method", "verified_at", "expires_at", "locked_until", "suspended_reason", "attested", "attested_at", "attestation_current_version", "attempts_left", "active_code", "last_attempt", "sandbox", "inbound_number"], "title": "VerificationOut", "type": "object"}, "AttestIn": {"properties": {"accept": {"description": "Must be true: you accept the attestation text.", "title": "Accept", "type": "boolean"}, "signer_name": {"description": "Full name and title of the person attesting.", "examples": ["Jane Doe, CTO"], "title": "Signer Name", "type": "string"}}, "required": ["accept", "signer_name"], "title": "AttestIn", "type": "object"}, "VerificationCodeOut": {"properties": {"code": {"description": "Shown ONCE, never stored in clear: copy it now.", "examples": ["482193"], "title": "Code", "type": "string"}, "phrase": {"description": "Add this sentence to the greeting or the agent prompt.", "examples": ["Verification code 4 8 2 1 9 3."], "title": "Phrase", "type": "string"}, "code_expires_at": {"format": "date-time", "title": "Code Expires At", "type": "string"}, "method": {"title": "Method", "type": "string"}, "verification": {"$ref": "#/components/schemas/VerificationOut"}}, "required": ["code", "phrase", "code_expires_at", "method", "verification"], "title": "VerificationCodeOut", "type": "object"}, "VerificationStartIn": {"properties": {"method": {"default": "spoken_code", "description": "`spoken_code` (default): put the code in the line's greeting or agent prompt, then `POST .../verification/call`. `inbound_dtmf` (when enabled): call our verification number from the line and type the code.", "enum": ["spoken_code", "inbound_dtmf"], "title": "Method", "type": "string"}, "attestation": {"anyOf": [{"$ref": "#/components/schemas/AttestIn"}, {"type": "null"}], "description": "Sign the attestation in the same request (required once)."}, "dtmf_gate": {"anyOf": [{"maxLength": 64, "type": "string"}, {"type": "null"}], "description": "Keys the verification call presses after the line answers, before listening for the code, when the code is behind an IVR menu: 0-9, `*`, `#`, `w` for a 0.5 s pause (as in Twilio's sendDigits), at most 40 characters. Example: `1w2`. `{code}` types the code itself (reserved to CallQA test lines). Omitted: the keys remembered on the number; empty string: no keys.", "examples": ["1w2", "w9#"], "title": "Dtmf Gate"}, "renew": {"default": false, "description": "Verify a `verified` number again (renews the 180 days). The number stays `verified` during the attempt and if it fails.", "title": "Renew", "type": "boolean"}}, "title": "VerificationStartIn", "type": "object"}, "VerificationCallOut": {"properties": {"call_id": {"format": "uuid", "title": "Call Id", "type": "string"}, "verification": {"$ref": "#/components/schemas/VerificationOut"}}, "required": ["call_id", "verification"], "title": "VerificationCallOut", "type": "object"}, "VerificationCallIn": {"properties": {"dtmf_gate": {"anyOf": [{"maxLength": 64, "type": "string"}, {"type": "null"}], "description": "Replace the keys to press of the active code (see `start`). `{code}` only works when it was already given to `start` or `retry`.", "examples": ["1w2"], "title": "Dtmf Gate"}}, "title": "VerificationCallIn", "type": "object"}, "VerifyIn": {"properties": {"method": {"const": "attestation", "default": "attestation", "description": "Legacy endpoint: signs the attestation only.", "title": "Method", "type": "string"}, "accept": {"description": "Must be true: you accept the attestation text.", "title": "Accept", "type": "boolean"}, "signer_name": {"description": "Full name of the person attesting.", "examples": ["Jane Doe, CTO"], "title": "Signer Name", "type": "string"}}, "required": ["accept", "signer_name"], "title": "VerifyIn", "type": "object"}, "ScenarioInvalid": {"properties": {"detail": {"default": "invalid scenario", "title": "Detail", "type": "string"}, "code": {"default": "invalid_scenario", "title": "Code", "type": "string"}, "errors": {"items": {"$ref": "#/components/schemas/ValidationIssue"}, "title": "Errors", "type": "array"}}, "required": ["errors"], "title": "ScenarioInvalid", "type": "object"}, "ValidationIssue": {"properties": {"loc": {"description": "Dotted path of the offending field.", "examples": ["target.phone"], "title": "Loc", "type": "string"}, "msg": {"title": "Msg", "type": "string"}}, "required": ["loc", "msg"], "title": "ValidationIssue", "type": "object"}, "GenerationJobOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "kind": {"enum": ["propose", "derive", "edge_case"], "title": "Kind", "type": "string"}, "status": {"enum": ["queued", "running", "done", "error"], "title": "Status", "type": "string"}, "scenario_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Scenario Id"}, "call_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Call Id"}, "result": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "description": "When done. propose: {scenarios: [...], rejected}; derive: {variants: [...], rejected}; edge_case: {variant: {...}}.", "title": "Result"}, "error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error"}, "usage": {"additionalProperties": true, "title": "Usage", "type": "object"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "finished_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Finished At"}, "url": {"description": "Poll this URL until status is done or error.", "title": "Url", "type": "string"}}, "required": ["id", "kind", "status", "scenario_id", "call_id", "result", "error", "usage", "created_at", "finished_at", "url"], "title": "GenerationJobOut", "type": "object"}, "GenerateIn": {"properties": {"description": {"description": "What the voice service does, in plain words.", "examples": ["Hair salon booking line: book, move, cancel."], "title": "Description", "type": "string"}, "phone": {"examples": ["+14155550100"], "title": "Phone", "type": "string"}, "language": {"default": "en-US", "title": "Language", "type": "string"}, "count": {"default": 5, "maximum": 20, "minimum": 1, "title": "Count", "type": "integer"}}, "required": ["description", "phone"], "title": "GenerateIn", "type": "object"}, "DeriveIn": {"properties": {"count": {"default": 4, "maximum": 20, "minimum": 1, "title": "Count", "type": "integer"}}, "title": "DeriveIn", "type": "object"}, "ScenarioSummary": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "name": {"title": "Name", "type": "string"}, "target_id": {"format": "uuid", "title": "Target Id", "type": "string"}, "target_phone": {"title": "Target Phone", "type": "string"}, "source": {"title": "Source", "type": "string"}, "tags": {"items": {"type": "string"}, "title": "Tags", "type": "array"}, "variants": {"title": "Variants", "type": "integer"}, "archived": {"title": "Archived", "type": "boolean"}, "schedule": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Schedule"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "name", "target_id", "target_phone", "source", "tags", "variants", "archived", "schedule", "updated_at"], "title": "ScenarioSummary", "type": "object"}, "ComplianceOut": {"properties": {"status": {"description": "Compliance review of the current content: only `allow` can be run.", "enum": ["pending", "allow", "needs_review", "block"], "title": "Status", "type": "string"}, "label": {"title": "Label", "type": "string"}, "categories": {"items": {"type": "string"}, "title": "Categories", "type": "array"}, "reasons": {"items": {"$ref": "#/components/schemas/ComplianceReasonOut"}, "title": "Reasons", "type": "array"}, "reviewed_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reviewed At"}, "decided_by_staff": {"title": "Decided By Staff", "type": "boolean"}, "message": {"description": "What it means and what to do next.", "title": "Message", "type": "string"}, "enforced": {"title": "Enforced", "type": "boolean"}}, "required": ["status", "label", "categories", "reasons", "reviewed_at", "decided_by_staff", "message", "enforced"], "title": "ComplianceOut", "type": "object"}, "ComplianceReasonOut": {"properties": {"category": {"title": "Category", "type": "string"}, "quote": {"description": "Words of the scenario that caused the decision.", "title": "Quote", "type": "string"}, "explanation": {"title": "Explanation", "type": "string"}}, "required": ["category", "quote", "explanation"], "title": "ComplianceReasonOut", "type": "object"}, "ScenarioOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "name": {"title": "Name", "type": "string"}, "target_id": {"format": "uuid", "title": "Target Id", "type": "string"}, "target_phone": {"title": "Target Phone", "type": "string"}, "source": {"title": "Source", "type": "string"}, "tags": {"items": {"type": "string"}, "title": "Tags", "type": "array"}, "variants": {"title": "Variants", "type": "integer"}, "archived": {"title": "Archived", "type": "boolean"}, "schedule": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Schedule"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "document": {"additionalProperties": true, "description": "Full scenario document, variants included.", "title": "Document", "type": "object"}, "variant_list": {"items": {"$ref": "#/components/schemas/VariantOut"}, "title": "Variant List", "type": "array"}, "compliance": {"anyOf": [{"$ref": "#/components/schemas/ComplianceOut"}, {"type": "null"}], "description": "Compliance review (acceptable use policy) of this content."}}, "required": ["id", "name", "target_id", "target_phone", "source", "tags", "variants", "archived", "schedule", "updated_at", "document", "variant_list"], "title": "ScenarioOut", "type": "object"}, "VariantOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "index": {"title": "Index", "type": "integer"}, "title": {"title": "Title", "type": "string"}, "source": {"enum": ["auto", "manual"], "title": "Source", "type": "string"}, "enabled": {"title": "Enabled", "type": "boolean"}, "spec": {"additionalProperties": true, "description": "callqa_spec Variant document.", "title": "Spec", "type": "object"}}, "required": ["id", "index", "title", "source", "enabled", "spec"], "title": "VariantOut", "type": "object"}, "VariantIn": {"properties": {"title": {"title": "Title", "type": "string"}, "source": {"default": "manual", "enum": ["auto", "manual"], "title": "Source", "type": "string"}, "persona": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Persona"}, "goal": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Goal"}, "instructions": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Instructions"}, "test_data": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Test Data"}, "assertions": {"anyOf": [{"items": {"additionalProperties": true, "type": "object"}, "type": "array"}, {"type": "null"}], "title": "Assertions"}, "enabled": {"default": true, "title": "Enabled", "type": "boolean"}}, "required": ["title"], "title": "VariantIn", "type": "object"}, "FromBundleIn": {"properties": {"call_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Build the bundle from this call...", "title": "Call Id"}, "bundle": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "description": "...or pass a ReplayBundle.", "title": "Bundle"}, "title": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Title"}}, "title": "FromBundleIn", "type": "object"}, "VariantPatch": {"properties": {"enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Enabled"}, "spec": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "description": "Replace the variant document.", "title": "Spec"}}, "title": "VariantPatch", "type": "object"}, "CiOut": {"properties": {"threshold": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Threshold"}, "passed": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "null while the run is not finished.", "title": "Passed"}}, "required": ["threshold", "passed"], "title": "CiOut", "type": "object"}, "RunOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "number": {"title": "Number", "type": "integer"}, "scenario_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Scenario Id"}, "scenario_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Scenario Name"}, "trigger": {"title": "Trigger", "type": "string"}, "status": {"enum": ["queued", "running", "completed", "canceled"], "title": "Status", "type": "string"}, "verdict": {"anyOf": [{"enum": ["pass", "fail", "warn"], "type": "string"}, {"type": "null"}], "title": "Verdict"}, "score": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Score"}, "total": {"title": "Total", "type": "integer"}, "passed": {"title": "Passed", "type": "integer"}, "failed": {"title": "Failed", "type": "integer"}, "warned": {"title": "Warned", "type": "integer"}, "errored": {"title": "Errored", "type": "integer"}, "blocked": {"title": "Blocked", "type": "integer"}, "cost_cents": {"title": "Cost Cents", "type": "integer"}, "version": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Label of the run's version: the one the trigger named, else the one live in its environment when it ran.", "title": "Version"}, "version_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Version Id"}, "release": {"anyOf": [{"type": "string"}, {"type": "null"}], "deprecated": true, "description": "**Deprecated**: same value as `version`.", "title": "Release"}, "tags": {"items": {"type": "string"}, "title": "Tags", "type": "array"}, "environment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Slug of the run's environment.", "title": "Environment"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}, "finished_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Finished At"}, "ci": {"anyOf": [{"$ref": "#/components/schemas/CiOut"}, {"type": "null"}]}, "url": {"title": "Url", "type": "string"}}, "required": ["id", "number", "scenario_id", "scenario_name", "trigger", "status", "verdict", "score", "total", "passed", "failed", "warned", "errored", "blocked", "cost_cents", "version", "version_id", "release", "environment", "created_at", "started_at", "finished_at", "url"], "title": "RunOut", "type": "object"}, "TriggerIn": {"properties": {"variants": {"anyOf": [{"items": {"format": "uuid", "type": "string"}, "type": "array"}, {"type": "null"}], "description": "Subset of variant ids; default all enabled variants.", "title": "Variants"}, "version": {"anyOf": [{"maxLength": 60, "type": "string"}, {"type": "null"}], "description": "Version of your code under test (`v2.3.0`, a short sha), in the run's environment; created if new. Without it the run belongs to the version live in the environment.", "examples": ["v2.3.0"], "title": "Version"}, "git_ref": {"anyOf": [{"maxLength": 200, "type": "string"}, {"type": "null"}], "description": "Branch or tag of the version, stored when the version is created.", "examples": ["main"], "title": "Git Ref"}, "git_sha": {"anyOf": [{"maxLength": 64, "type": "string"}, {"type": "null"}], "examples": ["9f2c1ab"], "title": "Git Sha"}, "source_url": {"anyOf": [{"maxLength": 500, "type": "string"}, {"type": "null"}], "description": "Commit or pipeline page.", "title": "Source Url"}, "release": {"anyOf": [{"type": "string"}, {"type": "null"}], "deprecated": true, "description": "**Deprecated**: the former name of `version`, read when `version` is absent.", "title": "Release"}, "tags": {"description": "Free keywords added to the run.", "items": {"type": "string"}, "title": "Tags", "type": "array"}, "ci": {"default": false, "description": "Mark the run as triggered by CI.", "title": "Ci", "type": "boolean"}, "environment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Environment, by slug, name or id (`staging`). Default: the organization's default environment. The version, when given, is looked up (or created) in this environment.", "examples": ["staging"], "title": "Environment"}}, "title": "TriggerIn", "type": "object"}, "Page_RunOut_": {"properties": {"count": {"description": "Total number of matching items.", "title": "Count", "type": "integer"}, "limit": {"title": "Limit", "type": "integer"}, "offset": {"title": "Offset", "type": "integer"}, "items": {"items": {"$ref": "#/components/schemas/RunOut"}, "title": "Items", "type": "array"}}, "required": ["count", "limit", "offset", "items"], "title": "Page[RunOut]", "type": "object"}, "CallOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "run_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Run Id"}, "variant_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Variant Id"}, "title": {"title": "Title", "type": "string"}, "target_phone": {"title": "Target Phone", "type": "string"}, "status": {"title": "Status", "type": "string"}, "block_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Block Reason"}, "error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error"}, "verdict": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Verdict"}, "score": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Score"}, "duration_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Duration Ms"}, "latency_p50_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Latency P50 Ms"}, "latency_p95_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Latency P95 Ms"}, "latency_max_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Latency Max Ms"}, "cost_cents": {"title": "Cost Cents", "type": "integer"}, "quota_units": {"title": "Quota Units", "type": "integer"}, "replay_of": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Replay Of"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "dispatched_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Dispatched At"}, "completed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Completed At"}, "content_purged_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the call's content (trace, transcript, detailed evaluation) was deleted at the end of the plan's retention period. Score, verdict, latencies and cost remain.", "title": "Content Purged At"}}, "required": ["id", "run_id", "variant_id", "title", "target_phone", "status", "block_reason", "error", "verdict", "score", "duration_ms", "latency_p50_ms", "latency_p95_ms", "latency_max_ms", "cost_cents", "quota_units", "replay_of", "created_at", "dispatched_at", "completed_at"], "title": "CallOut", "type": "object"}, "Page_CallOut_": {"properties": {"count": {"description": "Total number of matching items.", "title": "Count", "type": "integer"}, "limit": {"title": "Limit", "type": "integer"}, "offset": {"title": "Offset", "type": "integer"}, "items": {"items": {"$ref": "#/components/schemas/CallOut"}, "title": "Items", "type": "array"}}, "required": ["count", "limit", "offset", "items"], "title": "Page[CallOut]", "type": "object"}, "CallDetailOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "run_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Run Id"}, "variant_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Variant Id"}, "title": {"title": "Title", "type": "string"}, "target_phone": {"title": "Target Phone", "type": "string"}, "status": {"title": "Status", "type": "string"}, "block_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Block Reason"}, "error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error"}, "verdict": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Verdict"}, "score": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Score"}, "duration_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Duration Ms"}, "latency_p50_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Latency P50 Ms"}, "latency_p95_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Latency P95 Ms"}, "latency_max_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Latency Max Ms"}, "cost_cents": {"title": "Cost Cents", "type": "integer"}, "quota_units": {"title": "Quota Units", "type": "integer"}, "replay_of": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Replay Of"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "dispatched_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Dispatched At"}, "completed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Completed At"}, "content_purged_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the call's content (trace, transcript, detailed evaluation) was deleted at the end of the plan's retention period. Score, verdict, latencies and cost remain.", "title": "Content Purged At"}, "run": {"additionalProperties": true, "description": "The ResolvedRun that was dialed.", "title": "Run", "type": "object"}, "result": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "description": "CallResult: verdicts, metrics, score.", "title": "Result"}, "transcript": {"items": {"$ref": "#/components/schemas/TurnOut"}, "title": "Transcript", "type": "array"}, "recording": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Recording"}, "usage": {"additionalProperties": true, "title": "Usage", "type": "object"}, "cost_breakdown": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "description": "Our measured cost of the call in USD (telephony, STT, TTS, LLM, judge). Not what you are charged: see cost_cents.", "title": "Cost Breakdown"}}, "required": ["id", "run_id", "variant_id", "title", "target_phone", "status", "block_reason", "error", "verdict", "score", "duration_ms", "latency_p50_ms", "latency_p95_ms", "latency_max_ms", "cost_cents", "quota_units", "replay_of", "created_at", "dispatched_at", "completed_at", "run", "result", "transcript", "recording", "usage"], "title": "CallDetailOut", "type": "object"}, "TurnOut": {"properties": {"t_ms": {"title": "T Ms", "type": "integer"}, "speaker": {"title": "Speaker", "type": "string"}, "text": {"title": "Text", "type": "string"}, "start_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Start Ms"}, "end_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "End Ms"}}, "required": ["t_ms", "speaker", "text", "start_ms", "end_ms"], "title": "TurnOut", "type": "object"}, "EventOut": {"properties": {"seq": {"title": "Seq", "type": "integer"}, "t_ms": {"title": "T Ms", "type": "integer"}, "at": {"format": "date-time", "title": "At", "type": "string"}, "type": {"title": "Type", "type": "string"}, "data": {"additionalProperties": true, "title": "Data", "type": "object"}}, "required": ["seq", "t_ms", "at", "type", "data"], "title": "EventOut", "type": "object"}, "Page_EventOut_": {"properties": {"count": {"description": "Total number of matching items.", "title": "Count", "type": "integer"}, "limit": {"title": "Limit", "type": "integer"}, "offset": {"title": "Offset", "type": "integer"}, "items": {"items": {"$ref": "#/components/schemas/EventOut"}, "title": "Items", "type": "array"}}, "required": ["count", "limit", "offset", "items"], "title": "Page[EventOut]", "type": "object"}, "ReplayIn": {"properties": {"call_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Replay this call of your organization...", "title": "Call Id"}, "bundle": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "description": "...or an exported ReplayBundle.", "title": "Bundle"}, "same_runtime": {"default": true, "description": "Reuse the bundle's models, voices and settings (exact reproduction).", "title": "Same Runtime", "type": "boolean"}}, "title": "ReplayIn", "type": "object"}, "TagSuggestion": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "color": {"title": "Color", "type": "string"}, "uses": {"description": "Objects carrying the tag (scenarios, runs, versions, numbers).", "title": "Uses", "type": "integer"}}, "required": ["id", "name", "color", "uses"], "title": "TagSuggestion", "type": "object"}, "TagOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "color": {"title": "Color", "type": "string"}}, "required": ["id", "name", "color"], "title": "TagOut", "type": "object"}, "TagIn": {"properties": {"name": {"examples": ["checkout"], "maxLength": 40, "minLength": 1, "title": "Name", "type": "string"}, "color": {"default": "#1d7c70", "pattern": "^#[0-9a-fA-F]{6}$", "title": "Color", "type": "string"}}, "required": ["name"], "title": "TagIn", "type": "object"}, "TagBulkOut": {"properties": {"added": {"items": {"type": "string"}, "title": "Added", "type": "array"}, "removed": {"items": {"type": "string"}, "title": "Removed", "type": "array"}, "objects": {"additionalProperties": {"type": "integer"}, "description": "Objects touched, per kind.", "title": "Objects", "type": "object"}}, "required": ["added", "removed", "objects"], "title": "TagBulkOut", "type": "object"}, "TagBulkIn": {"properties": {"add": {"description": "Tags to add, created if new.", "examples": [["julia", "acme"]], "items": {"type": "string"}, "title": "Add", "type": "array"}, "remove": {"description": "Tags to remove.", "items": {"type": "string"}, "title": "Remove", "type": "array"}, "objects": {"$ref": "#/components/schemas/TagObjects"}}, "required": ["objects"], "title": "TagBulkIn", "type": "object"}, "TagObjects": {"properties": {"scenarios": {"items": {"format": "uuid", "type": "string"}, "title": "Scenarios", "type": "array"}, "runs": {"items": {"format": "uuid", "type": "string"}, "title": "Runs", "type": "array"}, "versions": {"items": {"format": "uuid", "type": "string"}, "title": "Versions", "type": "array"}, "numbers": {"description": "Phone numbers (targets).", "items": {"format": "uuid", "type": "string"}, "title": "Numbers", "type": "array"}}, "title": "TagObjects", "type": "object"}, "TagPatch": {"properties": {"name": {"anyOf": [{"maxLength": 40, "minLength": 1, "type": "string"}, {"type": "null"}], "title": "Name"}, "color": {"anyOf": [{"pattern": "^#[0-9a-fA-F]{6}$", "type": "string"}, {"type": "null"}], "title": "Color"}}, "title": "TagPatch", "type": "object"}, "Page_VersionOut_": {"properties": {"count": {"description": "Total number of matching items.", "title": "Count", "type": "integer"}, "limit": {"title": "Limit", "type": "integer"}, "offset": {"title": "Offset", "type": "integer"}, "items": {"items": {"$ref": "#/components/schemas/VersionOut"}, "title": "Items", "type": "array"}}, "required": ["count", "limit", "offset", "items"], "title": "Page[VersionOut]", "type": "object"}, "VersionOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "label": {"title": "Label", "type": "string"}, "environment": {"description": "Slug of the version's environment.", "title": "Environment", "type": "string"}, "deployed_at": {"format": "date-time", "title": "Deployed At", "type": "string"}, "git_ref": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Git Ref"}, "git_sha": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Git Sha"}, "source_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Source Url"}, "notes": {"title": "Notes", "type": "string"}, "target_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Target Id"}, "tags": {"items": {"type": "string"}, "title": "Tags", "type": "array"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "label", "environment", "deployed_at", "git_ref", "git_sha", "source_url", "notes", "target_id", "tags", "created_at"], "title": "VersionOut", "type": "object"}, "VersionIn": {"properties": {"label": {"examples": ["v2.3.0"], "maxLength": 60, "minLength": 1, "title": "Label", "type": "string"}, "environment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Environment, by slug, name or id (`staging`). Default: the organization's default environment.", "examples": ["staging"], "title": "Environment"}, "deployed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When it went live. Default: now.", "title": "Deployed At"}, "git_ref": {"default": "", "examples": ["main"], "maxLength": 200, "title": "Git Ref", "type": "string"}, "git_sha": {"default": "", "examples": ["9f2c1ab4e0"], "maxLength": 64, "title": "Git Sha", "type": "string"}, "source_url": {"default": "", "examples": ["https://github.com/acme/agent/commit/9f2c1ab"], "maxLength": 500, "title": "Source Url", "type": "string"}, "notes": {"default": "", "title": "Notes", "type": "string"}, "target_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Only for this phone number (default: every number).", "title": "Target Id"}, "tags": {"items": {"type": "string"}, "title": "Tags", "type": "array"}}, "required": ["label"], "title": "VersionIn", "type": "object"}, "VersionPatch": {"properties": {"label": {"anyOf": [{"maxLength": 60, "minLength": 1, "type": "string"}, {"type": "null"}], "title": "Label"}, "deployed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Deployed At"}, "git_ref": {"anyOf": [{"maxLength": 200, "type": "string"}, {"type": "null"}], "title": "Git Ref"}, "git_sha": {"anyOf": [{"maxLength": 64, "type": "string"}, {"type": "null"}], "title": "Git Sha"}, "source_url": {"anyOf": [{"maxLength": 500, "type": "string"}, {"type": "null"}], "title": "Source Url"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "target_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Send null to apply the version to every number.", "title": "Target Id"}, "tags": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Replaces the tags.", "title": "Tags"}}, "title": "VersionPatch", "type": "object"}, "VersionPromoteIn": {"properties": {"environment": {"description": "Environment to promote to, by slug, name or id.", "examples": ["production"], "title": "Environment", "type": "string"}, "deployed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Default: now.", "title": "Deployed At"}}, "required": ["environment"], "title": "VersionPromoteIn", "type": "object"}, "ReleaseOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "version": {"title": "Version", "type": "string"}, "notes": {"title": "Notes", "type": "string"}, "released_at": {"format": "date-time", "title": "Released At", "type": "string"}, "target_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Target Id"}, "environment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Slug of the release's environment.", "title": "Environment"}}, "required": ["id", "version", "notes", "released_at", "target_id", "environment"], "title": "ReleaseOut", "type": "object"}, "ReleaseIn": {"properties": {"version": {"examples": ["v2.2.0"], "maxLength": 60, "minLength": 1, "title": "Version", "type": "string"}, "notes": {"default": "", "title": "Notes", "type": "string"}, "released_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Released At"}, "target_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Target Id"}, "environment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Environment, by slug, name or id (`staging`). Default: the organization's default environment.", "examples": ["staging"], "title": "Environment"}}, "required": ["version"], "title": "ReleaseIn", "type": "object"}, "ReleasePatch": {"properties": {"version": {"anyOf": [{"maxLength": 60, "minLength": 1, "type": "string"}, {"type": "null"}], "title": "Version"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "released_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Released At"}, "target_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Send null to detach the release from its target.", "title": "Target Id"}}, "title": "ReleasePatch", "type": "object"}, "PromoteIn": {"properties": {"environment": {"description": "Environment to promote to, by slug, name or id.", "examples": ["production"], "title": "Environment", "type": "string"}, "released_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Default: now.", "title": "Released At"}}, "required": ["environment"], "title": "PromoteIn", "type": "object"}, "EnvironmentNumberOut": {"properties": {"target_id": {"format": "uuid", "title": "Target Id", "type": "string"}, "target_phone": {"title": "Target Phone", "type": "string"}, "number_id": {"format": "uuid", "title": "Number Id", "type": "string"}, "number_phone": {"title": "Number Phone", "type": "string"}}, "required": ["target_id", "target_phone", "number_id", "number_phone"], "title": "EnvironmentNumberOut", "type": "object"}, "EnvironmentOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "name": {"title": "Name", "type": "string"}, "slug": {"title": "Slug", "type": "string"}, "order": {"title": "Order", "type": "integer"}, "color": {"title": "Color", "type": "string"}, "is_default": {"title": "Is Default", "type": "boolean"}, "numbers": {"items": {"$ref": "#/components/schemas/EnvironmentNumberOut"}, "title": "Numbers", "type": "array"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "name", "slug", "order", "color", "is_default", "numbers", "created_at"], "title": "EnvironmentOut", "type": "object"}, "EnvironmentIn": {"properties": {"name": {"examples": ["Staging"], "maxLength": 40, "minLength": 1, "title": "Name", "type": "string"}, "order": {"anyOf": [{"maximum": 1000, "minimum": 0, "type": "integer"}, {"type": "null"}], "description": "Promotion order, smallest first (development 10, staging 20, production 30). Default: after the last one.", "title": "Order"}, "color": {"anyOf": [{"type": "string"}, {"type": "null"}], "examples": ["#fbbf24"], "title": "Color"}, "is_default": {"default": false, "description": "Runs that name no environment go here.", "title": "Is Default", "type": "boolean"}}, "required": ["name"], "title": "EnvironmentIn", "type": "object"}, "StabilityOut": {"properties": {"environment": {"title": "Environment", "type": "string"}, "tests": {"title": "Tests", "type": "integer"}, "pass_rate": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Pass Rate"}, "avg_score": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Avg Score"}, "p95_latency_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "P95 Latency Ms"}, "flaky": {"description": "Test cases that both passed and failed in the period.", "title": "Flaky", "type": "integer"}, "last_run_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Last Run Id"}, "last_run_verdict": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Last Run Verdict"}}, "required": ["environment", "tests", "pass_rate", "avg_score", "p95_latency_ms", "flaky", "last_run_id", "last_run_verdict"], "title": "StabilityOut", "type": "object"}, "CompareOut": {"properties": {"a": {"title": "A", "type": "string"}, "b": {"title": "B", "type": "string"}, "kpis_a": {"$ref": "#/components/schemas/KpisOut"}, "kpis_b": {"$ref": "#/components/schemas/KpisOut"}, "scenarios": {"items": {"$ref": "#/components/schemas/ScenarioCompareOut"}, "title": "Scenarios", "type": "array"}, "verdict_changes": {"items": {"$ref": "#/components/schemas/VerdictDiffOut"}, "title": "Verdict Changes", "type": "array"}}, "required": ["a", "b", "kpis_a", "kpis_b", "scenarios", "verdict_changes"], "title": "CompareOut", "type": "object"}, "KpisOut": {"properties": {"tests": {"title": "Tests", "type": "integer"}, "passed": {"title": "Passed", "type": "integer"}, "failed": {"title": "Failed", "type": "integer"}, "warned": {"title": "Warned", "type": "integer"}, "pass_rate": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Pass Rate"}, "avg_score": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Avg Score"}, "avg_latency_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Avg Latency Ms"}, "p95_latency_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "P95 Latency Ms"}, "interruptions_per_call": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Interruptions Per Call"}, "cost_cents": {"title": "Cost Cents", "type": "integer"}}, "required": ["tests", "passed", "failed", "warned", "pass_rate", "avg_score", "avg_latency_ms", "p95_latency_ms", "interruptions_per_call", "cost_cents"], "title": "KpisOut", "type": "object"}, "ScenarioCompareOut": {"properties": {"scenario_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Scenario Id"}, "name": {"title": "Name", "type": "string"}, "a": {"anyOf": [{"$ref": "#/components/schemas/SideScore"}, {"type": "null"}]}, "b": {"anyOf": [{"$ref": "#/components/schemas/SideScore"}, {"type": "null"}]}, "score_delta": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Score Delta"}}, "required": ["scenario_id", "name", "a", "b", "score_delta"], "title": "ScenarioCompareOut", "type": "object"}, "SideScore": {"properties": {"tests": {"title": "Tests", "type": "integer"}, "pass_rate": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Pass Rate"}, "score": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Score"}, "latency_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Latency Ms"}}, "required": ["tests", "pass_rate", "score", "latency_ms"], "title": "SideScore", "type": "object"}, "VerdictDiffOut": {"properties": {"scenario": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Scenario"}, "index": {"title": "Index", "type": "integer"}, "title": {"title": "Title", "type": "string"}, "a": {"title": "A", "type": "string"}, "b": {"title": "B", "type": "string"}, "a_call_id": {"format": "uuid", "title": "A Call Id", "type": "string"}, "b_call_id": {"format": "uuid", "title": "B Call Id", "type": "string"}, "regressed": {"description": "True when the test case passes on side A only.", "title": "Regressed", "type": "boolean"}}, "required": ["scenario", "index", "title", "a", "b", "a_call_id", "b_call_id", "regressed"], "title": "VerdictDiffOut", "type": "object"}, "EnvironmentPatch": {"properties": {"name": {"anyOf": [{"maxLength": 40, "minLength": 1, "type": "string"}, {"type": "null"}], "title": "Name"}, "order": {"anyOf": [{"maximum": 1000, "minimum": 0, "type": "integer"}, {"type": "null"}], "title": "Order"}, "color": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Color"}, "is_default": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Only `true` is accepted: make another environment the default to change it.", "title": "Is Default"}}, "title": "EnvironmentPatch", "type": "object"}, "NumberIn": {"properties": {"target_id": {"description": "The number the scenarios point to.", "format": "uuid", "title": "Target Id", "type": "string"}, "number_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "The number to dial instead in this environment (registered and verified); null or equal to `target_id` removes the mapping.", "title": "Number Id"}}, "required": ["target_id", "number_id"], "title": "NumberIn", "type": "object"}, "BindingOut": {"properties": {"scenario_id": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "scenario_name": {"title": "Scenario Name", "type": "string"}, "environment": {"description": "Environment slug.", "title": "Environment", "type": "string"}, "enabled": {"title": "Enabled", "type": "boolean"}, "schedule": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Schedule"}, "cron": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "The schedule as a cron expression, in `timezone`.", "title": "Cron"}, "timezone": {"title": "Timezone", "type": "string"}, "call_window": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Call Window"}, "schedule_enabled": {"title": "Schedule Enabled", "type": "boolean"}, "next_run_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Next Run At"}, "last_run_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Last Run At"}, "number_phone": {"description": "The number dialed in this environment.", "title": "Number Phone", "type": "string"}}, "required": ["scenario_id", "scenario_name", "environment", "enabled", "schedule", "cron", "timezone", "call_window", "schedule_enabled", "next_run_at", "last_run_at", "number_phone"], "title": "BindingOut", "type": "object"}, "BulkBindingOut": {"properties": {"action": {"title": "Action", "type": "string"}, "environment": {"title": "Environment", "type": "string"}, "scenarios": {"title": "Scenarios", "type": "integer"}, "bindings": {"items": {"$ref": "#/components/schemas/BindingOut"}, "title": "Bindings", "type": "array"}}, "required": ["action", "environment", "scenarios", "bindings"], "title": "BulkBindingOut", "type": "object"}, "BulkBindingIn": {"properties": {"enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Run the scenario in this environment. A new binding is enabled unless `false`.", "title": "Enabled"}, "schedule": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Cron expression or `every day at 09:00`. `\"\"` removes the schedule; absent keeps it.", "examples": ["every weekday at 08:30"], "title": "Schedule"}, "timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "IANA zone of the schedule. Absent keeps it (or the one written in `schedule`).", "examples": ["Europe/Paris"], "title": "Timezone"}, "call_window": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "`HH:MM-HH:MM Area/City`; scheduled calls wait for it. Without a zone, the schedule's zone. `\"\"` removes it.", "examples": ["08:00-20:00"], "title": "Call Window"}, "schedule_enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Pause (`false`) or resume the schedule without losing it.", "title": "Schedule Enabled"}, "scenario_ids": {"items": {"format": "uuid", "type": "string"}, "maxItems": 500, "minItems": 1, "title": "Scenario Ids", "type": "array"}, "action": {"description": "`enable`: activate (created if needed); `disable`: keep the binding and its schedule but do not run; `remove`: delete the binding.", "enum": ["enable", "disable", "remove"], "title": "Action", "type": "string"}}, "required": ["scenario_ids", "action"], "title": "BulkBindingIn", "type": "object"}, "BindingIn": {"properties": {"enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Run the scenario in this environment. A new binding is enabled unless `false`.", "title": "Enabled"}, "schedule": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Cron expression or `every day at 09:00`. `\"\"` removes the schedule; absent keeps it.", "examples": ["every weekday at 08:30"], "title": "Schedule"}, "timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "IANA zone of the schedule. Absent keeps it (or the one written in `schedule`).", "examples": ["Europe/Paris"], "title": "Timezone"}, "call_window": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "`HH:MM-HH:MM Area/City`; scheduled calls wait for it. Without a zone, the schedule's zone. `\"\"` removes it.", "examples": ["08:00-20:00"], "title": "Call Window"}, "schedule_enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Pause (`false`) or resume the schedule without losing it.", "title": "Schedule Enabled"}}, "title": "BindingIn", "type": "object"}, "MatrixCell": {"properties": {"environment": {"title": "Environment", "type": "string"}, "bound": {"title": "Bound", "type": "boolean"}, "enabled": {"title": "Enabled", "type": "boolean"}, "schedule": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Schedule"}, "timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Timezone"}, "call_window": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Call Window"}, "schedule_enabled": {"title": "Schedule Enabled", "type": "boolean"}, "next_run_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Next Run At"}, "running": {"description": "A run is queued or in progress.", "title": "Running", "type": "boolean"}, "last_run": {"anyOf": [{"$ref": "#/components/schemas/MatrixRun"}, {"type": "null"}], "description": "Last completed run."}, "trend": {"$ref": "#/components/schemas/MatrixTrend"}}, "required": ["environment", "bound", "enabled", "schedule", "timezone", "call_window", "schedule_enabled", "next_run_at", "running", "last_run", "trend"], "title": "MatrixCell", "type": "object"}, "MatrixEntry": {"properties": {"scenario_id": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "name": {"title": "Name", "type": "string"}, "run_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Run Id"}, "score": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Score"}}, "required": ["scenario_id", "name", "run_id", "score"], "title": "MatrixEntry", "type": "object"}, "MatrixEnvironment": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "slug": {"title": "Slug", "type": "string"}, "name": {"title": "Name", "type": "string"}, "color": {"title": "Color", "type": "string"}, "order": {"title": "Order", "type": "integer"}, "is_default": {"title": "Is Default", "type": "boolean"}}, "required": ["id", "slug", "name", "color", "order", "is_default"], "title": "MatrixEnvironment", "type": "object"}, "MatrixOut": {"properties": {"environments": {"items": {"$ref": "#/components/schemas/MatrixEnvironment"}, "title": "Environments", "type": "array"}, "scenarios": {"items": {"$ref": "#/components/schemas/MatrixScenario"}, "title": "Scenarios", "type": "array"}, "versions": {"description": "The last versions of each environment, newest first per environment.", "items": {"$ref": "#/components/schemas/MatrixVersionRow"}, "title": "Versions", "type": "array"}, "totals": {"additionalProperties": {"$ref": "#/components/schemas/MatrixTotals"}, "description": "Per environment slug, over the enabled scenarios: last verdicts.", "title": "Totals", "type": "object"}}, "required": ["environments", "scenarios", "versions", "totals"], "title": "MatrixOut", "type": "object"}, "MatrixRun": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "number": {"title": "Number", "type": "integer"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "verdict": {"enum": ["pass", "warn", "fail"], "title": "Verdict", "type": "string"}, "score": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Score"}, "total": {"title": "Total", "type": "integer"}, "passed": {"title": "Passed", "type": "integer"}, "version": {"anyOf": [{"$ref": "#/components/schemas/MatrixVersion"}, {"type": "null"}]}}, "required": ["id", "number", "created_at", "verdict", "score", "total", "passed", "version"], "title": "MatrixRun", "type": "object"}, "MatrixScenario": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "name": {"title": "Name", "type": "string"}, "target_phone": {"title": "Target Phone", "type": "string"}, "tags": {"items": {"type": "string"}, "title": "Tags", "type": "array"}, "cells": {"description": "One per environment, in `environments` order.", "items": {"$ref": "#/components/schemas/MatrixCell"}, "title": "Cells", "type": "array"}}, "required": ["id", "name", "target_phone", "tags", "cells"], "title": "MatrixScenario", "type": "object"}, "MatrixTotals": {"properties": {"passed": {"title": "Passed", "type": "integer"}, "warned": {"title": "Warned", "type": "integer"}, "failed": {"title": "Failed", "type": "integer"}, "untested": {"title": "Untested", "type": "integer"}, "running": {"title": "Running", "type": "integer"}}, "required": ["passed", "warned", "failed", "untested", "running"], "title": "MatrixTotals", "type": "object"}, "MatrixTrend": {"properties": {"scores": {"description": "Scores of the last completed runs, oldest first.", "items": {"anyOf": [{"type": "integer"}, {"type": "null"}]}, "title": "Scores", "type": "array"}, "direction": {"anyOf": [{"enum": ["up", "down", "flat"], "type": "string"}, {"type": "null"}], "title": "Direction"}}, "required": ["scores", "direction"], "title": "MatrixTrend", "type": "object"}, "MatrixVersion": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "label": {"title": "Label", "type": "string"}, "git_sha": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Git Sha"}, "deployed_at": {"format": "date-time", "title": "Deployed At", "type": "string"}}, "required": ["id", "label", "git_sha", "deployed_at"], "title": "MatrixVersion", "type": "object"}, "MatrixVersionRow": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "label": {"title": "Label", "type": "string"}, "environment": {"title": "Environment", "type": "string"}, "deployed_at": {"format": "date-time", "title": "Deployed At", "type": "string"}, "git_ref": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Git Ref"}, "git_sha": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Git Sha"}, "source_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Source Url"}, "tags": {"items": {"type": "string"}, "title": "Tags", "type": "array"}, "passed": {"items": {"$ref": "#/components/schemas/MatrixEntry"}, "title": "Passed", "type": "array"}, "warned": {"items": {"$ref": "#/components/schemas/MatrixEntry"}, "title": "Warned", "type": "array"}, "failed": {"items": {"$ref": "#/components/schemas/MatrixEntry"}, "title": "Failed", "type": "array"}, "untested": {"description": "Enabled in the environment, no run on this version.", "items": {"$ref": "#/components/schemas/MatrixEntry"}, "title": "Untested", "type": "array"}}, "required": ["id", "label", "environment", "deployed_at", "git_ref", "git_sha", "source_url", "tags", "passed", "warned", "failed", "untested"], "title": "MatrixVersionRow", "type": "object"}, "WebhookFilters": {"properties": {"scenario_ids": {"description": "Only events of these scenarios.", "items": {"format": "uuid", "type": "string"}, "title": "Scenario Ids", "type": "array"}, "tags": {"description": "Only events of scenarios or runs carrying one of these tags.", "examples": [["smoke"]], "items": {"type": "string"}, "title": "Tags", "type": "array"}, "environments": {"description": "Only events of these environments (slug, name or id).", "examples": [["production"]], "items": {"type": "string"}, "title": "Environments", "type": "array"}}, "title": "WebhookFilters", "type": "object"}, "WebhookOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "url": {"title": "Url", "type": "string"}, "events": {"items": {"type": "string"}, "title": "Events", "type": "array"}, "description": {"title": "Description", "type": "string"}, "enabled": {"title": "Enabled", "type": "boolean"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "filters": {"$ref": "#/components/schemas/WebhookFilters"}, "previous_secret_expires_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "While set and in the future, deliveries carry a second `v1` signature made with the previous secret.", "title": "Previous Secret Expires At"}}, "required": ["id", "url", "events", "description", "enabled", "created_at", "filters"], "title": "WebhookOut", "type": "object"}, "WebhookCreated": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "url": {"title": "Url", "type": "string"}, "events": {"items": {"type": "string"}, "title": "Events", "type": "array"}, "description": {"title": "Description", "type": "string"}, "enabled": {"title": "Enabled", "type": "boolean"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "filters": {"$ref": "#/components/schemas/WebhookFilters"}, "previous_secret_expires_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "While set and in the future, deliveries carry a second `v1` signature made with the previous secret.", "title": "Previous Secret Expires At"}, "secret": {"description": "Signing secret. Shown only once.", "title": "Secret", "type": "string"}}, "required": ["id", "url", "events", "description", "enabled", "created_at", "filters", "secret"], "title": "WebhookCreated", "type": "object"}, "WebhookIn": {"properties": {"url": {"examples": ["https://example.com/hooks/callqa"], "maxLength": 500, "title": "Url", "type": "string"}, "events": {"description": "Event types, or ['*'] for all.", "examples": [["suite_run.completed", "call.failed"]], "items": {"type": "string"}, "title": "Events", "type": "array"}, "description": {"default": "", "maxLength": 120, "title": "Description", "type": "string"}, "enabled": {"default": true, "title": "Enabled", "type": "boolean"}, "filters": {"anyOf": [{"$ref": "#/components/schemas/WebhookFilters"}, {"type": "null"}], "description": "Optional scope. Each non-empty list must match (any value of a list, all lists). Call, run and version events are filtered; organization events (`wallet.low_balance`) always go through. Empty or absent: every event."}}, "required": ["url", "events"], "title": "WebhookIn", "type": "object"}, "WebhookPatch": {"properties": {"url": {"anyOf": [{"maxLength": 500, "type": "string"}, {"type": "null"}], "title": "Url"}, "events": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "title": "Events"}, "description": {"anyOf": [{"maxLength": 120, "type": "string"}, {"type": "null"}], "title": "Description"}, "enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Enabled"}, "filters": {"anyOf": [{"$ref": "#/components/schemas/WebhookFilters"}, {"type": "null"}], "description": "Optional scope. Each non-empty list must match (any value of a list, all lists). Call, run and version events are filtered; organization events (`wallet.low_balance`) always go through. Empty or absent: every event. Send `{}` or null to remove every filter."}}, "title": "WebhookPatch", "type": "object"}, "SecretRotateIn": {"properties": {"grace_period_hours": {"default": 24, "description": "How long the previous secret keeps signing deliveries (second `v1`). 0 stops it at once.", "maximum": 168, "minimum": 0, "title": "Grace Period Hours", "type": "integer"}}, "title": "SecretRotateIn", "type": "object"}, "DeliveryOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "event_type": {"title": "Event Type", "type": "string"}, "status": {"title": "Status", "type": "string"}, "attempts": {"title": "Attempts", "type": "integer"}, "last_status_code": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Last Status Code"}, "last_error": {"title": "Last Error", "type": "string"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "delivered_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Delivered At"}}, "required": ["id", "event_type", "status", "attempts", "last_status_code", "last_error", "created_at", "delivered_at"], "title": "DeliveryOut", "type": "object"}, "Page_DeliveryOut_": {"properties": {"count": {"description": "Total number of matching items.", "title": "Count", "type": "integer"}, "limit": {"title": "Limit", "type": "integer"}, "offset": {"title": "Offset", "type": "integer"}, "items": {"items": {"$ref": "#/components/schemas/DeliveryOut"}, "title": "Items", "type": "array"}}, "required": ["count", "limit", "offset", "items"], "title": "Page[DeliveryOut]", "type": "object"}, "AlertChannelOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "kind": {"enum": ["slack", "email"], "title": "Kind", "type": "string"}, "config": {"additionalProperties": true, "description": "Slack: `{webhook_url}` masked (it is a secret). Email: `{to}`.", "title": "Config", "type": "object"}, "on_failure": {"title": "On Failure", "type": "boolean"}, "on_score_below": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "On Score Below"}, "on_latency_p95_above_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "On Latency P95 Above Ms"}, "enabled": {"title": "Enabled", "type": "boolean"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "name", "kind", "config", "on_failure", "on_score_below", "on_latency_p95_above_ms", "enabled", "created_at"], "title": "AlertChannelOut", "type": "object"}, "AlertChannelIn": {"properties": {"name": {"examples": ["#voice-alerts"], "maxLength": 80, "minLength": 1, "title": "Name", "type": "string"}, "kind": {"enum": ["slack", "email"], "title": "Kind", "type": "string"}, "webhook_url": {"anyOf": [{"maxLength": 500, "type": "string"}, {"type": "null"}], "description": "Slack only: incoming webhook URL (https://hooks.slack.com/services/...).", "title": "Webhook Url"}, "to": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Email only: up to 10 recipients.", "examples": [["oncall@example.com"]], "title": "To"}, "on_failure": {"default": true, "description": "Alert when a run fails.", "title": "On Failure", "type": "boolean"}, "on_score_below": {"anyOf": [{"maximum": 100, "minimum": 0, "type": "integer"}, {"type": "null"}], "description": "Alert when the run score is under this.", "title": "On Score Below"}, "on_latency_p95_above_ms": {"anyOf": [{"maximum": 60000, "minimum": 1, "type": "integer"}, {"type": "null"}], "description": "Alert when a call's p95 latency is above this.", "title": "On Latency P95 Above Ms"}, "enabled": {"default": true, "title": "Enabled", "type": "boolean"}}, "required": ["name", "kind"], "title": "AlertChannelIn", "type": "object"}, "AlertChannelPatch": {"properties": {"name": {"anyOf": [{"maxLength": 80, "minLength": 1, "type": "string"}, {"type": "null"}], "title": "Name"}, "webhook_url": {"anyOf": [{"maxLength": 500, "type": "string"}, {"type": "null"}], "title": "Webhook Url"}, "to": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "title": "To"}, "on_failure": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "On Failure"}, "on_score_below": {"anyOf": [{"maximum": 100, "minimum": 0, "type": "integer"}, {"type": "null"}], "description": "null removes the rule.", "title": "On Score Below"}, "on_latency_p95_above_ms": {"anyOf": [{"maximum": 60000, "minimum": 1, "type": "integer"}, {"type": "null"}], "description": "null removes the rule.", "title": "On Latency P95 Above Ms"}, "enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Enabled"}}, "title": "AlertChannelPatch", "type": "object"}, "AlertTestOut": {"properties": {"sent": {"title": "Sent", "type": "boolean"}, "error": {"title": "Error", "type": "string"}}, "required": ["sent", "error"], "title": "AlertTestOut", "type": "object"}, "ApiKeyOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "prefix": {"title": "Prefix", "type": "string"}, "scopes": {"items": {"type": "string"}, "title": "Scopes", "type": "array"}, "allowed_cidrs": {"items": {"type": "string"}, "title": "Allowed Cidrs", "type": "array"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "expires_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Expires At"}, "last_used_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Last Used At"}, "last_used_ip": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Last Used Ip"}, "revoked_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Revoked At"}, "rotated_from_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Rotated From Id"}}, "required": ["id", "name", "prefix", "scopes", "allowed_cidrs", "created_at", "expires_at", "last_used_at", "last_used_ip", "revoked_at", "rotated_from_id"], "title": "ApiKeyOut", "type": "object"}, "ApiKeyCreated": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "prefix": {"title": "Prefix", "type": "string"}, "scopes": {"items": {"type": "string"}, "title": "Scopes", "type": "array"}, "allowed_cidrs": {"items": {"type": "string"}, "title": "Allowed Cidrs", "type": "array"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "expires_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Expires At"}, "last_used_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Last Used At"}, "last_used_ip": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Last Used Ip"}, "revoked_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Revoked At"}, "rotated_from_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Rotated From Id"}, "key": {"description": "The API key. Shown only once: store it in your secrets.", "title": "Key", "type": "string"}}, "required": ["id", "name", "prefix", "scopes", "allowed_cidrs", "created_at", "expires_at", "last_used_at", "last_used_ip", "revoked_at", "rotated_from_id", "key"], "title": "ApiKeyCreated", "type": "object"}, "ApiKeyIn": {"properties": {"name": {"examples": ["GitHub Actions"], "maxLength": 80, "minLength": 1, "title": "Name", "type": "string"}, "scopes": {"items": {"enum": ["read", "write", "run", "admin"], "type": "string"}, "title": "Scopes", "type": "array"}, "expires_in_days": {"anyOf": [{"maximum": 3650, "minimum": 1, "type": "integer"}, {"type": "null"}], "title": "Expires In Days"}, "allowed_cidrs": {"description": "Only accept requests from these networks (IPv4 or IPv6, CIDR or single address, at most 20). Empty: any address.", "examples": [["203.0.113.0/24", "2001:db8::/32"]], "items": {"type": "string"}, "title": "Allowed Cidrs", "type": "array"}}, "required": ["name"], "title": "ApiKeyIn", "type": "object"}, "ApiKeyPatch": {"properties": {"name": {"anyOf": [{"maxLength": 80, "minLength": 1, "type": "string"}, {"type": "null"}], "title": "Name"}, "allowed_cidrs": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Replaces the list. [] removes the restriction.", "title": "Allowed Cidrs"}}, "title": "ApiKeyPatch", "type": "object"}, "KeyRotateIn": {"properties": {"grace_period_hours": {"default": 24, "description": "How long the old key keeps working. 0 revokes it now.", "maximum": 168, "minimum": 0, "title": "Grace Period Hours", "type": "integer"}}, "title": "KeyRotateIn", "type": "object"}, "ApiLogOut": {"properties": {"method": {"title": "Method", "type": "string"}, "path": {"title": "Path", "type": "string"}, "status_code": {"title": "Status Code", "type": "integer"}, "duration_ms": {"title": "Duration Ms", "type": "integer"}, "api_key_prefix": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Api Key Prefix"}, "ip": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Ip"}, "request_id": {"title": "Request Id", "type": "string"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}}, "required": ["method", "path", "status_code", "duration_ms", "api_key_prefix", "ip", "request_id", "created_at"], "title": "ApiLogOut", "type": "object"}, "Page_ApiLogOut_": {"properties": {"count": {"description": "Total number of matching items.", "title": "Count", "type": "integer"}, "limit": {"title": "Limit", "type": "integer"}, "offset": {"title": "Offset", "type": "integer"}, "items": {"items": {"$ref": "#/components/schemas/ApiLogOut"}, "title": "Items", "type": "array"}}, "required": ["count", "limit", "offset", "items"], "title": "Page[ApiLogOut]", "type": "object"}, "AuditOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "action": {"examples": ["webhook.create"], "title": "Action", "type": "string"}, "actor_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "The person, for actions done in the dashboard.", "title": "Actor Email"}, "actor_api_key_prefix": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "The API key, for API actions.", "title": "Actor Api Key Prefix"}, "target_type": {"title": "Target Type", "type": "string"}, "target_id": {"title": "Target Id", "type": "string"}, "data": {"additionalProperties": true, "title": "Data", "type": "object"}, "ip": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Ip"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "action", "actor_email", "actor_api_key_prefix", "target_type", "target_id", "data", "ip", "created_at"], "title": "AuditOut", "type": "object"}, "Page_AuditOut_": {"properties": {"count": {"description": "Total number of matching items.", "title": "Count", "type": "integer"}, "limit": {"title": "Limit", "type": "integer"}, "offset": {"title": "Offset", "type": "integer"}, "items": {"items": {"$ref": "#/components/schemas/AuditOut"}, "title": "Items", "type": "array"}}, "required": ["count", "limit", "offset", "items"], "title": "Page[AuditOut]", "type": "object"}, "ExportOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "status": {"enum": ["queued", "running", "done", "error", "expired"], "title": "Status", "type": "string"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "finished_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Finished At"}, "expires_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "The archive is deleted at this date.", "title": "Expires At"}, "size_bytes": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Size Bytes"}, "sha256": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "SHA-256 of the zip archive.", "title": "Sha256"}, "counts": {"additionalProperties": {"type": "integer"}, "description": "Number of objects of each kind.", "title": "Counts", "type": "object"}, "error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error"}, "download_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Signed link valid 24 hours, no API key needed. Set when done.", "title": "Download Url"}}, "required": ["id", "status", "created_at", "finished_at", "expires_at", "size_bytes", "sha256", "counts", "error", "download_url"], "title": "ExportOut", "type": "object"}, "Page_ExportOut_": {"properties": {"count": {"description": "Total number of matching items.", "title": "Count", "type": "integer"}, "limit": {"title": "Limit", "type": "integer"}, "offset": {"title": "Offset", "type": "integer"}, "items": {"items": {"$ref": "#/components/schemas/ExportOut"}, "title": "Items", "type": "array"}}, "required": ["count", "limit", "offset", "items"], "title": "Page[ExportOut]", "type": "object"}, "WalletOut": {"properties": {"balance_cents": {"title": "Balance Cents", "type": "integer"}, "held_cents": {"title": "Held Cents", "type": "integer"}, "available_cents": {"title": "Available Cents", "type": "integer"}, "currency": {"title": "Currency", "type": "string"}}, "required": ["balance_cents", "held_cents", "available_cents", "currency"], "title": "WalletOut", "type": "object"}, "Page_WalletTxOut_": {"properties": {"count": {"description": "Total number of matching items.", "title": "Count", "type": "integer"}, "limit": {"title": "Limit", "type": "integer"}, "offset": {"title": "Offset", "type": "integer"}, "items": {"items": {"$ref": "#/components/schemas/WalletTxOut"}, "title": "Items", "type": "array"}}, "required": ["count", "limit", "offset", "items"], "title": "Page[WalletTxOut]", "type": "object"}, "WalletTxOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "kind": {"title": "Kind", "type": "string"}, "amount_cents": {"title": "Amount Cents", "type": "integer"}, "held_delta_cents": {"title": "Held Delta Cents", "type": "integer"}, "balance_after_cents": {"title": "Balance After Cents", "type": "integer"}, "call_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Call Id"}, "description": {"title": "Description", "type": "string"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "kind", "amount_cents", "held_delta_cents", "balance_after_cents", "call_id", "description", "created_at"], "title": "WalletTxOut", "type": "object"}, "CheckoutOut": {"properties": {"url": {"description": "Redirect the user to this Stripe Checkout page.", "title": "Url", "type": "string"}}, "required": ["url"], "title": "CheckoutOut", "type": "object"}, "CheckoutIn": {"properties": {"amount_cents": {"description": "Top-up amount in USD cents (2000 to 500000).", "examples": [5000], "maximum": 500000, "minimum": 2000, "title": "Amount Cents", "type": "integer"}, "success_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Success Url"}, "cancel_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cancel Url"}}, "required": ["amount_cents"], "title": "CheckoutIn", "type": "object"}, "UsageOut": {"properties": {"period_start": {"title": "Period Start", "type": "string"}, "included": {"title": "Included", "type": "integer"}, "used": {"title": "Used", "type": "integer"}, "held": {"title": "Held", "type": "integer"}, "remaining": {"title": "Remaining", "type": "integer"}, "bonus_remaining": {"title": "Bonus Remaining", "type": "integer"}, "overage_price_cents": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Overage Price Cents"}, "wallet_available_cents": {"title": "Wallet Available Cents", "type": "integer"}, "plan": {"title": "Plan", "type": "string"}}, "required": ["period_start", "included", "used", "held", "remaining", "bonus_remaining", "overage_price_cents", "wallet_available_cents", "plan"], "title": "UsageOut", "type": "object"}, "EnvironmentForecastOut": {"properties": {"environment": {"title": "Environment", "type": "string"}, "units": {"title": "Units", "type": "integer"}, "runs_left": {"title": "Runs Left", "type": "integer"}, "calls": {"title": "Calls", "type": "integer"}}, "required": ["environment", "units", "runs_left", "calls"], "title": "EnvironmentForecastOut", "type": "object"}, "ForecastOut": {"properties": {"period_start": {"title": "Period Start", "type": "string"}, "period_end": {"description": "First day of the next period (exclusive).", "title": "Period End", "type": "string"}, "included": {"title": "Included", "type": "integer"}, "bonus_remaining": {"title": "Bonus Remaining", "type": "integer"}, "used_units": {"description": "Used or reserved this month (quota, bonus, wallet).", "title": "Used Units", "type": "integer"}, "scheduled_units": {"description": "What the enabled schedules will use until the end of the month.", "title": "Scheduled Units", "type": "integer"}, "projected_units": {"title": "Projected Units", "type": "integer"}, "will_exceed": {"description": "The schedules will use more than the quota and bonus calls left.", "title": "Will Exceed", "type": "boolean"}, "overage_units": {"title": "Overage Units", "type": "integer"}, "estimated_overage_cents": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Wallet cost of `overage_units` at your plan's price, uncapped. null: the plan has no paid overage.", "title": "Estimated Overage Cents"}, "month_overage_cents": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Spent so far + estimated.", "title": "Month Overage Cents"}, "blocked_units": {"description": "Units expected to be blocked: overage off, no overage on the plan, or the monthly cap.", "title": "Blocked Units", "type": "integer"}, "overage_allowed": {"title": "Overage Allowed", "type": "boolean"}, "spend_cap_cents": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Spend Cap Cents"}, "spent_cents": {"title": "Spent Cents", "type": "integer"}, "overage_price_cents": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Overage Price Cents"}, "level": {"enum": ["ok", "warn", "danger"], "title": "Level", "type": "string"}, "schedules_paused": {"title": "Schedules Paused", "type": "boolean"}, "schedules": {"items": {"$ref": "#/components/schemas/ScheduleForecastOut"}, "title": "Schedules", "type": "array"}, "environments": {"items": {"$ref": "#/components/schemas/EnvironmentForecastOut"}, "title": "Environments", "type": "array"}}, "required": ["period_start", "period_end", "included", "bonus_remaining", "used_units", "scheduled_units", "projected_units", "will_exceed", "overage_units", "estimated_overage_cents", "month_overage_cents", "blocked_units", "overage_allowed", "spend_cap_cents", "spent_cents", "overage_price_cents", "level", "schedules_paused", "schedules", "environments"], "title": "ForecastOut", "type": "object"}, "ScheduleForecastOut": {"properties": {"scenario_id": {"format": "uuid", "title": "Scenario Id", "type": "string"}, "scenario_name": {"title": "Scenario Name", "type": "string"}, "environment": {"description": "Environment of this schedule (a scenario has one schedule per environment): decides the number dialed.", "title": "Environment", "type": "string"}, "schedule": {"description": "Cron expression, local time of `timezone`.", "title": "Schedule", "type": "string"}, "timezone": {"title": "Timezone", "type": "string"}, "call_window": {"title": "Call Window", "type": "string"}, "runs_left": {"description": "Runs before the 1st of next month, 00:00 UTC.", "title": "Runs Left", "type": "integer"}, "test_cases": {"description": "Enabled variants (1 without variants).", "title": "Test Cases", "type": "integer"}, "weight": {"description": "Units per 10 minute slice for the destination; 0 when the destination is blocked.", "title": "Weight", "type": "integer"}, "avg_duration_s": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Average duration of the scenario's calls of the last 30 days.", "title": "Avg Duration S"}, "observed": {"description": "false: never ran recently, counted at its maximum duration.", "title": "Observed", "type": "boolean"}, "slices_per_call": {"title": "Slices Per Call", "type": "number"}, "units": {"title": "Units", "type": "integer"}}, "required": ["scenario_id", "scenario_name", "environment", "schedule", "timezone", "call_window", "runs_left", "test_cases", "weight", "avg_duration_s", "observed", "slices_per_call", "units"], "title": "ScheduleForecastOut", "type": "object"}, "ReferralOut": {"properties": {"code": {"title": "Code", "type": "string"}, "url": {"description": "Share it: a new organization created through it gets, like yours, `bonus_calls_each` bonus calls at its first paid subscription.", "title": "Url", "type": "string"}, "bonus_calls_each": {"title": "Bonus Calls Each", "type": "integer"}, "pending": {"description": "Referred organizations that have not paid yet.", "title": "Pending", "type": "integer"}, "granted": {"title": "Granted", "type": "integer"}, "calls_earned": {"title": "Calls Earned", "type": "integer"}}, "required": ["code", "url", "bonus_calls_each", "pending", "granted", "calls_earned"], "title": "ReferralOut", "type": "object"}, "BillingSettingsOut": {"properties": {"monthly_spend_cap_cents": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Most the wallet may spend per calendar month (UTC). null: no cap.", "title": "Monthly Spend Cap Cents"}, "spent_this_month_cents": {"description": "Wallet spend this month, reservations of calls in progress included.", "title": "Spent This Month Cents", "type": "integer"}, "low_balance_threshold_cents": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "`wallet.low_balance` is sent when the balance falls under this. null: never.", "title": "Low Balance Threshold Cents"}, "allow_paid_overage": {"description": "Calls beyond the monthly quota and bonus calls are paid from the wallet. false: they are not placed (block reason `overage_disabled`).", "title": "Allow Paid Overage", "type": "boolean"}, "on_limit": {"description": "When the limit is reached (overage off, cap reached, no overage on the plan): block each call, or also pause the schedules until the 1st of next month (UTC).", "enum": ["block_calls", "pause_schedules"], "title": "On Limit", "type": "string"}, "schedules_paused": {"description": "The schedules are paused by this rule now.", "title": "Schedules Paused", "type": "boolean"}}, "required": ["monthly_spend_cap_cents", "spent_this_month_cents", "low_balance_threshold_cents", "allow_paid_overage", "on_limit", "schedules_paused"], "title": "BillingSettingsOut", "type": "object"}, "BillingSettingsPatch": {"properties": {"monthly_spend_cap_cents": {"anyOf": [{"maximum": 100000000, "minimum": 0, "type": "integer"}, {"type": "null"}], "title": "Monthly Spend Cap Cents"}, "low_balance_threshold_cents": {"anyOf": [{"maximum": 100000000, "minimum": 0, "type": "integer"}, {"type": "null"}], "title": "Low Balance Threshold Cents"}, "allow_paid_overage": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Admins only (`billing.overage`).", "title": "Allow Paid Overage"}, "on_limit": {"anyOf": [{"enum": ["block_calls", "pause_schedules"], "type": "string"}, {"type": "null"}], "title": "On Limit"}}, "title": "BillingSettingsPatch", "type": "object"}, "PlanPublicOut": {"properties": {"code": {"examples": ["growth"], "title": "Code", "type": "string"}, "name": {"title": "Name", "type": "string"}, "included_calls_per_month": {"title": "Included Calls Per Month", "type": "integer"}, "overage_price_cents": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Wallet price of one extra call unit.", "title": "Overage Price Cents"}, "max_seats": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Seats"}, "max_countries": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Countries"}, "max_concurrent_calls": {"title": "Max Concurrent Calls", "type": "integer"}, "features": {"additionalProperties": {"type": "boolean"}, "title": "Features", "type": "object"}, "monthly_price_cents": {"title": "Monthly Price Cents", "type": "integer"}, "annual_monthly_price_cents": {"description": "Per month, billed yearly.", "title": "Annual Monthly Price Cents", "type": "integer"}}, "required": ["code", "name", "included_calls_per_month", "overage_price_cents", "max_seats", "max_countries", "max_concurrent_calls", "features", "monthly_price_cents", "annual_monthly_price_cents"], "title": "PlanPublicOut", "type": "object"}, "SubscriptionOut": {"properties": {"plan": {"$ref": "#/components/schemas/PlanOut"}, "status": {"title": "Status", "type": "string"}, "interval": {"title": "Interval", "type": "string"}, "current_period_start": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Current Period Start"}, "current_period_end": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Current Period End"}, "cancel_at_period_end": {"title": "Cancel At Period End", "type": "boolean"}, "managed_by_stripe": {"description": "false for plans invoiced manually.", "title": "Managed By Stripe", "type": "boolean"}, "payment_retry_until": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "status past_due: the renewal payment failed and Stripe retries it. The plan keeps working until this date; update the card in the billing portal before it or the subscription is canceled.", "title": "Payment Retry Until"}}, "required": ["plan", "status", "interval", "current_period_start", "current_period_end", "cancel_at_period_end", "managed_by_stripe"], "title": "SubscriptionOut", "type": "object"}, "SubscriptionCheckoutIn": {"properties": {"plan": {"description": "A public plan code (GET /plans).", "examples": ["growth"], "title": "Plan", "type": "string"}, "interval": {"default": "monthly", "enum": ["monthly", "annual"], "title": "Interval", "type": "string"}, "success_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Success Url"}, "cancel_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cancel Url"}}, "required": ["plan"], "title": "SubscriptionCheckoutIn", "type": "object"}, "PortalIn": {"properties": {"return_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Return Url"}}, "title": "PortalIn", "type": "object"}, "Page_TicketOut_": {"properties": {"count": {"description": "Total number of matching items.", "title": "Count", "type": "integer"}, "limit": {"title": "Limit", "type": "integer"}, "offset": {"title": "Offset", "type": "integer"}, "items": {"items": {"$ref": "#/components/schemas/TicketOut"}, "title": "Items", "type": "array"}}, "required": ["count", "limit", "offset", "items"], "title": "Page[TicketOut]", "type": "object"}, "TicketOut": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "ref": {"description": "Short reference, e.g. CQA-42.", "title": "Ref", "type": "string"}, "kind": {"enum": ["bug", "question", "feedback", "billing", "abuse_report"], "title": "Kind", "type": "string"}, "status": {"enum": ["open", "waiting_customer", "answered", "closed"], "title": "Status", "type": "string"}, "channel": {"enum": ["mcp", "api", "app", "email"], "title": "Channel", "type": "string"}, "subject": {"title": "Subject", "type": "string"}, "created_by": {"title": "Created By", "type": "string"}, "call_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Call Id"}, "run_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Run Id"}, "scenario_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Scenario Id"}, "context": {"additionalProperties": true, "title": "Context", "type": "object"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "last_staff_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Last answer of the team.", "title": "Last Staff At"}, "unread": {"description": "Answers of the team nobody of the organization has opened in the app yet.", "title": "Unread", "type": "integer"}, "message_count": {"title": "Message Count", "type": "integer"}, "url": {"description": "The ticket in the app.", "title": "Url", "type": "string"}}, "required": ["id", "ref", "kind", "status", "channel", "subject", "created_by", "call_id", "run_id", "scenario_id", "context", "created_at", "updated_at", "last_staff_at", "unread", "message_count", "url"], "title": "TicketOut", "type": "object"}, "MessageOut": {"properties": {"id": {"title": "Id", "type": "integer"}, "author": {"description": "`staff` is the CallQA team.", "enum": ["customer_human", "customer_agent", "staff"], "title": "Author", "type": "string"}, "author_name": {"title": "Author Name", "type": "string"}, "body": {"title": "Body", "type": "string"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "read_by_customer": {"description": "For a message of the team: a person of the organization opened it in the app.", "title": "Read By Customer", "type": "boolean"}}, "required": ["id", "author", "author_name", "body", "created_at", "read_by_customer"], "title": "MessageOut", "type": "object"}, "TicketDetail": {"properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "ref": {"description": "Short reference, e.g. CQA-42.", "title": "Ref", "type": "string"}, "kind": {"enum": ["bug", "question", "feedback", "billing", "abuse_report"], "title": "Kind", "type": "string"}, "status": {"enum": ["open", "waiting_customer", "answered", "closed"], "title": "Status", "type": "string"}, "channel": {"enum": ["mcp", "api", "app", "email"], "title": "Channel", "type": "string"}, "subject": {"title": "Subject", "type": "string"}, "created_by": {"title": "Created By", "type": "string"}, "call_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Call Id"}, "run_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Run Id"}, "scenario_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "title": "Scenario Id"}, "context": {"additionalProperties": true, "title": "Context", "type": "object"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "last_staff_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Last answer of the team.", "title": "Last Staff At"}, "unread": {"description": "Answers of the team nobody of the organization has opened in the app yet.", "title": "Unread", "type": "integer"}, "message_count": {"title": "Message Count", "type": "integer"}, "url": {"description": "The ticket in the app.", "title": "Url", "type": "string"}, "messages": {"items": {"$ref": "#/components/schemas/MessageOut"}, "title": "Messages", "type": "array"}, "secrets_redacted": {"default": 0, "description": "On create and reply: how many things that looked like secrets were removed.", "title": "Secrets Redacted", "type": "integer"}}, "required": ["id", "ref", "kind", "status", "channel", "subject", "created_by", "call_id", "run_id", "scenario_id", "context", "created_at", "updated_at", "last_staff_at", "unread", "message_count", "url", "messages"], "title": "TicketDetail", "type": "object"}, "TicketIn": {"properties": {"subject": {"examples": ["run_scenario answers blocked_policy on a verified number"], "maxLength": 200, "minLength": 3, "title": "Subject", "type": "string"}, "body": {"description": "Markdown. What you tried, what happened (error code and detail), what you expected.", "maxLength": 20000, "minLength": 1, "title": "Body", "type": "string"}, "kind": {"default": "question", "enum": ["bug", "question", "feedback", "billing", "abuse_report"], "title": "Kind", "type": "string"}, "call_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "A call this is about.", "title": "Call Id"}, "run_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "A run this is about.", "title": "Run Id"}, "scenario_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "A scenario this is about.", "title": "Scenario Id"}, "context": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "description": "Free JSON (8 KB at most): client name and version, OS, the request that failed...", "examples": [{"client": "my-ci 1.4"}], "title": "Context"}}, "required": ["subject", "body"], "title": "TicketIn", "type": "object"}, "MessageIn": {"properties": {"body": {"description": "Markdown.", "maxLength": 20000, "minLength": 1, "title": "Body", "type": "string"}}, "required": ["body"], "title": "MessageIn", "type": "object"}}, "securitySchemes": {"ApiKeyAuth": {"type": "http", "description": "Organization API key, created by an admin in Developer > API keys. Format: cqa_<prefix>_<secret>.", "scheme": "bearer"}}, "responses": {"Unauthorized": {"description": "Missing, malformed, unknown, expired or revoked API key (`unauthorized`).", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "Forbidden": {"description": "The key lacks the scope (`missing_scope`), the request comes from an address the key does not allow (`ip_not_allowed`), or the plan does not include the feature (`feature_not_in_plan`, `country_not_in_plan`).", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "NotFound": {"description": "Not found, or not in your organization (`not_found`).", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "InvalidRequest": {"description": "The request does not match the schema (`invalid_request`).", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "RateLimited": {"description": "Rate limited (`rate_limited`). Wait `Retry-After` seconds.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}, "headers": {"Retry-After": {"description": "Seconds until the limit resets.", "schema": {"type": "integer"}}}}}}, "servers": []}