{
  "openapi": "3.1.0",
  "info": {
    "title": "RelationsAI API",
    "version": "2026-10-21",
    "summary": "Place AI voice calls, run calling campaigns and manage contacts from your own systems.",
    "contact": {
      "name": "RelationsAI support",
      "email": "support@relationsai.com"
    },
    "description": "The RelationsAI API lets your servers place outbound AI voice calls, run campaigns, keep contacts and\nthe do-not-call list in sync, and receive events by webhook. It is a JSON-over-HTTPS REST API.\n\n**Private preview.** The API is enabled per workspace. A workspace that has not been enabled gets\n`403 api_access_not_enabled` on every request. Write to support@relationsai.com to request access.\n\n## Authentication\nEvery request sends an API key as a bearer token: `Authorization: Bearer <key>`. Keys are created in\nthe console (API & Developers) by a workspace admin and are shown once.\n\n- `rai_test_...` keys work in **test mode**: nothing is dialled, nothing is charged, and every object\n  has `\"livemode\": false`.\n- `rai_live_...` keys work in **live mode**: real calls to real people, charged to the workspace\n  balance.\n- Older `sk_live_...` keys are not accepted by this API (`401 legacy_api_key_not_supported`).\n\nEach key carries **scopes** (for example `calls:write`). Each operation lists the scopes it needs\nunder `x-required-scopes`. A key can never do more than the member who created it is currently\nallowed to do. Live keys are refused from browsers (requests with an `Origin` header).\n\n## Test mode and live mode\nTest mode and live mode are fully separate. Calls, campaigns, recipients, contacts, do-not-call\nentries, webhook endpoints, events and deliveries created with a test key exist only in test mode,\nand the same for live. An id from the other mode is answered with `404 resource_not_found`.\nAgents and phone numbers are your workspace's real configuration in both modes; test mode also has\na built-in **Sample agent** and a sample number `+12025550150`, so you can try everything before\nyour own agent is ready.\n\nIn test mode the destination number chooses what happens to a call:\n\n| Destination | Simulated result |\n|---|---|\n| `+12025550100` | Answered and completed, with transcript, recording and analysis |\n| `+12025550101` | No answer |\n| `+12025550102` | Busy |\n| `+12025550103` | Failed (network error) |\n| `+12025550104` | Answered by voicemail: `no_response` |\n| `+12025550105` | Completed after a longer conversation |\n| `+12025550106` | The person hangs up early: `completed`, short duration |\n| any other number | Completed |\n\nA test call reaches `ended` within about 20 seconds and `settled` within about 30 seconds.\nDo-not-call entries and missing consent refuse calls in test mode exactly as in live mode.\n\n## Requests and responses\n- Bodies are JSON with `Content-Type: application/json`. Field names are `snake_case`. Request\n  bodies are strict: an unknown field is a `400 validation_error`, never silently ignored.\n- Ids are opaque strings with a type prefix (`call_`, `cmp_`, `ct_`, ...). Treat them as opaque.\n- Timestamps are RFC 3339 in UTC, for example `2026-10-21T09:30:00.000Z`.\n- Money is `{\"amount\": <integer minor units>, \"currency\": \"INR\"}`, always what your workspace is\n  charged.\n- Phone numbers are E.164 strings, for example `+919000000001`.\n- **Enums are open.** New values can be added at any time; treat an unknown value as \"other\",\n  never as success.\n- Every response carries `X-Request-Id`. Quote it to support.\n- `HEAD` is accepted wherever `GET` is and answers the same status and headers with no body.\n- An operation that documents no request body ignores a body sent with it (it is not read, so it is\n  never refused as `415`, `413` or `invalid_json`).\n- Responses carry no automatic `ETag`; only campaigns and contacts have one (see Concurrency), and\n  conditional GET headers (`If-None-Match`, `If-Modified-Since`) are ignored: a response is never `304`.\n\n## Pagination\nList operations return `{\"object\": \"list\", \"data\": [...], \"has_more\": bool, \"next_cursor\": string|null}`,\nnewest first. Pass `limit` (1 to 100, default 25) and, for the next page, `cursor` set to the\nprevious `next_cursor` with the **same filters**. Cursors are opaque and bound to the filters that\nproduced them.\n\n## Idempotency\nThe `Idempotency-Key` header is **optional** on every `POST` and `DELETE`: an extra safety for retries.\nWithout it every request runs, so a retry after a timeout or a lost response can repeat the action (place\na second call, start a campaign again); before retrying, check the state with a `GET` (for a call, list\ncalls by `to` and `created_after`). With it (1 to 255 printable ASCII characters, no spaces; a UUID v4 is\nideal), a retry is safe. Keys are scoped to your workspace and mode and kept for 24 hours.\nWhat is stored under a key: a successful (2xx) answer, and the few errors whose documentation says the\noutcome is unknown and the answer is kept (for example `campaign_outcome_unknown`). A retry with the\nsame key and the same request gets that stored answer again with `Idempotent-Replayed: true` (the\nsame data and status; `request_id` and `X-Request-Id` are the retry's own, and a stored `retry: after`\nerror carries its `Retry-After`). Any other error is not stored: a retry with the same key runs the\nrequest again (each error page says what to check first). Reusing a key for a different request is\n`409 idempotency_key_reused`. If the first attempt is still running you get\n`409 idempotency_key_in_progress` with `Retry-After`. If you send keys, **never generate a new key to\nretry a request that may have succeeded**: that is how a request runs twice.\n\n## Concurrency\nCampaigns and contacts carry an `ETag` response header. `PATCH` on them requires `If-Match` with\nthat value (`428 precondition_required` if missing, `412 version_conflict` if the resource changed).\n`If-Match: *` matches any current version and applies the update without the concurrency check.\n\n## Errors\nEvery error has the same envelope: `{\"error\": {\"code\", \"message\", \"details\", \"request_id\", \"retry\",\n\"doc_url\"}}`. Branch on `code`. `retry` tells you what to do: `no` (fix the request or the\nconfiguration), `yes` (retry with backoff: with the same Idempotency-Key if you sent one, otherwise after\nchecking the state with a `GET`) or `after` (wait\n`Retry-After` seconds). Some errors can happen after work may have begun; their documentation says\nso and tells you to retry with the same key and then check the resource state.\n\n## Rate limits\nLimits apply per key and per workspace, separately in test and live mode, in three classes: `read`\n(600 per minute per key, 1200 per workspace), `write` (120 per key, 240 per workspace) and `dial`\n(placing calls and starting or resuming campaigns: 30 per minute per workspace). Requests that end\nbefore they reach an operation (an unknown path, a refused body, a missing or invalid key, a workspace\nwithout API access) are counted per client IP address: 300 per minute, after which every request\nfrom that address answers `429 rate_limited` until the window resets. Live mode also caps calls\nplaced through the API per UTC day (`429 daily_call_limit_reached`): each `POST /v1/calls` counts\none, a campaign start counts every recipient and is refused whole if they do not all fit, and a\nresume counts nothing. Every response has `RateLimit-Limit`, `RateLimit-Remaining` and\n`RateLimit-Reset` (for the tightest limit that applied); 429 and 503 responses have `Retry-After`.\nEach operation's class is shown as `x-rate-limit-class`.\n\n## Asynchronous work\nCalls and campaigns run after the request returns. `POST /v1/calls` answers `202` with a call in\n`queued` status; follow it with webhooks (`call.ended`, `call.settled`) or by polling\n`GET /v1/calls/{call_id}`. Transcripts, recordings and analysis become ready after the call ends,\nusually within a minute and sometimes several minutes later; `call.settled` says everything,\nincluding the charge, is final.\n\n## Versioning\nThe major version is in the path (`/v1`). Additive changes (new operations, fields, enum values,\nevent types, error codes) ship without advance notice and are recorded in the changelog. Breaking changes need a new major\nversion and at least six months' notice. Events carry `api_version`.\n"
  },
  "servers": [
    {
      "url": "https://voice-api.relationsai.com/v1",
      "description": "Production. Test keys use test mode, live keys use live mode."
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Workspace",
      "description": "The workspace and API key a request is authenticated as, and what they can do."
    },
    {
      "name": "Agents",
      "description": "AI voice agents. Agents are created, configured and published in the console; the API reads them and tells you whether one is ready to place calls. Agent editing through the API is planned."
    },
    {
      "name": "Phone numbers",
      "description": "The workspace's phone numbers and which agents use them. Numbers are added and assigned in the console."
    },
    {
      "name": "Calls",
      "description": "Place outbound calls and read their status, outcome, transcript, recording and analysis."
    },
    {
      "name": "Campaigns",
      "description": "Call a list of contacts with one agent, with pause, resume and stop."
    },
    {
      "name": "Contacts",
      "description": "People you call, with consent and custom fields that become call variables."
    },
    {
      "name": "Do-not-call list",
      "description": "Numbers that must never be called. Checked, in both modes, on every `POST /v1/calls`, when a campaign starts and when it resumes (the resume re-screens). A number added while a campaign is running is not removed from that run: pause and resume the campaign to re-screen it, or stop the campaign."
    },
    {
      "name": "Webhook endpoints",
      "description": "Receive signed event notifications on your server."
    }
  ],
  "x-tagGroups": [
    {
      "name": "Basics",
      "tags": [
        "Workspace"
      ]
    },
    {
      "name": "Configuration",
      "tags": [
        "Agents",
        "Phone numbers"
      ]
    },
    {
      "name": "Calling",
      "tags": [
        "Calls",
        "Campaigns"
      ]
    },
    {
      "name": "Audience",
      "tags": [
        "Contacts",
        "Do-not-call list"
      ]
    },
    {
      "name": "Events",
      "tags": [
        "Webhook endpoints"
      ]
    }
  ],
  "x-scopes": [
    {
      "scope": "workspace:read",
      "label": "Read workspace",
      "description": "Read the workspace, the current key and its limits. Every key has it.",
      "default": true
    },
    {
      "scope": "agents:read",
      "label": "Read agents",
      "description": "List and retrieve agents and check their readiness.",
      "default": true
    },
    {
      "scope": "numbers:read",
      "label": "Read phone numbers",
      "description": "List and retrieve phone numbers.",
      "default": true
    },
    {
      "scope": "calls:read",
      "label": "Read calls",
      "description": "List and retrieve calls, with status, outcome, timing and cost.",
      "default": true
    },
    {
      "scope": "calls:write",
      "label": "Place calls",
      "description": "Place outbound calls. Live calls are charged to the workspace.",
      "default": false
    },
    {
      "scope": "transcripts:read",
      "label": "Read transcripts",
      "description": "Read call transcripts, verbatim.",
      "default": true
    },
    {
      "scope": "recordings:read",
      "label": "Read recordings",
      "description": "Get short-lived links to call recordings.",
      "default": true
    },
    {
      "scope": "analysis:read",
      "label": "Read analysis",
      "description": "Read call summaries, extracted fields and goal outcome.",
      "default": true
    },
    {
      "scope": "campaigns:read",
      "label": "Read campaigns",
      "description": "List and retrieve campaigns and their recipients.",
      "default": true
    },
    {
      "scope": "campaigns:write",
      "label": "Manage campaigns",
      "description": "Create and edit campaigns, add recipients, and start, pause, resume and stop them. Live campaigns are charged.",
      "default": false
    },
    {
      "scope": "contacts:read",
      "label": "Read contacts",
      "description": "List and retrieve contacts, including consent and custom fields.",
      "default": true
    },
    {
      "scope": "contacts:write",
      "label": "Manage contacts",
      "description": "Create, update and delete contacts and record consent.",
      "default": false
    },
    {
      "scope": "dnc:read",
      "label": "Read do-not-call list",
      "description": "List and look up do-not-call entries.",
      "default": true
    },
    {
      "scope": "dnc:write",
      "label": "Manage do-not-call list",
      "description": "Add numbers to and remove numbers from the do-not-call list. Removals are audited.",
      "default": false
    },
    {
      "scope": "webhooks:read",
      "label": "Read webhook endpoints",
      "description": "List and retrieve webhook endpoints and their deliveries.",
      "default": true
    },
    {
      "scope": "webhooks:write",
      "label": "Manage webhook endpoints",
      "description": "Create, update, delete and test webhook endpoints, rotate their secrets and retry deliveries.",
      "default": false
    }
  ],
  "x-event-types": [
    {
      "type": "call.ended",
      "description": "A call ended. Outcome and duration are known; artifacts and the charge may still be pending."
    },
    {
      "type": "call.settled",
      "description": "Everything about a call is final, including transcript, recording, analysis and the charge."
    },
    {
      "type": "campaign.started",
      "description": "A campaign started a run and began dialling."
    },
    {
      "type": "campaign.paused",
      "description": "A campaign was paused, by a request or automatically (budget, balance, telephony)."
    },
    {
      "type": "campaign.resumed",
      "description": "A paused campaign resumed its run."
    },
    {
      "type": "campaign.stopped",
      "description": "A campaign was stopped. It will not dial again unless started anew."
    },
    {
      "type": "campaign.completed",
      "description": "A campaign run finished dialling every recipient."
    },
    {
      "type": "campaign.failed",
      "description": "A campaign run ended in failure before finishing."
    },
    {
      "type": "webhook_endpoint.test",
      "description": "A test event you sent to an endpoint."
    }
  ],
  "components": {
    "schemas": {
      "Agent": {
        "type": "object",
        "description": "An AI voice agent: what callers hear and how the conversation goes. Agents are created, configured, published and switched on in the console. A call uses the agent's published version.",
        "additionalProperties": false,
        "required": [
          "id",
          "object",
          "livemode",
          "name",
          "description",
          "status",
          "published",
          "published_version",
          "is_default",
          "sample",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Agent id (`agent_...`).",
            "pattern": "^agent_[A-Za-z0-9_-]{1,58}$"
          },
          "object": {
            "type": "string",
            "const": "agent",
            "description": "Always `agent`."
          },
          "livemode": {
            "type": "boolean",
            "description": "Mode of the key that read it. Agents are shared configuration, readable in both modes."
          },
          "name": {
            "type": "string",
            "description": "Agent name."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "What the agent is for, as written in the console. Null when not set."
          },
          "status": {
            "type": "string",
            "description": "Whether the agent is switched on in the console. `active` agents can place calls; `paused` and `draft` agents cannot. Open enum: unknown values mean the agent cannot be assumed callable.",
            "enum": [
              "active",
              "paused",
              "draft",
              "unknown"
            ]
          },
          "published": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "True when the agent has a published version that calls use. Null when the publication state could not be read right now; use the readiness endpoint for a definite answer."
          },
          "published_version": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Number of the published version, when known.",
            "minimum": 1
          },
          "is_default": {
            "type": "boolean",
            "description": "True for the workspace's default agent."
          },
          "sample": {
            "type": "boolean",
            "description": "True only for the built-in Sample agent that exists in test mode."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the agent was created."
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the agent's configuration last changed, when known."
          }
        }
      },
      "AgentList": {
        "description": "A page of agents, newest first.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ListMeta"
          },
          {
            "type": "object",
            "description": "The agents.",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "type": "array",
                "description": "Agents on this page.",
                "items": {
                  "$ref": "#/components/schemas/Agent"
                }
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "AgentReadiness": {
        "type": "object",
        "description": "Whether an agent can place calls right now, and every reason it cannot. This is a point-in-time check of the agent and the workspace. Per-destination rules (do-not-call list, consent, calling hours, the per-number daily limit) are checked when each call is placed and are not part of readiness.",
        "additionalProperties": false,
        "required": [
          "object",
          "livemode",
          "agent_id",
          "ready",
          "reasons",
          "checked_at"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "agent_readiness",
            "description": "Always `agent_readiness`."
          },
          "livemode": {
            "type": "boolean",
            "description": "Mode of the key that asked."
          },
          "agent_id": {
            "type": "string",
            "description": "The agent checked."
          },
          "ready": {
            "type": "boolean",
            "description": "True when `reasons` is empty."
          },
          "reasons": {
            "type": "array",
            "description": "Every reason the agent cannot place calls. Empty when ready.",
            "items": {
              "$ref": "#/components/schemas/AgentReadinessReason"
            }
          },
          "checked_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the check ran."
          }
        }
      },
      "AgentReadinessReason": {
        "type": "object",
        "description": "One reason an agent cannot place calls.",
        "additionalProperties": false,
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Machine-readable reason. Open enum: `agent_paused` (switched off in the console), `agent_not_connected` (setup not finished: open the agent in the console and save it once), `agent_not_published` (no published version, or its live version is paused), `no_outbound_number` (no outbound number assigned to the agent), `calling_not_configured` (no telephony account or number in the workspace), `telephony_disconnected`, `account_inactive` (trial ended or account suspended), `spend_limit_reached`, `insufficient_balance`."
          },
          "message": {
            "type": "string",
            "description": "What to do about it, for an operator."
          }
        }
      },
      "ArtifactState": {
        "type": "object",
        "description": "State of one call artifact.",
        "additionalProperties": false,
        "required": [
          "state"
        ],
        "properties": {
          "state": {
            "type": "string",
            "description": "`pending`, `ready`, `absent` or `failed`. Open enum.",
            "enum": [
              "pending",
              "ready",
              "absent",
              "failed"
            ]
          }
        }
      },
      "Call": {
        "type": "object",
        "description": "An outbound call placed by an agent. A call moves through these statuses:\n\n`queued` (accepted; being placed) -> `ringing` (not reported today, see `capabilities.call_ringing_status` on the workspace) -> `in_progress` (connected) -> `ended`.\n\nAfter `ended`, the transcript, recording and analysis become ready (`artifacts`), and the charge is\nfinalised. When everything is final, `settled` becomes true and a `call.settled` event is sent.\n`outcome`, `duration_seconds` and `cost` can still change between `ended` and `settled`; treat them\nas final only once `settled` is true.\n",
        "additionalProperties": false,
        "required": [
          "id",
          "object",
          "livemode",
          "status",
          "outcome",
          "end_reason",
          "direction",
          "source",
          "agent_id",
          "campaign_id",
          "phone_number_id",
          "from",
          "to",
          "metadata",
          "created_at",
          "ended_at",
          "duration_seconds",
          "billable_minutes",
          "cost",
          "artifacts",
          "settled",
          "settled_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Call id (`call_...`).",
            "pattern": "^call_[A-Za-z0-9_-]{1,59}$"
          },
          "object": {
            "type": "string",
            "const": "call",
            "description": "Always `call`."
          },
          "livemode": {
            "type": "boolean",
            "description": "`true` for a live call, `false` for a simulated test-mode call."
          },
          "status": {
            "type": "string",
            "description": "Where the call is in its lifecycle. Open enum. `unknown` means the state could not be confirmed for an unusually long time; it is not a success.",
            "enum": [
              "queued",
              "ringing",
              "in_progress",
              "ended",
              "unknown"
            ]
          },
          "outcome": {
            "type": [
              "string",
              "null"
            ],
            "description": "How the call ended. Null until `status` is `ended`. `completed`: answered and a conversation took place. `no_response`: answered but nobody spoke (this includes most voicemail greetings). `no_answer`, `busy`: not answered. `failed`: could not be connected. `unknown`: the result could not be determined. Open enum.",
            "enum": [
              "completed",
              "no_response",
              "no_answer",
              "busy",
              "failed",
              "unknown",
              null
            ]
          },
          "end_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the call ended. Null until `status` is `ended`. `hangup`: a normal end of a connected call. `no_answer`, `busy`, `invalid_number`, `network_error`: the call was not connected for that reason. `insufficient_balance`: ended because the workspace balance ran out. `not_confirmed`: the start was never confirmed, so the call is treated as failed and is not charged (whether the number briefly rang cannot be known). `refused`: the call was refused before it started. `unknown`. Open enum.",
            "enum": [
              "hangup",
              "no_answer",
              "busy",
              "invalid_number",
              "network_error",
              "insufficient_balance",
              "not_confirmed",
              "refused",
              "unknown",
              null
            ]
          },
          "direction": {
            "type": "string",
            "description": "Always `outbound` today. Open enum.",
            "enum": [
              "outbound",
              "inbound"
            ]
          },
          "source": {
            "type": "string",
            "description": "`api` (placed with POST /v1/calls), `console`, or `campaign`. Open enum.",
            "enum": [
              "api",
              "console",
              "campaign"
            ]
          },
          "agent_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The agent that handled the call. Null only if the agent was deleted."
          },
          "campaign_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The campaign that placed the call, if any."
          },
          "phone_number_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The workspace number the call was placed from, once known."
          },
          "from": {
            "type": [
              "string",
              "null"
            ],
            "description": "The caller number shown to the person called (E.164), once known. Null when not known in full."
          },
          "to": {
            "type": [
              "string",
              "null"
            ],
            "description": "The number called (E.164), always in full. Null only for some calls recorded before 2026-08-14 whose number was stored partially at the time; a partial number is never shown in place of a full one."
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the call was accepted."
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the call ended."
          },
          "duration_seconds": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Talk time in seconds once known. Final when `settled` is true.",
            "minimum": 0
          },
          "billable_minutes": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Minutes charged (whole minutes, rounded up). Zero for calls that are not charged. Final when `settled` is true.",
            "minimum": 0
          },
          "cost": {
            "description": "What the workspace was charged for this call. Null until known; always zero in test mode.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/Money"
              },
              {
                "type": "null",
                "description": "Not known yet."
              }
            ]
          },
          "artifacts": {
            "$ref": "#/components/schemas/CallArtifacts"
          },
          "settled": {
            "type": "boolean",
            "description": "True when outcome, duration, artifacts and charge are all final."
          },
          "settled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the call settled."
          }
        }
      },
      "CallAnalysis": {
        "type": "object",
        "description": "What the call achieved: a summary, the fields the agent was configured to extract, and whether the call's goal was met. Produced after the call ends.",
        "additionalProperties": false,
        "required": [
          "object",
          "livemode",
          "call_id",
          "state",
          "simulated",
          "summary",
          "extracted_fields",
          "goal_met"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "call_analysis",
            "description": "Always `call_analysis`."
          },
          "livemode": {
            "type": "boolean",
            "description": "Mode of the call."
          },
          "call_id": {
            "type": "string",
            "description": "The call."
          },
          "state": {
            "type": "string",
            "description": "Overall state: `pending` while any part is still being produced, `ready` when every part has finished (a part may still be `failed`), `absent` when the call produced nothing to analyse. Open enum.",
            "enum": [
              "pending",
              "ready",
              "absent",
              "failed"
            ]
          },
          "simulated": {
            "type": "boolean",
            "description": "True for a test-mode fixture."
          },
          "summary": {
            "type": "object",
            "description": "A short written summary of the conversation.",
            "additionalProperties": false,
            "required": [
              "state",
              "text"
            ],
            "properties": {
              "state": {
                "type": "string",
                "description": "`pending`, `ready`, `absent` or `failed`. Open enum.",
                "enum": [
                  "pending",
                  "ready",
                  "absent",
                  "failed"
                ]
              },
              "text": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The summary. Null unless `state` is `ready`."
              }
            }
          },
          "extracted_fields": {
            "type": "array",
            "description": "Fields the agent is configured (in the console) to extract from the conversation.",
            "items": {
              "$ref": "#/components/schemas/ExtractedField"
            }
          },
          "goal_met": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the call met the agent's goal, when the agent is configured to report it. Null otherwise."
          }
        }
      },
      "CallArtifacts": {
        "type": "object",
        "description": "Readiness of each artifact of the call. `pending`: not ready yet. `ready`: available from its endpoint. `absent`: there is none for this call (for example a call that was not answered has no recording). `failed`: it could not be produced. Open enum.",
        "additionalProperties": false,
        "required": [
          "transcript",
          "recording",
          "analysis"
        ],
        "properties": {
          "transcript": {
            "$ref": "#/components/schemas/ArtifactState"
          },
          "recording": {
            "$ref": "#/components/schemas/ArtifactState"
          },
          "analysis": {
            "$ref": "#/components/schemas/ArtifactState"
          }
        }
      },
      "CallCreateRequest": {
        "type": "object",
        "description": "Place one outbound call.",
        "additionalProperties": false,
        "required": [
          "agent_id",
          "to"
        ],
        "properties": {
          "agent_id": {
            "type": "string",
            "description": "The agent that makes the call (`agent_...`). It must be ready (see the agent readiness endpoint).",
            "pattern": "^agent_[A-Za-z0-9_-]{1,58}$"
          },
          "to": {
            "type": "string",
            "description": "The number to call, in E.164 format (a plus, then 8 to 15 digits, the first not 0).",
            "format": "e164",
            "pattern": "^\\+[1-9][0-9]{7,14}$"
          },
          "phone_number_id": {
            "type": "string",
            "description": "The workspace number to call from (`pn_...`). Optional: by default the agent's outbound number is used. Required when the agent has more than one outbound number.",
            "pattern": "^pn_[A-Za-z0-9_-]{1,61}$"
          },
          "variables": {
            "type": "object",
            "description": "Values the agent can use in the conversation, for example `{\"first_name\": \"Asha\"}`. Up to 50 keys; keys are lowercase letters, digits and `_`, starting with a letter, up to 64 characters; values are strings up to 500 characters. If the destination matches a contact, the contact's name and custom fields are added automatically; values here take precedence.",
            "maxProperties": 50,
            "propertyNames": {
              "pattern": "^[a-z][a-z0-9_]{0,63}$"
            },
            "additionalProperties": {
              "type": "string",
              "maxLength": 500
            }
          },
          "metadata": {
            "$ref": "#/components/schemas/Metadata"
          }
        }
      },
      "CallEvent": {
        "description": "A call event. `data.object` is the call as it was when the event was created.",
        "allOf": [
          {
            "$ref": "#/components/schemas/EventBase"
          },
          {
            "type": "object",
            "description": "Call event payload.",
            "properties": {
              "type": {
                "type": "string",
                "description": "The call event type.",
                "enum": [
                  "call.ended",
                  "call.settled"
                ]
              },
              "data": {
                "type": "object",
                "description": "Event data.",
                "additionalProperties": false,
                "required": [
                  "object"
                ],
                "properties": {
                  "object": {
                    "$ref": "#/components/schemas/Call"
                  }
                }
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "CallList": {
        "description": "A page of calls, newest first.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ListMeta"
          },
          {
            "type": "object",
            "description": "The calls.",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "type": "array",
                "description": "Calls on this page.",
                "items": {
                  "$ref": "#/components/schemas/Call"
                }
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "CallRecording": {
        "type": "object",
        "description": "The call recording. When `state` is `ready`, `url` is a short-lived HTTPS link to the audio that needs no API key. Fetch it before `expires_at`, and retrieve this object again for a fresh link. Do not store the link.",
        "additionalProperties": false,
        "required": [
          "object",
          "livemode",
          "call_id",
          "state",
          "simulated",
          "url",
          "expires_at",
          "content_type"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "call_recording",
            "description": "Always `call_recording`."
          },
          "livemode": {
            "type": "boolean",
            "description": "Mode of the call."
          },
          "call_id": {
            "type": "string",
            "description": "The call."
          },
          "state": {
            "type": "string",
            "description": "`pending`, `ready`, `absent` (no recording exists for this call) or `failed`. Open enum.",
            "enum": [
              "pending",
              "ready",
              "absent",
              "failed"
            ]
          },
          "simulated": {
            "type": "boolean",
            "description": "True for the short synthetic audio file used in test mode."
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Short-lived link to the audio. Null unless `state` is `ready`."
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When `url` stops working."
          },
          "content_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Media type of the audio, for example `audio/ogg` or `audio/mpeg` (`audio/wav` for test-mode audio). Null when not known in advance; the download's `Content-Type` is authoritative."
          }
        }
      },
      "CallTranscript": {
        "type": "object",
        "description": "The words spoken on a call, in order, verbatim (nothing is masked). Available after the call ends; `state` says whether it is ready.",
        "additionalProperties": false,
        "required": [
          "object",
          "livemode",
          "call_id",
          "state",
          "simulated",
          "turns"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "call_transcript",
            "description": "Always `call_transcript`."
          },
          "livemode": {
            "type": "boolean",
            "description": "Mode of the call."
          },
          "call_id": {
            "type": "string",
            "description": "The call."
          },
          "state": {
            "type": "string",
            "description": "`pending`, `ready`, `absent` (nothing was said or the call was not connected) or `failed`. `turns` is empty unless `ready`. Open enum.",
            "enum": [
              "pending",
              "ready",
              "absent",
              "failed"
            ]
          },
          "simulated": {
            "type": "boolean",
            "description": "True for a test-mode fixture transcript."
          },
          "turns": {
            "type": "array",
            "description": "Turns in the order they were spoken.",
            "items": {
              "$ref": "#/components/schemas/TranscriptTurn"
            }
          }
        }
      },
      "Campaign": {
        "type": "object",
        "description": "A campaign calls a list of recipients (contacts) with one agent. Lifecycle:\n\n`draft` -> start -> `running` <-> `paused` -> `stopped`, or `running` -> `completed` / `failed`.\n\n- **start** begins a run. It is allowed from `draft`, `paused`, `stopped`, `completed` and `failed`.\n  From `paused` it abandons the paused run and begins a new one; from `stopped`, `completed` or\n  `failed` it calls the previous run's recipients again, including people already reached. A start of\n  a campaign that was stopped before it ever started calls the recipients added to it. Every start\n  screens recipients against the do-not-call list, consent and the per-number daily limit and leaves\n  blocked ones out.\n- **pause** (from `running`) stops new calls; calls already connected finish normally.\n- **resume** (from `paused`) continues the same run. Every remaining recipient is screened again; if\n  any is now blocked, the resume is refused and the campaign stays paused.\n- **Do-not-call timing.** Recipients are screened when a run starts and when it resumes, not before\n  each call. A number added to the do-not-call list while the campaign is running is still called by\n  that run: pause and resume the campaign (the resume is refused while a remaining recipient is\n  listed) or stop it.\n- **stop** (from `draft`, `running` or `paused`) ends the campaign; calls already connected finish.\n- **Edits** (PATCH) are allowed in every status except `running` and take effect at the next start.\n  A resume continues with the settings the run began with.\n- **Recipients** can be added only while the campaign is `draft`.\n\nA campaign whose do-not-call screening was switched off in the console (`dnc_screening`\n`disabled_in_console`) cannot be started or resumed through the API.\n\nA campaign can also be paused automatically, for example when its budget cap is reached, the\nworkspace balance runs out, or the telephony connection drops. `capabilities` says which actions\nare allowed right now.\n",
        "additionalProperties": false,
        "required": [
          "id",
          "object",
          "livemode",
          "name",
          "agent_id",
          "status",
          "capabilities",
          "concurrency_limit",
          "budget_cap",
          "recipient_count",
          "progress",
          "spend",
          "run_number",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Campaign id (`cmp_...`).",
            "pattern": "^cmp_[A-Za-z0-9_-]{1,60}$"
          },
          "object": {
            "type": "string",
            "const": "campaign",
            "description": "Always `campaign`."
          },
          "livemode": {
            "type": "boolean",
            "description": "`true` for a live campaign, `false` for a test-mode campaign."
          },
          "name": {
            "type": "string",
            "description": "Campaign name."
          },
          "agent_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The agent that makes the calls. Null if the agent was deleted; the campaign cannot start until one is set."
          },
          "status": {
            "type": "string",
            "description": "`draft` (never started), `running`, `paused`, `stopped`, `completed` (the run finished), `failed` (the run ended in failure), `unknown`. Open enum.",
            "enum": [
              "draft",
              "running",
              "paused",
              "stopped",
              "completed",
              "failed",
              "unknown"
            ]
          },
          "capabilities": {
            "$ref": "#/components/schemas/CampaignCapabilities"
          },
          "concurrency_limit": {
            "type": "integer",
            "description": "Most calls the campaign places at the same time. Lowered at start to the plan maximum (`limits.campaign_max_concurrency` on the workspace). Campaigns created in the console can hold a higher value than the API accepts on a write.",
            "minimum": 1
          },
          "budget_cap": {
            "description": "The spend at which the campaign is paused. When the campaign's spend reaches the cap the campaign is paused. The check runs about every 15 minutes, so spend can exceed the cap by the calls placed in that time. Null for no cap.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/Money"
              },
              {
                "type": "null",
                "description": "No cap."
              }
            ]
          },
          "recipient_count": {
            "type": "integer",
            "description": "Before the first start, the recipients added to the campaign. From a start on, the recipients that run calls: recipients left out by compliance screening at that start are not counted.",
            "minimum": 0
          },
          "progress": {
            "$ref": "#/components/schemas/CampaignProgress"
          },
          "spend": {
            "description": "What the current or latest run has cost so far. Always zero in test mode, which never charges.",
            "allOf": [
              {
                "$ref": "#/components/schemas/Money"
              }
            ]
          },
          "run_number": {
            "type": "integer",
            "description": "How many runs the campaign has had. 0 before the first start.",
            "minimum": 0
          },
          "dnc_screening": {
            "type": "string",
            "description": "`enforced` (numbers on the do-not-call list are left out at every start and block a resume) or `disabled_in_console` (a person switched screening off for this campaign in the console; the API refuses to start or resume it with `409 campaign_dnc_override_enabled`). Read-only. Open enum.",
            "enum": [
              "enforced",
              "disabled_in_console"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the campaign was created."
          }
        }
      },
      "CampaignCapabilities": {
        "type": "object",
        "description": "Which actions the campaign allows in its current status.",
        "additionalProperties": false,
        "required": [
          "start",
          "pause",
          "resume",
          "stop",
          "update",
          "add_recipients"
        ],
        "properties": {
          "start": {
            "type": "boolean",
            "description": "POST .../start is allowed."
          },
          "pause": {
            "type": "boolean",
            "description": "POST .../pause is allowed."
          },
          "resume": {
            "type": "boolean",
            "description": "POST .../resume is allowed."
          },
          "stop": {
            "type": "boolean",
            "description": "POST .../stop is allowed."
          },
          "update": {
            "type": "boolean",
            "description": "PATCH is allowed."
          },
          "add_recipients": {
            "type": "boolean",
            "description": "POST .../recipients is allowed."
          }
        }
      },
      "CampaignCreateRequest": {
        "type": "object",
        "description": "Create a campaign in `draft` status. Nothing is dialled until you start it.",
        "additionalProperties": false,
        "required": [
          "name",
          "agent_id"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Campaign name.",
            "minLength": 1,
            "maxLength": 200
          },
          "agent_id": {
            "type": "string",
            "description": "The agent that makes the calls.",
            "pattern": "^agent_[A-Za-z0-9_-]{1,58}$"
          },
          "concurrency_limit": {
            "type": "integer",
            "description": "Most simultaneous calls. Defaults to 1. Lowered at start to the plan maximum.",
            "minimum": 1,
            "maximum": 100,
            "default": 1
          },
          "budget_cap": {
            "description": "The spend at which the campaign is paused. When the campaign's spend reaches the cap the campaign is paused. The check runs about every 15 minutes, so spend can exceed the cap by the calls placed in that time. Omit or null for no cap.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/MoneyInput"
              },
              {
                "type": "null",
                "description": "No cap."
              }
            ]
          },
          "contact_ids": {
            "type": "array",
            "description": "Contacts to add as recipients now. You can also add them later, while the campaign is `draft`.",
            "maxItems": 1000,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^ct_[A-Za-z0-9_-]{1,61}$"
            }
          }
        }
      },
      "CampaignEvent": {
        "description": "A campaign event. `data.object` is the campaign as it was when the event was created.",
        "allOf": [
          {
            "$ref": "#/components/schemas/EventBase"
          },
          {
            "type": "object",
            "description": "Campaign event payload.",
            "properties": {
              "type": {
                "type": "string",
                "description": "The campaign event type.",
                "enum": [
                  "campaign.started",
                  "campaign.paused",
                  "campaign.resumed",
                  "campaign.stopped",
                  "campaign.completed",
                  "campaign.failed"
                ]
              },
              "data": {
                "type": "object",
                "description": "Event data.",
                "additionalProperties": false,
                "required": [
                  "object",
                  "reason"
                ],
                "properties": {
                  "object": {
                    "$ref": "#/components/schemas/Campaign"
                  },
                  "reason": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Why it happened, on `campaign.paused` and `campaign.stopped`: `requested` (an API or console request), `budget_cap_reached`, `insufficient_balance`, `spend_limit_reached`, `telephony_disconnected`, `failure_streak` (too many consecutive failed calls), `start_refused` (the start was refused before any call was placed, for example the agent or the phone number is not ready, so the campaign was left paused; fix the cause and start it again), `account_inactive`, `unknown` (also when the campaign was stopped outside RelationsAI's control). Null on other types. Open enum."
                  }
                }
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "CampaignList": {
        "description": "A page of campaigns, newest first.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ListMeta"
          },
          {
            "type": "object",
            "description": "The campaigns.",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "type": "array",
                "description": "Campaigns on this page.",
                "items": {
                  "$ref": "#/components/schemas/Campaign"
                }
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "CampaignProgress": {
        "type": "object",
        "description": "Call counts for the current or latest run. A call is counted in `in_progress` until it ends, and only then in `connected`, `no_answer` or `failed`. Updated as calls end; can lag by up to a minute.",
        "additionalProperties": false,
        "required": [
          "calls",
          "connected",
          "no_answer",
          "failed",
          "in_progress"
        ],
        "properties": {
          "calls": {
            "type": "integer",
            "description": "Calls placed.",
            "minimum": 0
          },
          "connected": {
            "type": "integer",
            "description": "Ended calls that were answered.",
            "minimum": 0
          },
          "no_answer": {
            "type": "integer",
            "description": "Ended calls that were not answered or were busy.",
            "minimum": 0
          },
          "failed": {
            "type": "integer",
            "description": "Every other ended call (it could not be connected, or it ended with an outcome that is not known).",
            "minimum": 0
          },
          "in_progress": {
            "type": "integer",
            "description": "Calls not yet ended.",
            "minimum": 0
          }
        }
      },
      "CampaignRecipient": {
        "type": "object",
        "description": "One recipient of a campaign and what has happened to them in the current or latest run.",
        "additionalProperties": false,
        "required": [
          "id",
          "object",
          "livemode",
          "campaign_id",
          "contact_id",
          "phone_number",
          "status",
          "attempts",
          "last_call_id",
          "outcome",
          "suppression_reason"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Recipient id (`rcp_...`).",
            "pattern": "^rcp_[A-Za-z0-9_-]{1,60}$"
          },
          "object": {
            "type": "string",
            "const": "campaign_recipient",
            "description": "Always `campaign_recipient`."
          },
          "livemode": {
            "type": "boolean",
            "description": "Mode of the campaign."
          },
          "campaign_id": {
            "type": "string",
            "description": "The campaign."
          },
          "contact_id": {
            "type": "string",
            "description": "The contact."
          },
          "phone_number": {
            "type": "string",
            "description": "The number that is (or was) called."
          },
          "status": {
            "type": "string",
            "description": "`pending` (not yet called in this run), `in_progress`, `completed` (called; see `outcome`), `failed` (every attempt failed), `suppressed` (left out by compliance screening, see `suppression_reason`), `cancelled` (the run stopped before reaching them), `unknown`. Open enum. In live mode a recipient left out by screening at start is not recorded per recipient yet: it shows `pending` while the run is open and `unknown` once the run has ended. Test mode records it as `suppressed`.",
            "enum": [
              "pending",
              "in_progress",
              "completed",
              "failed",
              "suppressed",
              "cancelled",
              "unknown"
            ]
          },
          "attempts": {
            "type": "integer",
            "description": "Call attempts made in this run.",
            "minimum": 0
          },
          "last_call_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The most recent call to this recipient, if any."
          },
          "outcome": {
            "type": [
              "string",
              "null"
            ],
            "description": "Outcome of the most recent call, using the call `outcome` values. Null if not called yet."
          },
          "suppression_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the recipient was left out, when `status` is `suppressed`. Open enum `dnc_listed`, `consent_required`, `contact_daily_limit_reached`, `unknown`."
          }
        }
      },
      "CampaignRecipientList": {
        "description": "A page of campaign recipients, in a stable order.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ListMeta"
          },
          {
            "type": "object",
            "description": "The recipients.",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "type": "array",
                "description": "Recipients on this page.",
                "items": {
                  "$ref": "#/components/schemas/CampaignRecipient"
                }
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "CampaignRecipientsAddRequest": {
        "type": "object",
        "description": "Add contacts to a draft campaign as recipients.",
        "additionalProperties": false,
        "required": [
          "contact_ids"
        ],
        "properties": {
          "contact_ids": {
            "type": "array",
            "description": "Contacts to add. Contacts already in the campaign are skipped, not duplicated.",
            "minItems": 1,
            "maxItems": 1000,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^ct_[A-Za-z0-9_-]{1,61}$"
            }
          }
        }
      },
      "CampaignRecipientsAddResult": {
        "type": "object",
        "description": "Result of adding recipients.",
        "additionalProperties": false,
        "required": [
          "object",
          "livemode",
          "campaign_id",
          "added",
          "recipient_count"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "campaign_recipients_added",
            "description": "Always `campaign_recipients_added`."
          },
          "livemode": {
            "type": "boolean",
            "description": "Mode of the campaign."
          },
          "campaign_id": {
            "type": "string",
            "description": "The campaign."
          },
          "added": {
            "type": "integer",
            "description": "Recipients newly added by this request (contacts already in the campaign are not counted).",
            "minimum": 0
          },
          "recipient_count": {
            "type": "integer",
            "description": "Total recipients in the campaign now.",
            "minimum": 0
          }
        }
      },
      "CampaignUpdateRequest": {
        "type": "object",
        "description": "Fields to change. Omitted fields are left as they are. Changes apply from the next start.",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "name": {
            "type": "string",
            "description": "Campaign name.",
            "minLength": 1,
            "maxLength": 200
          },
          "agent_id": {
            "type": "string",
            "description": "The agent that makes the calls.",
            "pattern": "^agent_[A-Za-z0-9_-]{1,58}$"
          },
          "concurrency_limit": {
            "type": "integer",
            "description": "Most simultaneous calls.",
            "minimum": 1,
            "maximum": 100
          },
          "budget_cap": {
            "description": "The spend at which the campaign is paused, or null to remove the cap. When the campaign's spend reaches the cap the campaign is paused. The check runs about every 15 minutes, so spend can exceed the cap by the calls placed in that time.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/MoneyInput"
              },
              {
                "type": "null",
                "description": "Remove the cap."
              }
            ]
          }
        }
      },
      "Contact": {
        "type": "object",
        "description": "A person you call. Phone numbers are unique within a workspace and mode. Custom field values become call variables: an agent can use `{{field_name}}` in its prompt.",
        "additionalProperties": false,
        "required": [
          "id",
          "object",
          "livemode",
          "phone_number",
          "name",
          "language",
          "country_code",
          "consent_granted",
          "do_not_call",
          "custom_fields",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Contact id (`ct_...`).",
            "pattern": "^ct_[A-Za-z0-9_-]{1,61}$"
          },
          "object": {
            "type": "string",
            "const": "contact",
            "description": "Always `contact`."
          },
          "livemode": {
            "type": "boolean",
            "description": "`true` for a live contact, `false` for a test-mode contact."
          },
          "phone_number": {
            "type": "string",
            "description": "The contact's number. E.164 for contacts created through this API; contacts created earlier in the console may hold the number in the format it was entered."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display name."
          },
          "language": {
            "type": [
              "string",
              "null"
            ],
            "description": "Preferred language, as free text or a language code."
          },
          "country_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "Country code as entered, for example `IN`."
          },
          "consent_granted": {
            "type": "boolean",
            "description": "Whether the contact has consented to be called. When the workspace requires consent (a console compliance setting), calls to a contact without consent are refused. Setting this through the API records that consent was given; only set it when it really was. Consent is never recorded on a contact that is on the do-not-call list: it stays `false` there, and removing the entry does not restore it."
          },
          "do_not_call": {
            "type": "boolean",
            "description": "True when the contact's number is on the do-not-call list. Read-only here: manage it with the do-not-call endpoints. Adding a number to the list also withdraws the contact's consent."
          },
          "custom_fields": {
            "type": "object",
            "description": "Values of the workspace's custom fields for this contact, by field name. Fields are defined in the console.",
            "additionalProperties": {
              "type": "string"
            }
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the contact was created. Null for some contacts created before this was recorded."
          }
        }
      },
      "ContactCreateRequest": {
        "type": "object",
        "description": "Create a contact.",
        "additionalProperties": false,
        "required": [
          "phone_number"
        ],
        "properties": {
          "phone_number": {
            "type": "string",
            "description": "The contact's number in E.164 format.",
            "format": "e164"
          },
          "name": {
            "type": "string",
            "description": "Display name.",
            "minLength": 1,
            "maxLength": 200
          },
          "language": {
            "type": "string",
            "description": "Preferred language.",
            "maxLength": 50
          },
          "country_code": {
            "type": "string",
            "description": "Country code, for example `IN`.",
            "minLength": 2,
            "maxLength": 10
          },
          "consent_granted": {
            "type": "boolean",
            "description": "Set to true only when the person has consented to be called. Recorded with the time and the API as its source.",
            "default": false
          },
          "custom_fields": {
            "$ref": "#/components/schemas/CustomFieldValues"
          }
        }
      },
      "ContactList": {
        "description": "A page of contacts, newest first.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ListMeta"
          },
          {
            "type": "object",
            "description": "The contacts.",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "type": "array",
                "description": "Contacts on this page.",
                "items": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "ContactUpdateRequest": {
        "type": "object",
        "description": "Fields to change. Omitted fields are left as they are.",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "phone_number": {
            "type": "string",
            "description": "New number in E.164 format. Must not belong to another contact.",
            "format": "e164"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display name. Null clears it.",
            "maxLength": 200
          },
          "language": {
            "type": [
              "string",
              "null"
            ],
            "description": "Preferred language. Null clears it.",
            "maxLength": 50
          },
          "country_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "Country code. Null clears it.",
            "maxLength": 10
          },
          "consent_granted": {
            "type": "boolean",
            "description": "True records that consent was given; false records that it was withdrawn."
          },
          "custom_fields": {
            "$ref": "#/components/schemas/CustomFieldValues"
          }
        }
      },
      "ContactUpsertRequest": {
        "type": "object",
        "description": "Create the contact with this phone number, or update it if it exists. Matching is by phone number in the same way the do-not-call check matches numbers.",
        "additionalProperties": false,
        "required": [
          "phone_number"
        ],
        "properties": {
          "phone_number": {
            "type": "string",
            "description": "The contact's number in E.164 format. Identifies the contact.",
            "format": "e164"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display name. Null clears it.",
            "maxLength": 200
          },
          "language": {
            "type": [
              "string",
              "null"
            ],
            "description": "Preferred language. Null clears it.",
            "maxLength": 50
          },
          "country_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "Country code. Null clears it.",
            "maxLength": 10
          },
          "consent_granted": {
            "type": "boolean",
            "description": "Set to true only when the person has consented to be called; false records withdrawal. Omit to leave unchanged."
          },
          "custom_fields": {
            "$ref": "#/components/schemas/CustomFieldValues"
          }
        }
      },
      "CustomFieldValues": {
        "type": "object",
        "description": "Custom field values by field name. Each key must be a custom field defined in the console; an unknown name is `422 custom_field_not_found`. Values are strings up to 500 characters. On update, a null value clears that field and omitted fields are left unchanged.",
        "maxProperties": 100,
        "propertyNames": {
          "minLength": 1,
          "maxLength": 64
        },
        "additionalProperties": {
          "type": [
            "string",
            "null"
          ],
          "maxLength": 500
        }
      },
      "DeletedObject": {
        "type": "object",
        "description": "Returned by a successful delete. The object no longer exists.",
        "additionalProperties": false,
        "required": [
          "id",
          "object",
          "livemode",
          "deleted"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Id of the deleted object."
          },
          "object": {
            "type": "string",
            "description": "Type of the deleted object, for example `contact`."
          },
          "livemode": {
            "type": "boolean",
            "description": "`true` for live mode, `false` for test mode."
          },
          "deleted": {
            "type": "boolean",
            "description": "Always `true`.",
            "const": true
          }
        }
      },
      "DncEntry": {
        "type": "object",
        "description": "A number on the workspace do-not-call list. When it is checked, in both modes: every POST /v1/calls (`422 dnc_listed`), every campaign start (the number is left out) and every resume (the resume is refused while a remaining recipient is listed). A campaign that is already running is not screened again: pause and resume it, or stop it. Matching ignores formatting: a number matches by its digits, and by its last ten digits when both numbers have at least ten.",
        "additionalProperties": false,
        "required": [
          "id",
          "object",
          "livemode",
          "phone_number",
          "contact_id",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Entry id (`dnc_...`).",
            "pattern": "^dnc_[A-Za-z0-9_-]{1,60}$"
          },
          "object": {
            "type": "string",
            "const": "dnc_entry",
            "description": "Always `dnc_entry`."
          },
          "livemode": {
            "type": "boolean",
            "description": "Mode of the entry. Test-mode entries apply only to test-mode calls."
          },
          "phone_number": {
            "type": "string",
            "description": "The number."
          },
          "contact_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The contact with this number, if there is one."
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the number was added to the list. Recorded in test mode; null in live mode, where the time is not stored yet."
          }
        }
      },
      "DncEntryCreateRequest": {
        "type": "object",
        "description": "Add a number to the do-not-call list.",
        "additionalProperties": false,
        "required": [
          "phone_number"
        ],
        "properties": {
          "phone_number": {
            "type": "string",
            "description": "The number in E.164 format.",
            "format": "e164"
          }
        }
      },
      "DncEntryList": {
        "description": "A page of do-not-call entries, newest first.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ListMeta"
          },
          {
            "type": "object",
            "description": "The entries.",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "type": "array",
                "description": "Entries on this page.",
                "items": {
                  "$ref": "#/components/schemas/DncEntry"
                }
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "Error": {
        "type": "object",
        "description": "The error envelope. Every non-2xx response has this shape. Branch on `error.code` (stable) and `error.retry`; never parse `error.message`, which is written for people and may change.",
        "additionalProperties": false,
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "description": "The error.",
            "additionalProperties": false,
            "required": [
              "code",
              "message",
              "details",
              "request_id",
              "retry",
              "doc_url"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code. The full list, with causes and fixes, is in the error reference. Open enum: new codes may be added.",
                "pattern": "^[a-z][a-z0-9_]*$",
                "examples": [
                  "agent_not_ready"
                ]
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation. Safe to show to an operator; never parse it."
              },
              "details": {
                "type": "object",
                "description": "Extra structured facts for this code, documented per code in the error reference. Always an object; `{}` when the code carries no details.",
                "additionalProperties": true
              },
              "request_id": {
                "type": "string",
                "description": "The id of this request (same as the `X-Request-Id` header). Quote it to support.",
                "pattern": "^req_[a-z2-7]{24}$"
              },
              "retry": {
                "type": "string",
                "description": "Whether to retry. `no`: change the request or configuration first. `yes`: retry with exponential backoff; for a POST or DELETE reuse the same Idempotency-Key if you sent one, otherwise check the state with a GET first (a blind retry can repeat the action). `after`: retry after the number of seconds in the `Retry-After` header.",
                "enum": [
                  "no",
                  "yes",
                  "after"
                ]
              },
              "doc_url": {
                "type": "string",
                "format": "uri",
                "description": "Link to this code's page in the error reference."
              }
            }
          }
        }
      },
      "EventBase": {
        "type": "object",
        "description": "Fields every event has. An event is delivered as the JSON body of a POST to your endpoint, signed with the `RelationsAI-Signature` header.",
        "required": [
          "id",
          "object",
          "type",
          "created_at",
          "livemode",
          "api_version",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Event id (`evt_...`). The same event can be delivered more than once; use this to discard duplicates.",
            "pattern": "^evt_[A-Za-z0-9_-]{1,60}$"
          },
          "object": {
            "type": "string",
            "const": "event",
            "description": "Always `event`."
          },
          "type": {
            "$ref": "#/components/schemas/WebhookEventType"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the event happened."
          },
          "livemode": {
            "type": "boolean",
            "description": "Mode of the event."
          },
          "api_version": {
            "type": "string",
            "description": "Version of the payload format, a date. Today `2026-10-21`."
          }
        }
      },
      "ExtractedField": {
        "type": "object",
        "description": "One extracted field.",
        "additionalProperties": false,
        "required": [
          "name",
          "type",
          "state",
          "value"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Field name as configured on the agent."
          },
          "type": {
            "type": "string",
            "description": "Declared type of the field, for example `string`, `number`, `boolean`. Open enum."
          },
          "state": {
            "type": "string",
            "description": "`ready`, `pending`, `absent` (not mentioned in the call) or `failed`. Open enum.",
            "enum": [
              "pending",
              "ready",
              "absent",
              "failed"
            ]
          },
          "value": {
            "description": "The extracted value, typed per `type`. Null unless `state` is `ready`.",
            "type": [
              "string",
              "number",
              "integer",
              "boolean",
              "null"
            ]
          }
        }
      },
      "ListMeta": {
        "type": "object",
        "description": "Fields shared by every list response. Lists are newest first unless an operation says otherwise.",
        "required": [
          "object",
          "has_more",
          "next_cursor"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Always `list`."
          },
          "has_more": {
            "type": "boolean",
            "description": "True when more objects exist after this page."
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Pass as `cursor` (with the same filters) to fetch the next page. Null on the last page."
          }
        }
      },
      "Metadata": {
        "type": "object",
        "description": "Your own key-value data, stored with the object and returned as sent. Up to 16 keys; keys up to 40 characters (letters, digits, `_`, `-`, `.`), values strings up to 500 characters. Never sent to the person called and never used by the agent. Do not put secrets here.",
        "maxProperties": 16,
        "propertyNames": {
          "pattern": "^[A-Za-z0-9_.-]{1,40}$"
        },
        "additionalProperties": {
          "type": "string",
          "maxLength": 500
        }
      },
      "Money": {
        "type": "object",
        "description": "An amount of money as charged to your workspace, in the currency's minor unit (for INR, paise: `1250` is ₹12.50).",
        "additionalProperties": false,
        "required": [
          "amount",
          "currency"
        ],
        "properties": {
          "amount": {
            "type": "integer",
            "description": "Amount in the minor unit of `currency`. Never negative.",
            "minimum": 0
          },
          "currency": {
            "type": "string",
            "description": "ISO 4217 currency code. Open enum; today always `INR`.",
            "pattern": "^[A-Z]{3}$",
            "examples": [
              "INR"
            ]
          }
        }
      },
      "MoneyInput": {
        "type": "object",
        "description": "An amount of money in the currency's minor unit. The currency must be the workspace currency.",
        "additionalProperties": false,
        "required": [
          "amount",
          "currency"
        ],
        "properties": {
          "amount": {
            "type": "integer",
            "description": "Amount in the minor unit of `currency` (for INR, paise). At least 1.",
            "minimum": 1,
            "maximum": 100000000000
          },
          "currency": {
            "type": "string",
            "description": "ISO 4217 code. Must be `INR` today.",
            "enum": [
              "INR"
            ]
          }
        }
      },
      "PhoneNumber": {
        "type": "object",
        "description": "A phone number your workspace can call from or be called on. Numbers are added and assigned to agents in the console. An outbound call shows the caller number chosen for it; by default that is the number assigned to the agent for outbound calls.",
        "additionalProperties": false,
        "required": [
          "id",
          "object",
          "livemode",
          "number",
          "label",
          "status",
          "capabilities",
          "inbound_agent_id",
          "outbound_agent_ids",
          "sample"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Phone number id (`pn_...`).",
            "pattern": "^pn_[A-Za-z0-9_-]{1,61}$"
          },
          "object": {
            "type": "string",
            "const": "phone_number",
            "description": "Always `phone_number`."
          },
          "livemode": {
            "type": "boolean",
            "description": "Mode of the key that read it. Numbers are shared configuration, readable in both modes."
          },
          "number": {
            "type": "string",
            "description": "The number in E.164 format.",
            "pattern": "^\\+[1-9][0-9]{7,14}$"
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "description": "Label given in the console, if any."
          },
          "status": {
            "type": "string",
            "description": "`active` numbers can be used. `pending` numbers are still being set up. Open enum.",
            "enum": [
              "active",
              "pending",
              "unknown"
            ]
          },
          "capabilities": {
            "type": "object",
            "description": "What the number supports.",
            "additionalProperties": false,
            "required": [
              "outbound",
              "inbound"
            ],
            "properties": {
              "outbound": {
                "type": "boolean",
                "description": "Can place outbound calls."
              },
              "inbound": {
                "type": "boolean",
                "description": "Can receive inbound calls."
              }
            }
          },
          "inbound_agent_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The agent of this workspace that answers calls to this number, if any."
          },
          "outbound_agent_ids": {
            "type": "array",
            "description": "Agents of this workspace that call from this number.",
            "items": {
              "type": "string"
            }
          },
          "sample": {
            "type": "boolean",
            "description": "True only for the built-in sample number that exists in test mode."
          }
        }
      },
      "PhoneNumberList": {
        "description": "A page of phone numbers.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ListMeta"
          },
          {
            "type": "object",
            "description": "The phone numbers.",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "type": "array",
                "description": "Phone numbers on this page.",
                "items": {
                  "$ref": "#/components/schemas/PhoneNumber"
                }
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "RateLimitClass": {
        "type": "object",
        "description": "One rate-limit class. Null means that dimension is not limited separately.",
        "additionalProperties": false,
        "required": [
          "per_key_per_minute",
          "per_workspace_per_minute"
        ],
        "properties": {
          "per_key_per_minute": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Requests per minute allowed for one key.",
            "minimum": 1
          },
          "per_workspace_per_minute": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Requests per minute allowed across all keys of the workspace in this mode.",
            "minimum": 1
          }
        }
      },
      "TranscriptTurn": {
        "type": "object",
        "description": "One turn of the conversation.",
        "additionalProperties": false,
        "required": [
          "index",
          "speaker",
          "text",
          "start_ms",
          "end_ms"
        ],
        "properties": {
          "index": {
            "type": "integer",
            "description": "Position of the turn, from 0.",
            "minimum": 0
          },
          "speaker": {
            "type": "string",
            "description": "`agent` or `caller` (the person called). Open enum.",
            "enum": [
              "agent",
              "caller"
            ]
          },
          "text": {
            "type": "string",
            "description": "What was said."
          },
          "start_ms": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Start of the turn in milliseconds from the start of the call, when known.",
            "minimum": 0
          },
          "end_ms": {
            "type": [
              "integer",
              "null"
            ],
            "description": "End of the turn in milliseconds from the start of the call, when known.",
            "minimum": 0
          }
        }
      },
      "WebhookDelivery": {
        "type": "object",
        "description": "One event's delivery to one endpoint, with its attempts so far.",
        "additionalProperties": false,
        "required": [
          "id",
          "object",
          "livemode",
          "webhook_endpoint_id",
          "event_id",
          "event_type",
          "status",
          "attempts",
          "last_attempt_at",
          "next_attempt_at",
          "response_status",
          "duration_ms",
          "error",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Delivery id (`wd_...`).",
            "pattern": "^wd_[A-Za-z0-9_-]{1,61}$"
          },
          "object": {
            "type": "string",
            "const": "webhook_delivery",
            "description": "Always `webhook_delivery`."
          },
          "livemode": {
            "type": "boolean",
            "description": "Mode of the event."
          },
          "webhook_endpoint_id": {
            "type": "string",
            "description": "The endpoint."
          },
          "event_id": {
            "type": "string",
            "description": "The event delivered (`evt_...`). Also sent as the `RelationsAI-Event-Id` header."
          },
          "event_type": {
            "$ref": "#/components/schemas/WebhookEventType"
          },
          "status": {
            "type": "string",
            "description": "`pending` (first attempt not made yet), `retrying` (failed, another attempt is scheduled), `succeeded` (your server answered 2xx), `failed` (every attempt failed). Open enum.",
            "enum": [
              "pending",
              "retrying",
              "succeeded",
              "failed"
            ]
          },
          "attempts": {
            "type": "integer",
            "description": "Attempts made so far.",
            "minimum": 0
          },
          "last_attempt_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the last attempt was made."
          },
          "next_attempt_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the next attempt is scheduled, if any."
          },
          "response_status": {
            "type": [
              "integer",
              "null"
            ],
            "description": "HTTP status of your server's last answer, if it answered."
          },
          "duration_ms": {
            "type": [
              "integer",
              "null"
            ],
            "description": "How long the last attempt took.",
            "minimum": 0
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the last attempt failed: `timeout` (no answer in 10 seconds), `connection_failed` (including a host name that did not resolve in time), `tls_error`, `blocked_destination` (the URL resolved to a non-public address), `http_error` (a non-2xx answer), `signing_failed` (RelationsAI could not sign the delivery; nothing was sent, the attempt still counts, and the delivery fails after its last attempt like any other; contact support if it persists). Null if it succeeded. Open enum.",
            "enum": [
              "timeout",
              "connection_failed",
              "tls_error",
              "blocked_destination",
              "http_error",
              "signing_failed",
              null
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the delivery was created."
          }
        }
      },
      "WebhookDeliveryList": {
        "description": "A page of deliveries, newest first.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ListMeta"
          },
          {
            "type": "object",
            "description": "The deliveries.",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "type": "array",
                "description": "Deliveries on this page.",
                "items": {
                  "$ref": "#/components/schemas/WebhookDelivery"
                }
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "WebhookEndpoint": {
        "type": "object",
        "description": "A URL on your server that receives signed event notifications for one mode. Deliveries are at-least-once and not ordered; use the event `id` to discard duplicates and the resource's own timestamps or status to discard stale updates.",
        "required": [
          "id",
          "object",
          "livemode",
          "url",
          "description",
          "events",
          "status",
          "secret_last4",
          "created_at",
          "updated_at",
          "last_delivery"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Endpoint id (`we_...`).",
            "pattern": "^we_[A-Za-z0-9_-]{1,61}$"
          },
          "object": {
            "type": "string",
            "const": "webhook_endpoint",
            "description": "Always `webhook_endpoint`."
          },
          "livemode": {
            "type": "boolean",
            "description": "The endpoint receives events of this mode only."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Where events are delivered."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Your note about the endpoint."
          },
          "events": {
            "type": "array",
            "description": "Event types delivered to this endpoint. The test event is delivered on request regardless of this list.",
            "items": {
              "$ref": "#/components/schemas/WebhookSubscribableEventType"
            }
          },
          "status": {
            "type": "string",
            "description": "`enabled` endpoints receive deliveries; `disabled` ones do not. Open enum.",
            "enum": [
              "enabled",
              "disabled"
            ]
          },
          "secret_last4": {
            "type": "string",
            "description": "Last four characters of the current signing secret, to tell secrets apart."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the endpoint was created."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the endpoint was last changed."
          },
          "last_delivery": {
            "description": "The most recent delivery attempt, or null if none yet.",
            "oneOf": [
              {
                "type": "object",
                "description": "Summary of the most recent delivery attempt.",
                "additionalProperties": false,
                "required": [
                  "status",
                  "attempted_at",
                  "response_status"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "description": "Delivery status (see the delivery object)."
                  },
                  "attempted_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "When the attempt was made."
                  },
                  "response_status": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "HTTP status your server answered, if it answered."
                  }
                }
              },
              {
                "type": "null",
                "description": "No delivery yet."
              }
            ]
          }
        }
      },
      "WebhookEndpointCreateRequest": {
        "type": "object",
        "description": "Create a webhook endpoint in the key's mode.",
        "additionalProperties": false,
        "required": [
          "url",
          "events"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Must start with `https://`; any other scheme is refused with 400 `validation_error` (issue `invalid_format`) before the URL is checked. Then: port 443 only, no user name or password, not a RelationsAI host, and the host must resolve only to public internet addresses, otherwise 422 `webhook_url_not_allowed`. Checked when created, when changed, and again on every delivery.",
            "maxLength": 2048,
            "pattern": "^https://"
          },
          "description": {
            "type": "string",
            "description": "Your note about the endpoint.",
            "maxLength": 500
          },
          "events": {
            "type": "array",
            "description": "Event types to deliver. `webhook_endpoint.test` cannot be subscribed to (the test operation always delivers it).",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/WebhookSubscribableEventType"
            }
          }
        }
      },
      "WebhookEndpointList": {
        "description": "A page of webhook endpoints, newest first.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ListMeta"
          },
          {
            "type": "object",
            "description": "The endpoints.",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "type": "array",
                "description": "Endpoints on this page.",
                "items": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "WebhookEndpointUpdateRequest": {
        "type": "object",
        "description": "Fields to change. Omitted fields are left as they are.",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Must start with `https://`; any other scheme is refused with 400 `validation_error` (issue `invalid_format`) before the URL is checked. Then: port 443 only, no user name or password, not a RelationsAI host, and the host must resolve only to public internet addresses, otherwise 422 `webhook_url_not_allowed`. Checked when created, when changed, and again on every delivery.",
            "maxLength": 2048,
            "pattern": "^https://"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Your note about the endpoint. Null clears it.",
            "maxLength": 500
          },
          "events": {
            "type": "array",
            "description": "Event types to deliver. Replaces the current list. `webhook_endpoint.test` cannot be subscribed to (the test operation always delivers it).",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/WebhookSubscribableEventType"
            }
          },
          "status": {
            "type": "string",
            "description": "`enabled` or `disabled`.",
            "enum": [
              "enabled",
              "disabled"
            ]
          }
        }
      },
      "WebhookEndpointWithSecret": {
        "description": "A webhook endpoint together with its signing secret. The secret is shown only in this response; store it now.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEndpoint"
          },
          {
            "type": "object",
            "description": "The secret.",
            "required": [
              "secret"
            ],
            "properties": {
              "secret": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The signing secret (`whsec_...`), shown only in the first response to the create or rotate request. `null` on an idempotent replay of that request (same Idempotency-Key): the secret is stored only encrypted and is never returned again. If it was lost, rotate the secret.",
                "pattern": "^whsec_[A-Za-z0-9_-]{16,}$"
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "WebhookEventType": {
        "type": "string",
        "description": "An event type. Open enum; new types can be added.",
        "enum": [
          "call.ended",
          "call.settled",
          "campaign.started",
          "campaign.paused",
          "campaign.resumed",
          "campaign.stopped",
          "campaign.completed",
          "campaign.failed",
          "webhook_endpoint.test"
        ]
      },
      "WebhookSecretRotateRequest": {
        "type": "object",
        "description": "How long the previous secret keeps signing deliveries alongside the new one.",
        "additionalProperties": false,
        "required": [
          "grace_period_hours"
        ],
        "properties": {
          "grace_period_hours": {
            "type": "integer",
            "description": "Hours during which every delivery carries two signatures, one per secret, so you can deploy the new secret without dropping events. `0` retires every previous secret immediately (always allowed, also during a grace period). A value above 0 during a running grace period keeps the oldest secret still signing until its original grace end and discards the one in between.",
            "enum": [
              0,
              1,
              24,
              168
            ]
          }
        }
      },
      "WebhookSubscribableEventType": {
        "type": "string",
        "description": "An event type an endpoint can subscribe to. Open enum; new types can be added. `webhook_endpoint.test` is not in this list: it cannot be subscribed to, and is delivered only by POST /v1/webhook-endpoints/{webhook_endpoint_id}/test, to that endpoint, whatever its subscriptions.",
        "enum": [
          "call.ended",
          "call.settled",
          "campaign.started",
          "campaign.paused",
          "campaign.resumed",
          "campaign.stopped",
          "campaign.completed",
          "campaign.failed"
        ]
      },
      "WebhookTestEvent": {
        "description": "A test event sent with POST /v1/webhook-endpoints/{webhook_endpoint_id}/test. `data.object` is the endpoint.",
        "allOf": [
          {
            "$ref": "#/components/schemas/EventBase"
          },
          {
            "type": "object",
            "description": "Test event payload.",
            "properties": {
              "type": {
                "type": "string",
                "description": "Always `webhook_endpoint.test`.",
                "const": "webhook_endpoint.test"
              },
              "data": {
                "type": "object",
                "description": "Event data.",
                "additionalProperties": false,
                "required": [
                  "object"
                ],
                "properties": {
                  "object": {
                    "$ref": "#/components/schemas/WebhookEndpoint"
                  }
                }
              }
            }
          }
        ],
        "unevaluatedProperties": false
      },
      "Workspace": {
        "type": "object",
        "description": "The workspace the API key belongs to, the key itself, and what the workspace can do through the API in the key's mode. Call it first to check a key, its scopes and its limits.",
        "additionalProperties": false,
        "required": [
          "id",
          "object",
          "livemode",
          "name",
          "timezone",
          "currency",
          "api_key",
          "capabilities",
          "limits"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Workspace id (`ws_...`).",
            "pattern": "^ws_[A-Za-z0-9_-]{1,61}$"
          },
          "object": {
            "type": "string",
            "const": "workspace",
            "description": "Always `workspace`."
          },
          "livemode": {
            "type": "boolean",
            "description": "`true` when the key is a live key, `false` for a test key."
          },
          "name": {
            "type": "string",
            "description": "Workspace name as shown in the console."
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone of the workspace. Calling hours (if enabled in the console) are evaluated in it.",
            "examples": [
              "Asia/Kolkata"
            ]
          },
          "currency": {
            "type": "string",
            "description": "Currency calls are charged in (ISO 4217). Open enum; today always `INR`.",
            "pattern": "^[A-Z]{3}$"
          },
          "api_key": {
            "$ref": "#/components/schemas/WorkspaceApiKey"
          },
          "capabilities": {
            "$ref": "#/components/schemas/WorkspaceCapabilities"
          },
          "limits": {
            "$ref": "#/components/schemas/WorkspaceLimits"
          }
        }
      },
      "WorkspaceApiKey": {
        "type": "object",
        "description": "The API key this request was authenticated with. The secret itself is never returned.",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "environment",
          "scopes",
          "created_at",
          "expires_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Key id (`key_...`). Shown in the console next to the key.",
            "pattern": "^key_[A-Za-z0-9_-]{1,60}$"
          },
          "name": {
            "type": "string",
            "description": "The name given to the key when it was created."
          },
          "environment": {
            "type": "string",
            "enum": [
              "test",
              "live"
            ],
            "description": "`test` for `rai_test_` keys, `live` for `rai_live_` keys."
          },
          "scopes": {
            "type": "array",
            "description": "Scopes this key can use right now: the scopes it was created with, limited to what its creator's current role allows.",
            "items": {
              "type": "string"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the key was created."
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the key stops working. Null for a test key created without expiry."
          }
        }
      },
      "WorkspaceCapabilities": {
        "type": "object",
        "description": "What this workspace can do through the API. A `false` here means the feature is not offered today, so a client can adapt instead of discovering it from errors.",
        "additionalProperties": false,
        "required": [
          "campaign_pause",
          "campaign_resume",
          "call_ringing_status",
          "live_transcript",
          "sentiment_analysis",
          "end_call",
          "agent_editing",
          "inbound_calls",
          "webhooks"
        ],
        "properties": {
          "campaign_pause": {
            "type": "boolean",
            "description": "Running campaigns can be paused."
          },
          "campaign_resume": {
            "type": "boolean",
            "description": "Paused campaigns can be resumed (continuing the same run)."
          },
          "call_ringing_status": {
            "type": "boolean",
            "description": "Calls report a separate `ringing` status. When false, a call goes from `queued` straight to `in_progress` or `ended`."
          },
          "live_transcript": {
            "type": "boolean",
            "description": "Transcripts can be read while a call is in progress. When false, transcripts are available after the call ends."
          },
          "sentiment_analysis": {
            "type": "boolean",
            "description": "Call analysis includes sentiment. When false, analysis has a summary, extracted fields and the goal outcome only."
          },
          "end_call": {
            "type": "boolean",
            "description": "Calls can be hung up through the API."
          },
          "agent_editing": {
            "type": "boolean",
            "description": "Agents can be created or edited through the API. When false, use the console."
          },
          "inbound_calls": {
            "type": "boolean",
            "description": "Inbound calls appear in the call list."
          },
          "webhooks": {
            "type": "boolean",
            "description": "Webhook endpoints can be created and events are delivered."
          }
        }
      },
      "WorkspaceLimits": {
        "type": "object",
        "description": "Limits that apply to this key and workspace in the key's mode.",
        "additionalProperties": false,
        "required": [
          "rate_limits",
          "daily_call_limit",
          "campaign_max_concurrency"
        ],
        "properties": {
          "rate_limits": {
            "type": "object",
            "description": "Requests per minute by rate-limit class. Each operation shows its class as `x-rate-limit-class`.",
            "additionalProperties": false,
            "required": [
              "read",
              "write",
              "dial"
            ],
            "properties": {
              "read": {
                "$ref": "#/components/schemas/RateLimitClass"
              },
              "write": {
                "$ref": "#/components/schemas/RateLimitClass"
              },
              "dial": {
                "$ref": "#/components/schemas/RateLimitClass"
              }
            }
          },
          "daily_call_limit": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Calls this workspace may place through the API per UTC day in live mode. Null in test mode, which has no daily cap.",
            "minimum": 0
          },
          "campaign_max_concurrency": {
            "type": "integer",
            "description": "Most simultaneous calls a campaign can run with on the workspace's plan. A higher `concurrency_limit` is lowered to this at start.",
            "minimum": 1
          }
        }
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "rai_test_... or rai_live_...",
        "description": "An API key created in the console under API & Developers, sent as `Authorization: Bearer <key>`. `rai_test_` keys use test mode and `rai_live_` keys use live mode."
      }
    },
    "parameters": {
      "AgentId": {
        "name": "agent_id",
        "in": "path",
        "required": true,
        "description": "The agent id (`agent_...`).",
        "schema": {
          "type": "string",
          "pattern": "^agent_[A-Za-z0-9_-]{1,58}$"
        },
        "example": "agent_3hT9kQ2mVx7RbN4pLc8Wz1"
      },
      "CallId": {
        "name": "call_id",
        "in": "path",
        "required": true,
        "description": "The call id (`call_...`).",
        "schema": {
          "type": "string",
          "pattern": "^call_[A-Za-z0-9_-]{1,59}$"
        },
        "example": "call_6Vb3Nm8Qw2Er5Ty9Ui4Op7"
      },
      "CampaignId": {
        "name": "campaign_id",
        "in": "path",
        "required": true,
        "description": "The campaign id (`cmp_...`).",
        "schema": {
          "type": "string",
          "pattern": "^cmp_[A-Za-z0-9_-]{1,60}$"
        },
        "example": "cmp_2Kd7Fg4Hj9Lz3Xc8Vb5Nm1"
      },
      "ContactId": {
        "name": "contact_id",
        "in": "path",
        "required": true,
        "description": "The contact id (`ct_...`).",
        "schema": {
          "type": "string",
          "pattern": "^ct_[A-Za-z0-9_-]{1,61}$"
        },
        "example": "ct_8Rw2Tq5Lm9Xc3Vb7Nz4Kp1"
      },
      "CreatedAfter": {
        "name": "created_after",
        "in": "query",
        "required": false,
        "description": "Only objects created at or after this time (RFC 3339, UTC).",
        "schema": {
          "type": "string",
          "format": "date-time"
        },
        "example": "2026-10-01T00:00:00.000Z"
      },
      "CreatedBefore": {
        "name": "created_before",
        "in": "query",
        "required": false,
        "description": "Only objects created before this time (RFC 3339, UTC).",
        "schema": {
          "type": "string",
          "format": "date-time"
        },
        "example": "2026-10-22T00:00:00.000Z"
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "description": "The `next_cursor` of the previous page. Send it with exactly the same filters as the request that returned it; a changed filter set is `400 invalid_cursor`.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 512
        }
      },
      "DncEntryId": {
        "name": "dnc_entry_id",
        "in": "path",
        "required": true,
        "description": "The do-not-call entry id (`dnc_...`).",
        "schema": {
          "type": "string",
          "pattern": "^dnc_[A-Za-z0-9_-]{1,60}$"
        },
        "example": "dnc_4Ty8Ui2Op6As3Df9Gh7Jk5"
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Optional. A unique key for this operation, 1 to 255 printable ASCII characters with no spaces (a UUID v4 is ideal). With it, a retry of the same request (same key, same body) returns the stored answer and never runs the action twice; reuse the same key for every retry, it is kept for 24 hours. Without it, every request runs: a retry after a timeout can repeat the action, so check the state with a GET before retrying.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 255,
          "pattern": "^[\\x21-\\x7E]+$"
        },
        "example": "5b0b5a3e-7f43-4c55-9d0e-2f1c8e6a4b17"
      },
      "IfMatch": {
        "name": "If-Match",
        "in": "header",
        "required": true,
        "description": "The `ETag` from your most recent read of this resource. The update is refused if the resource has changed since. `*` matches any current version: the update is applied without the concurrency check.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128
        },
        "example": "\"c3f1a9e2b7d4\""
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Maximum number of objects to return, from 1 to 100. Defaults to 25.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 25
        },
        "example": 25
      },
      "PhoneNumberId": {
        "name": "phone_number_id",
        "in": "path",
        "required": true,
        "description": "The phone number id (`pn_...`).",
        "schema": {
          "type": "string",
          "pattern": "^pn_[A-Za-z0-9_-]{1,61}$"
        },
        "example": "pn_5Lq8Xc2Rk9TzW3mBv7Np4d"
      },
      "RecordingToken": {
        "name": "recording_token",
        "in": "path",
        "required": true,
        "description": "The opaque token from a recording `url`. It is the credential for this request.",
        "schema": {
          "type": "string",
          "minLength": 16,
          "maxLength": 512,
          "pattern": "^[A-Za-z0-9._~-]+$"
        },
        "example": "rec_tok_Y2FsbF82VmIzTm04UXcyRXI1VHk5VWk0T3A3"
      },
      "WebhookDeliveryId": {
        "name": "webhook_delivery_id",
        "in": "path",
        "required": true,
        "description": "The webhook delivery id (`wd_...`).",
        "schema": {
          "type": "string",
          "pattern": "^wd_[A-Za-z0-9_-]{1,61}$"
        },
        "example": "wd_1Qa5Ws9Ed3Rf7Tg2Yh6Uj4"
      },
      "WebhookEndpointId": {
        "name": "webhook_endpoint_id",
        "in": "path",
        "required": true,
        "description": "The webhook endpoint id (`we_...`).",
        "schema": {
          "type": "string",
          "pattern": "^we_[A-Za-z0-9_-]{1,61}$"
        },
        "example": "we_9Pl3Ok7Ij2Uh6Yg4Tf8Rd1"
      }
    },
    "headers": {
      "ETag": {
        "description": "Version tag of the returned resource. Send it as `If-Match` when you update the resource.",
        "schema": {
          "type": "string"
        },
        "example": "\"c3f1a9e2b7d4\""
      },
      "Idempotent-Replayed": {
        "description": "`true` when this response is the stored result of an earlier request with the same Idempotency-Key.",
        "schema": {
          "type": "string",
          "enum": [
            "true"
          ]
        },
        "example": "true"
      },
      "RateLimit-Limit": {
        "required": true,
        "description": "Requests allowed in the current one-minute window by the tightest limit that applied to this request (the key's or the workspace's limit for the operation's rate-limit class).",
        "schema": {
          "type": "integer",
          "minimum": 0
        },
        "example": 600
      },
      "RateLimit-Remaining": {
        "required": true,
        "description": "Requests left in the current window.",
        "schema": {
          "type": "integer",
          "minimum": 0
        },
        "example": 597
      },
      "RateLimit-Reset": {
        "required": true,
        "description": "Seconds until the current window resets.",
        "schema": {
          "type": "integer",
          "minimum": 0
        },
        "example": 42
      },
      "Retry-After": {
        "description": "Seconds to wait before retrying.",
        "schema": {
          "type": "integer",
          "minimum": 1
        },
        "example": 30
      },
      "X-Request-Id": {
        "required": true,
        "description": "Unique id of this request (`req_...`). Also in every error body as `request_id`. Quote it to support.",
        "schema": {
          "type": "string",
          "pattern": "^req_[a-z2-7]{24}$"
        },
        "example": "req_4k7m2qat5xvz3c6vqnwpbdfh"
      }
    },
    "examples": {
      "call_no_answer": {
        "summary": "Not answered (test mode)",
        "value": {
          "id": "call_9Tg5Yh2Uj8Ik4Ol7Pm3Nb6",
          "object": "call",
          "livemode": false,
          "status": "ended",
          "outcome": "no_answer",
          "end_reason": "no_answer",
          "direction": "outbound",
          "source": "api",
          "agent_id": "agent_1ZltiWzxrXmMprGD6q63",
          "campaign_id": null,
          "phone_number_id": "pn_6Vhm3sFrB5UpmXAnsvmDu",
          "from": "+12025550150",
          "to": "+12025550101",
          "metadata": {},
          "created_at": "2026-10-21T09:35:00.000Z",
          "ended_at": "2026-10-21T09:35:18.000Z",
          "duration_seconds": 0,
          "billable_minutes": 0,
          "cost": {
            "amount": 0,
            "currency": "INR"
          },
          "artifacts": {
            "transcript": {
              "state": "absent"
            },
            "recording": {
              "state": "absent"
            },
            "analysis": {
              "state": "absent"
            }
          },
          "settled": true,
          "settled_at": "2026-10-21T09:35:30.000Z"
        }
      },
      "call_queued": {
        "summary": "Accepted and queued (test mode)",
        "value": {
          "id": "call_6Vb3Nm8Qw2Er5Ty9Ui4Op7",
          "object": "call",
          "livemode": false,
          "status": "queued",
          "outcome": null,
          "end_reason": null,
          "direction": "outbound",
          "source": "api",
          "agent_id": "agent_1ZltiWzxrXmMprGD6q63",
          "campaign_id": null,
          "phone_number_id": "pn_6Vhm3sFrB5UpmXAnsvmDu",
          "from": "+12025550150",
          "to": "+12025550100",
          "metadata": {
            "crm_lead_id": "L-20931"
          },
          "created_at": "2026-10-21T09:30:00.000Z",
          "ended_at": null,
          "duration_seconds": null,
          "billable_minutes": null,
          "cost": null,
          "artifacts": {
            "transcript": {
              "state": "pending"
            },
            "recording": {
              "state": "pending"
            },
            "analysis": {
              "state": "pending"
            }
          },
          "settled": false,
          "settled_at": null
        }
      },
      "call_settled": {
        "summary": "Ended and settled (live mode)",
        "value": {
          "id": "call_2Hd8Ks4Lq7Mw3Nx9Pz5Rc1",
          "object": "call",
          "livemode": true,
          "status": "ended",
          "outcome": "completed",
          "end_reason": "hangup",
          "direction": "outbound",
          "source": "api",
          "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
          "campaign_id": null,
          "phone_number_id": "pn_5Lq8Xc2Rk9TzW3mBv7Np4d",
          "from": "+918000000001",
          "to": "+919000000001",
          "metadata": {
            "crm_lead_id": "L-20931"
          },
          "created_at": "2026-10-21T09:30:00.000Z",
          "ended_at": "2026-10-21T09:32:14.000Z",
          "duration_seconds": 118,
          "billable_minutes": 2,
          "cost": {
            "amount": 600,
            "currency": "INR"
          },
          "artifacts": {
            "transcript": {
              "state": "ready"
            },
            "recording": {
              "state": "ready"
            },
            "analysis": {
              "state": "ready"
            }
          },
          "settled": true,
          "settled_at": "2026-10-21T09:41:02.000Z"
        }
      },
      "campaign_draft": {
        "summary": "A draft campaign (test mode)",
        "value": {
          "id": "cmp_2Kd7Fg4Hj9Lz3Xc8Vb5Nm1",
          "object": "campaign",
          "livemode": false,
          "name": "November renewals",
          "agent_id": "agent_1ZltiWzxrXmMprGD6q63",
          "status": "draft",
          "capabilities": {
            "start": true,
            "pause": false,
            "resume": false,
            "stop": true,
            "update": true,
            "add_recipients": true
          },
          "concurrency_limit": 5,
          "budget_cap": {
            "amount": 500000,
            "currency": "INR"
          },
          "recipient_count": 2,
          "progress": {
            "calls": 0,
            "connected": 0,
            "no_answer": 0,
            "failed": 0,
            "in_progress": 0
          },
          "spend": {
            "amount": 0,
            "currency": "INR"
          },
          "run_number": 0,
          "dnc_screening": "enforced",
          "created_at": "2026-10-21T08:00:00.000Z"
        }
      },
      "campaign_paused": {
        "summary": "A paused campaign (live mode)",
        "value": {
          "id": "cmp_7Wq3Er9Ty2Ui5Op8As4Df6",
          "object": "campaign",
          "livemode": true,
          "name": "November renewals",
          "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
          "status": "paused",
          "capabilities": {
            "start": true,
            "pause": false,
            "resume": true,
            "stop": true,
            "update": true,
            "add_recipients": false
          },
          "concurrency_limit": 5,
          "budget_cap": {
            "amount": 500000,
            "currency": "INR"
          },
          "recipient_count": 1200,
          "progress": {
            "calls": 702,
            "connected": 451,
            "no_answer": 210,
            "failed": 41,
            "in_progress": 0
          },
          "spend": {
            "amount": 270600,
            "currency": "INR"
          },
          "run_number": 1,
          "dnc_screening": "enforced",
          "created_at": "2026-10-20T08:00:00.000Z"
        }
      },
      "campaign_running": {
        "summary": "A running campaign (live mode)",
        "value": {
          "id": "cmp_7Wq3Er9Ty2Ui5Op8As4Df6",
          "object": "campaign",
          "livemode": true,
          "name": "November renewals",
          "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
          "status": "running",
          "capabilities": {
            "start": false,
            "pause": true,
            "resume": false,
            "stop": true,
            "update": false,
            "add_recipients": false
          },
          "concurrency_limit": 5,
          "budget_cap": {
            "amount": 500000,
            "currency": "INR"
          },
          "recipient_count": 1200,
          "progress": {
            "calls": 640,
            "connected": 410,
            "no_answer": 190,
            "failed": 35,
            "in_progress": 5
          },
          "spend": {
            "amount": 246000,
            "currency": "INR"
          },
          "run_number": 1,
          "dnc_screening": "enforced",
          "created_at": "2026-10-20T08:00:00.000Z"
        }
      },
      "campaign_started_test": {
        "summary": "Started (test mode)",
        "value": {
          "id": "cmp_2Kd7Fg4Hj9Lz3Xc8Vb5Nm1",
          "object": "campaign",
          "livemode": false,
          "name": "November renewals",
          "agent_id": "agent_1ZltiWzxrXmMprGD6q63",
          "status": "running",
          "capabilities": {
            "start": false,
            "pause": true,
            "resume": false,
            "stop": true,
            "update": false,
            "add_recipients": false
          },
          "concurrency_limit": 5,
          "budget_cap": {
            "amount": 500000,
            "currency": "INR"
          },
          "recipient_count": 2,
          "progress": {
            "calls": 0,
            "connected": 0,
            "no_answer": 0,
            "failed": 0,
            "in_progress": 0
          },
          "spend": {
            "amount": 0,
            "currency": "INR"
          },
          "run_number": 1,
          "dnc_screening": "enforced",
          "created_at": "2026-10-21T08:00:00.000Z"
        }
      },
      "campaign_stopped": {
        "summary": "A stopped campaign (live mode)",
        "value": {
          "id": "cmp_7Wq3Er9Ty2Ui5Op8As4Df6",
          "object": "campaign",
          "livemode": true,
          "name": "November renewals",
          "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
          "status": "stopped",
          "capabilities": {
            "start": true,
            "pause": false,
            "resume": false,
            "stop": false,
            "update": true,
            "add_recipients": false
          },
          "concurrency_limit": 5,
          "budget_cap": {
            "amount": 500000,
            "currency": "INR"
          },
          "recipient_count": 1200,
          "progress": {
            "calls": 702,
            "connected": 451,
            "no_answer": 210,
            "failed": 41,
            "in_progress": 0
          },
          "spend": {
            "amount": 270600,
            "currency": "INR"
          },
          "run_number": 1,
          "dnc_screening": "enforced",
          "created_at": "2026-10-20T08:00:00.000Z"
        }
      },
      "contact": {
        "summary": "A contact with consent (test mode)",
        "value": {
          "id": "ct_8Rw2Tq5Lm9Xc3Vb7Nz4Kp1",
          "object": "contact",
          "livemode": false,
          "phone_number": "+12025550100",
          "name": "Asha Rao",
          "language": "en",
          "country_code": "US",
          "consent_granted": true,
          "do_not_call": false,
          "custom_fields": {
            "policy_number": "PN-55012",
            "due_date": "2026-11-05"
          },
          "created_at": "2026-10-21T08:30:00.000Z"
        }
      },
      "contact_live": {
        "summary": "A contact (live mode)",
        "value": {
          "id": "ct_2Mh7Yd4Qs8Fv1Kc6Bx9Tn3",
          "object": "contact",
          "livemode": true,
          "phone_number": "+919000000001",
          "name": "Asha Rao",
          "language": "hi",
          "country_code": "IN",
          "consent_granted": true,
          "do_not_call": false,
          "custom_fields": {
            "policy_number": "PN-55012"
          },
          "created_at": "2026-10-19T11:02:00.000Z"
        }
      },
      "delivery_pending": {
        "summary": "A delivery about to be attempted",
        "value": {
          "id": "wd_8Ik2Ol5Pm9Nb3Vc6Xz1As4",
          "object": "webhook_delivery",
          "livemode": false,
          "webhook_endpoint_id": "we_9Pl3Ok7Ij2Uh6Yg4Tf8Rd1",
          "event_id": "evt_3Df7Gh1Jk5Lz9Xc2Vb6Nm8",
          "event_type": "webhook_endpoint.test",
          "status": "pending",
          "attempts": 0,
          "last_attempt_at": null,
          "next_attempt_at": "2026-10-21T09:45:00.000Z",
          "response_status": null,
          "duration_ms": null,
          "error": null,
          "created_at": "2026-10-21T09:45:00.000Z"
        }
      },
      "endpoint": {
        "summary": "An enabled endpoint",
        "value": {
          "id": "we_9Pl3Ok7Ij2Uh6Yg4Tf8Rd1",
          "object": "webhook_endpoint",
          "livemode": false,
          "url": "https://example.com/webhooks/relationsai",
          "description": "CRM sync (test)",
          "events": [
            "call.ended",
            "call.settled",
            "campaign.completed"
          ],
          "status": "enabled",
          "secret_last4": "x9Qa",
          "created_at": "2026-10-21T08:00:00.000Z",
          "updated_at": "2026-10-21T08:00:00.000Z",
          "last_delivery": {
            "status": "succeeded",
            "attempted_at": "2026-10-21T09:31:02.000Z",
            "response_status": 200
          }
        }
      },
      "endpoint_with_secret": {
        "summary": "Created, with its secret",
        "value": {
          "id": "we_9Pl3Ok7Ij2Uh6Yg4Tf8Rd1",
          "object": "webhook_endpoint",
          "livemode": false,
          "url": "https://example.com/webhooks/relationsai",
          "description": "CRM sync (test)",
          "events": [
            "call.ended",
            "call.settled",
            "campaign.completed"
          ],
          "status": "enabled",
          "secret_last4": "x9Qa",
          "created_at": "2026-10-21T08:00:00.000Z",
          "updated_at": "2026-10-21T08:00:00.000Z",
          "last_delivery": null,
          "secret": "whsec_test_7c2f9a4b1e8d3c6a5f0b2e9d4c7a1x9Qa"
        }
      },
      "error_account_inactive": {
        "summary": "Workspace account inactive",
        "value": {
          "error": {
            "code": "account_inactive",
            "message": "This workspace cannot place calls because its account is not active.",
            "details": {
              "reason": "trial_expired"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/account_inactive"
          }
        }
      },
      "error_agent_not_ready": {
        "summary": "Agent not ready to call",
        "value": {
          "error": {
            "code": "agent_not_ready",
            "message": "This agent cannot place calls right now.",
            "details": {
              "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
              "reasons": [
                "agent_not_published"
              ]
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/agent_not_ready"
          }
        }
      },
      "error_api_access_not_enabled": {
        "summary": "API access not enabled",
        "value": {
          "error": {
            "code": "api_access_not_enabled",
            "message": "API access is not enabled for this workspace.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/api_access_not_enabled"
          }
        }
      },
      "error_api_key_expired": {
        "summary": "API key expired",
        "value": {
          "error": {
            "code": "api_key_expired",
            "message": "This API key has expired.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/api_key_expired"
          }
        }
      },
      "error_api_key_revoked": {
        "summary": "API key revoked",
        "value": {
          "error": {
            "code": "api_key_revoked",
            "message": "This API key has been revoked.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/api_key_revoked"
          }
        }
      },
      "error_authentication_required": {
        "summary": "Authentication required",
        "value": {
          "error": {
            "code": "authentication_required",
            "message": "Send your API key as a Bearer token in the Authorization header.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/authentication_required"
          }
        }
      },
      "error_call_not_accepted": {
        "summary": "Call not accepted",
        "value": {
          "error": {
            "code": "call_not_accepted",
            "message": "The call could not be placed. Nothing was dialled and nothing was charged.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/call_not_accepted"
          }
        }
      },
      "error_calling_capacity_reached": {
        "summary": "Calling capacity reached",
        "value": {
          "error": {
            "code": "calling_capacity_reached",
            "message": "Too many calls are being started right now. Retry after the number of seconds in the Retry-After header.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "after",
            "doc_url": "https://docs.relationsai.com/errors/calling_capacity_reached"
          }
        }
      },
      "error_calling_not_configured": {
        "summary": "Calling not set up",
        "value": {
          "error": {
            "code": "calling_not_configured",
            "message": "Calling is not set up for this workspace yet.",
            "details": {
              "reason": "no_outbound_assignment"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/calling_not_configured"
          }
        }
      },
      "error_campaign_budget_reached": {
        "summary": "Campaign budget reached",
        "value": {
          "error": {
            "code": "campaign_budget_reached",
            "message": "This campaign has reached its budget cap.",
            "details": {
              "budget_cap": {
                "amount": 500000,
                "currency": "INR"
              }
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/campaign_budget_reached"
          }
        }
      },
      "error_campaign_dnc_override_enabled": {
        "summary": "Campaign calls numbers on the do-not-call list",
        "value": {
          "error": {
            "code": "campaign_dnc_override_enabled",
            "message": "This campaign is set in the console to also call contacts on the do-not-call list, so it cannot be started or resumed through the API.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/campaign_dnc_override_enabled"
          }
        }
      },
      "error_campaign_has_no_recipients": {
        "summary": "Campaign has no recipients",
        "value": {
          "error": {
            "code": "campaign_has_no_recipients",
            "message": "This campaign has no recipients to call.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/campaign_has_no_recipients"
          }
        }
      },
      "error_campaign_not_resumable": {
        "summary": "Campaign cannot be resumed",
        "value": {
          "error": {
            "code": "campaign_not_resumable",
            "message": "This campaign cannot be resumed. Start it again to begin a new run.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/campaign_not_resumable"
          }
        }
      },
      "error_campaign_operation_in_progress": {
        "summary": "Another start or resume is in progress",
        "value": {
          "error": {
            "code": "campaign_operation_in_progress",
            "message": "This campaign is being started or resumed by another request. Retry shortly.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "after",
            "doc_url": "https://docs.relationsai.com/errors/campaign_operation_in_progress"
          }
        }
      },
      "error_campaign_outcome_unknown": {
        "summary": "Campaign start or resume not confirmed",
        "value": {
          "error": {
            "code": "campaign_outcome_unknown",
            "message": "The request was sent but its outcome is not confirmed yet. Check the campaign before trying again.",
            "details": {
              "action": "start",
              "needs_support": false
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "after",
            "doc_url": "https://docs.relationsai.com/errors/campaign_outcome_unknown"
          }
        }
      },
      "error_campaign_pause_not_confirmed": {
        "summary": "Pause not confirmed",
        "value": {
          "error": {
            "code": "campaign_pause_not_confirmed",
            "message": "The pause was requested but not confirmed. The campaign may still be dialling.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "yes",
            "doc_url": "https://docs.relationsai.com/errors/campaign_pause_not_confirmed"
          }
        }
      },
      "error_campaign_recipients_blocked": {
        "summary": "Recipients now blocked by compliance",
        "value": {
          "error": {
            "code": "campaign_recipients_blocked",
            "message": "Some recipients of this campaign are now blocked by compliance rules, so it was not resumed.",
            "details": {
              "blocked_total": 2,
              "by_reason": {
                "dnc_listed": 1,
                "consent_required": 1
              },
              "contact_ids": [
                "ct_8Rw2Tq5Lm9Xc3Vb7Nz4Kp1",
                "ct_2Mh7Yd4Qs8Fv1Kc6Bx9Tn3"
              ],
              "contact_ids_truncated": false
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/campaign_recipients_blocked"
          }
        }
      },
      "error_campaign_recipients_suppressed": {
        "summary": "Every recipient is suppressed",
        "value": {
          "error": {
            "code": "campaign_recipients_suppressed",
            "message": "Every recipient of this campaign is blocked by your compliance settings. Nothing was dialled.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/campaign_recipients_suppressed"
          }
        }
      },
      "error_campaign_recipients_unavailable": {
        "summary": "Recipients could not be checked",
        "value": {
          "error": {
            "code": "campaign_recipients_unavailable",
            "message": "The campaign's recipients could not be read for screening right now, so nothing was dialled.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "after",
            "doc_url": "https://docs.relationsai.com/errors/campaign_recipients_unavailable"
          }
        }
      },
      "error_campaign_state_conflict": {
        "summary": "Campaign is in the wrong state",
        "value": {
          "error": {
            "code": "campaign_state_conflict",
            "message": "This action is not allowed in the campaign's current status.",
            "details": {
              "status": "running",
              "action": "update"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/campaign_state_conflict"
          }
        }
      },
      "error_campaign_too_large": {
        "summary": "Campaign too large",
        "value": {
          "error": {
            "code": "campaign_too_large",
            "message": "This campaign has too many recipients to start in one run.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/campaign_too_large"
          }
        }
      },
      "error_consent_required": {
        "summary": "Consent required",
        "value": {
          "error": {
            "code": "consent_required",
            "message": "This contact has no recorded consent, and consent is required for calls in this workspace.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/consent_required"
          }
        }
      },
      "error_contact_already_exists": {
        "summary": "Contact already exists",
        "value": {
          "error": {
            "code": "contact_already_exists",
            "message": "A contact with this phone number already exists.",
            "details": {
              "contact_id": "ct_8Rw2Tq5Lm9Xc3Vb7Nz4Kp1"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/contact_already_exists"
          }
        }
      },
      "error_contact_daily_limit_reached": {
        "summary": "Daily call limit for this number reached",
        "value": {
          "error": {
            "code": "contact_daily_limit_reached",
            "message": "This number has already been called the maximum number of times allowed in 24 hours.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/contact_daily_limit_reached"
          }
        }
      },
      "error_contact_limit_reached": {
        "summary": "Contact limit reached",
        "value": {
          "error": {
            "code": "contact_limit_reached",
            "message": "No more contacts can be created right now.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/contact_limit_reached"
          }
        }
      },
      "error_contact_on_dnc_list": {
        "summary": "Contact is on the do-not-call list",
        "value": {
          "error": {
            "code": "contact_on_dnc_list",
            "message": "This contact is on the do-not-call list. Remove its do-not-call entry before deleting it.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/contact_on_dnc_list"
          }
        }
      },
      "error_custom_field_not_found": {
        "summary": "Custom field not found",
        "value": {
          "error": {
            "code": "custom_field_not_found",
            "message": "This custom field does not exist in the workspace.",
            "details": {
              "field": "policy_numbr"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/custom_field_not_found"
          }
        }
      },
      "error_daily_call_limit_reached": {
        "summary": "Daily call limit reached",
        "value": {
          "error": {
            "code": "daily_call_limit_reached",
            "message": "This workspace has reached its daily limit of calls placed through the API.",
            "details": {
              "limit": 500,
              "requested": 120,
              "remaining": 37,
              "resets_at": "2026-10-22T00:00:00.000Z"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "after",
            "doc_url": "https://docs.relationsai.com/errors/daily_call_limit_reached"
          }
        }
      },
      "error_dnc_listed": {
        "summary": "Number on the do-not-call list",
        "value": {
          "error": {
            "code": "dnc_listed",
            "message": "This number is on your do-not-call list, so the call was not placed.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/dnc_listed"
          }
        }
      },
      "error_idempotency_key_in_progress": {
        "summary": "Request with this Idempotency-Key in progress",
        "value": {
          "error": {
            "code": "idempotency_key_in_progress",
            "message": "A request with this Idempotency-Key is still being processed.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "after",
            "doc_url": "https://docs.relationsai.com/errors/idempotency_key_in_progress"
          }
        }
      },
      "error_idempotency_key_reused": {
        "summary": "Idempotency-Key reused",
        "value": {
          "error": {
            "code": "idempotency_key_reused",
            "message": "This Idempotency-Key was already used with a different request.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/idempotency_key_reused"
          }
        }
      },
      "error_idempotency_outcome_unknown": {
        "summary": "Outcome of the earlier request unknown",
        "value": {
          "error": {
            "code": "idempotency_outcome_unknown",
            "message": "An earlier request with this Idempotency-Key did not finish, and its outcome is unknown.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/idempotency_outcome_unknown"
          }
        }
      },
      "error_insufficient_balance": {
        "summary": "Insufficient balance",
        "value": {
          "error": {
            "code": "insufficient_balance",
            "message": "The workspace balance is too low to start this call. Top up to continue.",
            "details": {
              "balance": {
                "amount": 250,
                "currency": "INR"
              },
              "required": {
                "amount": 600,
                "currency": "INR"
              }
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/insufficient_balance"
          }
        }
      },
      "error_insufficient_permissions": {
        "summary": "Key creator lacks permission",
        "value": {
          "error": {
            "code": "insufficient_permissions",
            "message": "The member who created this API key no longer has permission for this operation.",
            "details": {
              "required_scopes": [
                "campaigns:write"
              ]
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/insufficient_permissions"
          }
        }
      },
      "error_insufficient_scope": {
        "summary": "Insufficient scope",
        "value": {
          "error": {
            "code": "insufficient_scope",
            "message": "This API key does not have the scope this operation requires.",
            "details": {
              "required_scopes": [
                "calls:write"
              ]
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/insufficient_scope"
          }
        }
      },
      "error_internal_error": {
        "summary": "Internal error",
        "value": {
          "error": {
            "code": "internal_error",
            "message": "Something went wrong on our side.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "yes",
            "doc_url": "https://docs.relationsai.com/errors/internal_error"
          }
        }
      },
      "error_invalid_api_key": {
        "summary": "Invalid API key",
        "value": {
          "error": {
            "code": "invalid_api_key",
            "message": "The API key is not valid.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/invalid_api_key"
          }
        }
      },
      "error_invalid_cursor": {
        "summary": "Invalid pagination cursor",
        "value": {
          "error": {
            "code": "invalid_cursor",
            "message": "The pagination cursor is invalid or does not match these filters.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/invalid_cursor"
          }
        }
      },
      "error_invalid_idempotency_key": {
        "summary": "Invalid Idempotency-Key",
        "value": {
          "error": {
            "code": "invalid_idempotency_key",
            "message": "The Idempotency-Key header must be 1 to 255 printable ASCII characters with no spaces.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/invalid_idempotency_key"
          }
        }
      },
      "error_invalid_json": {
        "summary": "Invalid JSON body",
        "value": {
          "error": {
            "code": "invalid_json",
            "message": "The request body is not valid JSON.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/invalid_json"
          }
        }
      },
      "error_invalid_phone_number": {
        "summary": "Invalid phone number",
        "value": {
          "error": {
            "code": "invalid_phone_number",
            "message": "The phone number is not a valid E.164 number.",
            "details": {
              "field": "to"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/invalid_phone_number"
          }
        }
      },
      "error_ip_not_allowed": {
        "summary": "IP address not allowed",
        "value": {
          "error": {
            "code": "ip_not_allowed",
            "message": "Requests from this IP address are not allowed for this workspace.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/ip_not_allowed"
          }
        }
      },
      "error_legacy_api_key_not_supported": {
        "summary": "Legacy API key not supported",
        "value": {
          "error": {
            "code": "legacy_api_key_not_supported",
            "message": "Legacy API keys cannot be used with the v1 API. Create a scoped key in the console.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/legacy_api_key_not_supported"
          }
        }
      },
      "error_live_key_not_allowed_in_browser": {
        "summary": "Live key used from a browser",
        "value": {
          "error": {
            "code": "live_key_not_allowed_in_browser",
            "message": "Live API keys cannot be used from a browser. Use a test key, or call the API from your server.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/live_key_not_allowed_in_browser"
          }
        }
      },
      "error_media_link_expired": {
        "summary": "Recording link expired",
        "value": {
          "error": {
            "code": "media_link_expired",
            "message": "This recording link has expired. Retrieve the recording again for a new link.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/media_link_expired"
          }
        }
      },
      "error_outside_calling_hours": {
        "summary": "Outside calling hours",
        "value": {
          "error": {
            "code": "outside_calling_hours",
            "message": "This is outside the permitted calling window for this workspace. Nothing was dialled.",
            "details": {
              "window": "09:00-21:00",
              "timezone": "Asia/Kolkata"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/outside_calling_hours"
          }
        }
      },
      "error_payload_too_large": {
        "summary": "Payload too large",
        "value": {
          "error": {
            "code": "payload_too_large",
            "message": "The request body is too large.",
            "details": {
              "limit_bytes": 1048576
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/payload_too_large"
          }
        }
      },
      "error_phone_number_not_usable": {
        "summary": "Phone number cannot be used for this call",
        "value": {
          "error": {
            "code": "phone_number_not_usable",
            "message": "This phone number cannot place outbound calls for this agent.",
            "details": {
              "phone_number_id": "pn_5Lq8Xc2Rk9TzW3mBv7Np4d"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/phone_number_not_usable"
          }
        }
      },
      "error_phone_number_required": {
        "summary": "Caller number must be chosen",
        "value": {
          "error": {
            "code": "phone_number_required",
            "message": "This agent has more than one outbound number. Choose one with phone_number_id.",
            "details": {
              "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/phone_number_required"
          }
        }
      },
      "error_precondition_required": {
        "summary": "If-Match required",
        "value": {
          "error": {
            "code": "precondition_required",
            "message": "This update needs an If-Match header with the ETag of the version you read.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/precondition_required"
          }
        }
      },
      "error_rate_limited": {
        "summary": "Rate limit exceeded",
        "value": {
          "error": {
            "code": "rate_limited",
            "message": "Too many requests. Retry after the number of seconds in the Retry-After header.",
            "details": {
              "limit_class": "write"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "after",
            "doc_url": "https://docs.relationsai.com/errors/rate_limited"
          }
        }
      },
      "error_recipient_contacts_not_found": {
        "summary": "Contacts not found",
        "value": {
          "error": {
            "code": "recipient_contacts_not_found",
            "message": "Some contact ids do not name contacts in this workspace.",
            "details": {
              "contact_ids": [
                "ct_9Zx4Vb7Nm2Qw5Er8Ty1Ui3"
              ]
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/recipient_contacts_not_found"
          }
        }
      },
      "error_resource_not_found": {
        "summary": "Resource not found",
        "value": {
          "error": {
            "code": "resource_not_found",
            "message": "No such resource.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/resource_not_found"
          }
        }
      },
      "error_service_unavailable": {
        "summary": "Service temporarily unavailable",
        "value": {
          "error": {
            "code": "service_unavailable",
            "message": "The service is temporarily unavailable. Retry after the number of seconds in the Retry-After header.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "after",
            "doc_url": "https://docs.relationsai.com/errors/service_unavailable"
          }
        }
      },
      "error_spend_limit_reached": {
        "summary": "Monthly spend limit reached",
        "value": {
          "error": {
            "code": "spend_limit_reached",
            "message": "This workspace has reached the monthly spend limit set by its admin.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/spend_limit_reached"
          }
        }
      },
      "error_telephony_disconnected": {
        "summary": "Telephony connection down",
        "value": {
          "error": {
            "code": "telephony_disconnected",
            "message": "The telephony connection for this workspace is not working, so the campaign was paused.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/telephony_disconnected"
          }
        }
      },
      "error_unsupported_media_type": {
        "summary": "Unsupported media type",
        "value": {
          "error": {
            "code": "unsupported_media_type",
            "message": "Request bodies must be sent as application/json.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/unsupported_media_type"
          }
        }
      },
      "error_validation_error": {
        "summary": "Validation failed",
        "value": {
          "error": {
            "code": "validation_error",
            "message": "One or more fields are invalid.",
            "details": {
              "errors": [
                {
                  "field": "agent_id",
                  "issue": "required",
                  "message": "agent_id is required."
                }
              ]
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/validation_error"
          }
        }
      },
      "error_version_conflict": {
        "summary": "Version conflict",
        "value": {
          "error": {
            "code": "version_conflict",
            "message": "The resource changed since you read it.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/version_conflict"
          }
        }
      },
      "error_webhook_delivery_not_retryable": {
        "summary": "Delivery cannot be retried",
        "value": {
          "error": {
            "code": "webhook_delivery_not_retryable",
            "message": "This delivery cannot be retried in its current status.",
            "details": {
              "status": "succeeded"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/webhook_delivery_not_retryable"
          }
        }
      },
      "error_webhook_endpoint_disabled": {
        "summary": "Webhook endpoint disabled",
        "value": {
          "error": {
            "code": "webhook_endpoint_disabled",
            "message": "This webhook endpoint is disabled.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/webhook_endpoint_disabled"
          }
        }
      },
      "error_webhook_endpoint_limit_reached": {
        "summary": "Webhook endpoint limit reached",
        "value": {
          "error": {
            "code": "webhook_endpoint_limit_reached",
            "message": "This workspace already has the maximum number of webhook endpoints for this mode.",
            "details": {
              "limit": 16
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/webhook_endpoint_limit_reached"
          }
        }
      },
      "error_webhook_url_not_allowed": {
        "summary": "Webhook URL not allowed",
        "value": {
          "error": {
            "code": "webhook_url_not_allowed",
            "message": "This URL cannot receive webhooks.",
            "details": {
              "reason": "private_address"
            },
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/webhook_url_not_allowed"
          }
        }
      },
      "error_webhooks_not_enabled": {
        "summary": "Webhooks not enabled",
        "value": {
          "error": {
            "code": "webhooks_not_enabled",
            "message": "Webhook delivery is not available yet.",
            "details": {},
            "request_id": "req_4k7m2qat5xvz3c6vqnwpbdfh",
            "retry": "no",
            "doc_url": "https://docs.relationsai.com/errors/webhooks_not_enabled"
          }
        }
      }
    }
  },
  "paths": {
    "/workspace": {
      "get": {
        "operationId": "getWorkspace",
        "summary": "Retrieve the workspace",
        "externalDocs": {
          "description": "Guide: Authentication",
          "url": "https://docs.relationsai.com/getting-started/authentication"
        },
        "description": "Returns the workspace your API key belongs to, the key itself (name, mode, scopes, expiry), what\nthe workspace can do through the API (`capabilities`) and the limits that apply (`limits`).\n\nCall this first: it is the quickest way to check that a key works, which mode it is in and which\nscopes it has. It needs no scope beyond the `workspace:read` scope every key has, and it never\nchanges anything.\n",
        "tags": [
          "Workspace"
        ],
        "x-required-scopes": [
          "workspace:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Returns the same workspace with `livemode` false, the test key, and `limits.daily_call_limit` null.",
        "x-availability": "ga-candidate",
        "responses": {
          "200": {
            "description": "The workspace, the current key, capabilities and limits.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                },
                "examples": {
                  "test_key": {
                    "summary": "A test key",
                    "value": {
                      "id": "ws_7Hk2Lm9QxR4tB8vN3cZp6W",
                      "object": "workspace",
                      "livemode": false,
                      "name": "Acme Lending",
                      "timezone": "Asia/Kolkata",
                      "currency": "INR",
                      "api_key": {
                        "id": "key_4Nf8Gt2Hx6Jq9Lm3Pv7Rs1",
                        "name": "CRM sync (test)",
                        "environment": "test",
                        "scopes": [
                          "workspace:read",
                          "agents:read",
                          "numbers:read",
                          "calls:read",
                          "calls:write",
                          "transcripts:read",
                          "recordings:read",
                          "analysis:read"
                        ],
                        "created_at": "2026-10-20T08:15:00.000Z",
                        "expires_at": null
                      },
                      "capabilities": {
                        "campaign_pause": true,
                        "campaign_resume": true,
                        "call_ringing_status": false,
                        "live_transcript": false,
                        "sentiment_analysis": false,
                        "end_call": false,
                        "agent_editing": false,
                        "inbound_calls": false,
                        "webhooks": true
                      },
                      "limits": {
                        "rate_limits": {
                          "read": {
                            "per_key_per_minute": 600,
                            "per_workspace_per_minute": 1200
                          },
                          "write": {
                            "per_key_per_minute": 120,
                            "per_workspace_per_minute": 240
                          },
                          "dial": {
                            "per_key_per_minute": null,
                            "per_workspace_per_minute": 30
                          }
                        },
                        "daily_call_limit": null,
                        "campaign_max_concurrency": 10
                      }
                    }
                  },
                  "live_key": {
                    "summary": "A live key",
                    "value": {
                      "id": "ws_7Hk2Lm9QxR4tB8vN3cZp6W",
                      "object": "workspace",
                      "livemode": true,
                      "name": "Acme Lending",
                      "timezone": "Asia/Kolkata",
                      "currency": "INR",
                      "api_key": {
                        "id": "key_9Bv2Cx7Zl4Kj8Hg3Fd6Sa5",
                        "name": "CRM sync",
                        "environment": "live",
                        "scopes": [
                          "workspace:read",
                          "calls:read",
                          "calls:write"
                        ],
                        "created_at": "2026-10-21T06:00:00.000Z",
                        "expires_at": "2027-01-19T06:00:00.000Z"
                      },
                      "capabilities": {
                        "campaign_pause": true,
                        "campaign_resume": true,
                        "call_ringing_status": false,
                        "live_transcript": false,
                        "sentiment_analysis": false,
                        "end_call": false,
                        "agent_editing": false,
                        "inbound_calls": false,
                        "webhooks": false
                      },
                      "limits": {
                        "rate_limits": {
                          "read": {
                            "per_key_per_minute": 600,
                            "per_workspace_per_minute": 1200
                          },
                          "write": {
                            "per_key_per_minute": 120,
                            "per_workspace_per_minute": 240
                          },
                          "dial": {
                            "per_key_per_minute": null,
                            "per_workspace_per_minute": 30
                          }
                        },
                        "daily_call_limit": 500,
                        "campaign_max_concurrency": 10
                      }
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.",
            "x-error-codes": [
              "validation_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/agents": {
      "get": {
        "operationId": "listAgents",
        "summary": "List agents",
        "externalDocs": {
          "description": "Guide: Creating and preparing agents",
          "url": "https://docs.relationsai.com/guides/creating-and-preparing-agents"
        },
        "description": "Lists the workspace's agents, newest first. Agents are created, configured and published in the\nconsole; the API reads them. Deleted agents are not listed.\n\n`published` is checked live for each page, so it can be null when that check is not available at\nthat moment. Use the readiness endpoint before placing calls with an agent.\n",
        "tags": [
          "Agents"
        ],
        "x-required-scopes": [
          "agents:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Lists the workspace's real agents plus the built-in Sample agent (`sample` true), which is always active, published and ready in test mode.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of agents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentList"
                },
                "examples": {
                  "agents": {
                    "summary": "Agents in test mode",
                    "value": {
                      "object": "list",
                      "data": [
                        {
                          "id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                          "object": "agent",
                          "livemode": false,
                          "name": "Loan renewal reminder",
                          "description": "Reminds customers that their loan is due for renewal and books a callback.",
                          "status": "active",
                          "published": true,
                          "published_version": 4,
                          "is_default": true,
                          "sample": false,
                          "created_at": "2026-09-02T10:12:44.000Z",
                          "updated_at": "2026-10-18T14:03:10.000Z"
                        },
                        {
                          "id": "agent_1ZltiWzxrXmMprGD6q63",
                          "object": "agent",
                          "livemode": false,
                          "name": "Sample agent",
                          "description": "A built-in agent for trying the API in test mode.",
                          "status": "active",
                          "published": true,
                          "published_version": 1,
                          "is_default": false,
                          "sample": true,
                          "created_at": "2026-10-21T00:00:00.000Z",
                          "updated_at": null
                        }
                      ],
                      "has_more": false,
                      "next_cursor": null
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_cursor`: Invalid pagination cursor.",
            "x-error-codes": [
              "validation_error",
              "invalid_cursor"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_cursor": {
                    "$ref": "#/components/examples/error_invalid_cursor"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/agents/{agent_id}": {
      "get": {
        "operationId": "getAgent",
        "summary": "Retrieve an agent",
        "externalDocs": {
          "description": "Guide: Creating and preparing agents",
          "url": "https://docs.relationsai.com/guides/creating-and-preparing-agents"
        },
        "description": "Returns one agent. An agent that was deleted, belongs to another workspace, or is the test-mode Sample agent read with a live key is `404 resource_not_found`.",
        "tags": [
          "Agents"
        ],
        "x-required-scopes": [
          "agents:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Returns real agents and the Sample agent.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/AgentId"
          }
        ],
        "responses": {
          "200": {
            "description": "The agent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Agent"
                },
                "examples": {
                  "agent": {
                    "summary": "A published agent",
                    "value": {
                      "id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                      "object": "agent",
                      "livemode": true,
                      "name": "Loan renewal reminder",
                      "description": "Reminds customers that their loan is due for renewal and books a callback.",
                      "status": "active",
                      "published": true,
                      "published_version": 4,
                      "is_default": true,
                      "sample": false,
                      "created_at": "2026-09-02T10:12:44.000Z",
                      "updated_at": "2026-10-18T14:03:10.000Z"
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.",
            "x-error-codes": [
              "validation_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/agents/{agent_id}/readiness": {
      "get": {
        "operationId": "getAgentReadiness",
        "summary": "Check whether an agent can place calls",
        "externalDocs": {
          "description": "Guide: Creating and preparing agents",
          "url": "https://docs.relationsai.com/guides/creating-and-preparing-agents"
        },
        "description": "Checks, right now, everything about the agent and the workspace that would stop a call being\nplaced, and returns every problem found (not just the first). An agent is ready when it is\nswitched on, fully set up and published, has an outbound phone number, and the workspace has\ncalling set up, an active account, spend headroom and enough balance.\n\nReadiness does not check per-destination rules (the do-not-call list, consent, calling hours and\nthe per-number daily limit); those are applied to each call. A ready agent can therefore still be\nrefused for a particular number, and readiness can change at any time.\n",
        "tags": [
          "Agents"
        ],
        "x-required-scopes": [
          "agents:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "The Sample agent is always ready. Real agents are checked for their configuration only; balance, spend limit and account status never block test mode.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/AgentId"
          }
        ],
        "responses": {
          "200": {
            "description": "The readiness result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgentReadiness"
                },
                "examples": {
                  "ready": {
                    "summary": "Ready",
                    "value": {
                      "object": "agent_readiness",
                      "livemode": true,
                      "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                      "ready": true,
                      "reasons": [],
                      "checked_at": "2026-10-21T09:30:00.000Z"
                    }
                  },
                  "not_ready": {
                    "summary": "Not ready",
                    "value": {
                      "object": "agent_readiness",
                      "livemode": true,
                      "agent_id": "agent_7Yx2Wq9Lp4Mn8Bv3Kc6Hd1",
                      "ready": false,
                      "reasons": [
                        {
                          "code": "agent_not_published",
                          "message": "Publish the agent in the console before placing calls."
                        },
                        {
                          "code": "no_outbound_number",
                          "message": "Assign a phone number to this agent for outbound calls in the console."
                        }
                      ],
                      "checked_at": "2026-10-21T09:30:00.000Z"
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.",
            "x-error-codes": [
              "validation_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/phone-numbers": {
      "get": {
        "operationId": "listPhoneNumbers",
        "summary": "List phone numbers",
        "externalDocs": {
          "description": "Guide: Creating and preparing agents",
          "url": "https://docs.relationsai.com/guides/creating-and-preparing-agents"
        },
        "description": "Lists the workspace's phone numbers and the agents that use them. Numbers are added and assigned\nin the console. A number is listed only when the workspace has proven it holds that number, so a\nnumber visible here can be used as a caller number.\n\n`outbound_agent_ids` are the agents that call from the number; a call without `phone_number_id`\nuses the agent's outbound number. `inbound_agent_id` answers calls to the number.\nListed by number, in a stable order.\n",
        "tags": [
          "Phone numbers"
        ],
        "x-required-scopes": [
          "numbers:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Lists the workspace's real numbers plus the sample number `+12025550150` (`sample` true), assigned to the Sample agent.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of phone numbers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneNumberList"
                },
                "examples": {
                  "numbers": {
                    "summary": "Numbers in test mode",
                    "value": {
                      "object": "list",
                      "data": [
                        {
                          "id": "pn_6Vhm3sFrB5UpmXAnsvmDu",
                          "object": "phone_number",
                          "livemode": false,
                          "number": "+12025550150",
                          "label": "Sample number",
                          "status": "active",
                          "capabilities": {
                            "outbound": true,
                            "inbound": false
                          },
                          "inbound_agent_id": null,
                          "outbound_agent_ids": [
                            "agent_1ZltiWzxrXmMprGD6q63"
                          ],
                          "sample": true
                        },
                        {
                          "id": "pn_5Lq8Xc2Rk9TzW3mBv7Np4d",
                          "object": "phone_number",
                          "livemode": false,
                          "number": "+918000000001",
                          "label": "Collections line",
                          "status": "active",
                          "capabilities": {
                            "outbound": true,
                            "inbound": true
                          },
                          "inbound_agent_id": null,
                          "outbound_agent_ids": [
                            "agent_3hT9kQ2mVx7RbN4pLc8Wz1"
                          ],
                          "sample": false
                        }
                      ],
                      "has_more": false,
                      "next_cursor": null
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_cursor`: Invalid pagination cursor.",
            "x-error-codes": [
              "validation_error",
              "invalid_cursor"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_cursor": {
                    "$ref": "#/components/examples/error_invalid_cursor"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/phone-numbers/{phone_number_id}": {
      "get": {
        "operationId": "getPhoneNumber",
        "summary": "Retrieve a phone number",
        "externalDocs": {
          "description": "Guide: Creating and preparing agents",
          "url": "https://docs.relationsai.com/guides/creating-and-preparing-agents"
        },
        "description": "Returns one phone number with its capabilities and agent assignments. There is no carrier or account information in this object.",
        "tags": [
          "Phone numbers"
        ],
        "x-required-scopes": [
          "numbers:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Returns real numbers and the sample number.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/PhoneNumberId"
          }
        ],
        "responses": {
          "200": {
            "description": "The phone number.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneNumber"
                },
                "examples": {
                  "number": {
                    "summary": "An outbound number",
                    "value": {
                      "id": "pn_5Lq8Xc2Rk9TzW3mBv7Np4d",
                      "object": "phone_number",
                      "livemode": true,
                      "number": "+918000000001",
                      "label": "Collections line",
                      "status": "active",
                      "capabilities": {
                        "outbound": true,
                        "inbound": true
                      },
                      "inbound_agent_id": null,
                      "outbound_agent_ids": [
                        "agent_3hT9kQ2mVx7RbN4pLc8Wz1"
                      ],
                      "sample": false
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.",
            "x-error-codes": [
              "validation_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/calls": {
      "post": {
        "operationId": "createCall",
        "summary": "Place a call",
        "externalDocs": {
          "description": "Guide: Making an outbound call",
          "url": "https://docs.relationsai.com/guides/making-an-outbound-call"
        },
        "description": "Places one outbound call from an agent to a phone number. The call runs after the request returns:\nthe response is `202 Accepted` with the call in `queued` status.\n\n**What 202 means.** The call passed every check (agent readiness, account, balance and spend\nlimits, the do-not-call list, consent, calling hours and the per-number daily limit) and is being\nstarted. It does not mean anyone has answered.\nFollow the call with the `call.ended` and `call.settled` webhooks, or poll\n`GET /v1/calls/{call_id}`. In rare cases the start is never confirmed; the call then ends with\n`outcome: failed` and `end_reason: not_confirmed` within about two minutes and is not charged.\n\n**Retries.** `Idempotency-Key` is optional. With a key, a retry with the same key returns the original\nresponse and never places a second call, even if the first response was lost. Without one, a retry places\nanother call: if a response was lost, list calls by `to` and `created_after` before retrying.\n\n**Caller number.** Without `phone_number_id`, the agent's outbound number is used; when the agent\nhas several, send `phone_number_id`.\n\n**Variables.** `variables` are passed to the agent for this call. When `to` matches a contact, the\ncontact's name and custom fields are added as variables too (your values win).\n\n**Charges.** Live calls are charged per started minute of talk time at your workspace rate, from\nthe workspace balance. A call that is not answered is not charged.\n",
        "tags": [
          "Calls"
        ],
        "x-required-scopes": [
          "calls:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "dial",
        "x-test-mode": "Nothing is dialled or charged. The destination selects the simulated result (see Test mode). The call reaches `ended` in about 20 seconds and `settled` in about 30, and webhooks fire with `livemode` false. Do-not-call entries, consent, calling hours and the per-number daily limit are enforced exactly as in live mode, against test-mode contacts and do-not-call entries. Balance, spend limit, account status and the API daily call limit never apply. The Sample agent and sample number can be used; a real agent must be switched on and its setup finished in the console (publication and number assignment are not required in test mode).",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CallCreateRequest"
              },
              "examples": {
                "minimal": {
                  "summary": "Test call with the Sample agent",
                  "value": {
                    "agent_id": "agent_1ZltiWzxrXmMprGD6q63",
                    "to": "+12025550100"
                  }
                },
                "full": {
                  "summary": "Live call with variables and metadata",
                  "value": {
                    "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                    "to": "+919000000001",
                    "phone_number_id": "pn_5Lq8Xc2Rk9TzW3mBv7Np4d",
                    "variables": {
                      "first_name": "Asha",
                      "due_date": "2026-11-05"
                    },
                    "metadata": {
                      "crm_lead_id": "L-20931"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The call was accepted and is queued. Its id is final; follow it by webhook or polling.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Call"
                },
                "examples": {
                  "queued": {
                    "$ref": "#/components/examples/call_queued"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_json`: Invalid JSON body.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.\n- `invalid_phone_number`: Invalid phone number.",
            "x-error-codes": [
              "validation_error",
              "invalid_json",
              "invalid_idempotency_key",
              "invalid_phone_number"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_json": {
                    "$ref": "#/components/examples/error_invalid_json"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  },
                  "invalid_phone_number": {
                    "$ref": "#/components/examples/error_invalid_phone_number"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "402": {
            "description": "Payment required. One of:\n- `insufficient_balance`: Insufficient balance.\n- `spend_limit_reached`: Monthly spend limit reached.",
            "x-error-codes": [
              "insufficient_balance",
              "spend_limit_reached"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_balance": {
                    "$ref": "#/components/examples/error_insufficient_balance"
                  },
                  "spend_limit_reached": {
                    "$ref": "#/components/examples/error_spend_limit_reached"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.\n- `account_inactive`: Workspace account inactive.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser",
              "account_inactive"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  },
                  "account_inactive": {
                    "$ref": "#/components/examples/error_account_inactive"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "413": {
            "description": "Payload too large. One of:\n- `payload_too_large`: Payload too large.",
            "x-error-codes": [
              "payload_too_large"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "$ref": "#/components/examples/error_payload_too_large"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "415": {
            "description": "Unsupported media type. One of:\n- `unsupported_media_type`: Unsupported media type.",
            "x-error-codes": [
              "unsupported_media_type"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unsupported_media_type": {
                    "$ref": "#/components/examples/error_unsupported_media_type"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Unprocessable. One of:\n- `agent_not_ready`: Agent not ready to call.\n- `calling_not_configured`: Calling not set up.\n- `outside_calling_hours`: Outside calling hours.\n- `phone_number_not_usable`: Phone number cannot be used for this call.\n- `phone_number_required`: Caller number must be chosen.\n- `dnc_listed`: Number on the do-not-call list.\n- `consent_required`: Consent required.\n- `contact_daily_limit_reached`: Daily call limit for this number reached.\n- `call_not_accepted`: Call not accepted.",
            "x-error-codes": [
              "agent_not_ready",
              "calling_not_configured",
              "outside_calling_hours",
              "phone_number_not_usable",
              "phone_number_required",
              "dnc_listed",
              "consent_required",
              "contact_daily_limit_reached",
              "call_not_accepted"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "agent_not_ready": {
                    "$ref": "#/components/examples/error_agent_not_ready"
                  },
                  "calling_not_configured": {
                    "$ref": "#/components/examples/error_calling_not_configured"
                  },
                  "outside_calling_hours": {
                    "$ref": "#/components/examples/error_outside_calling_hours"
                  },
                  "phone_number_not_usable": {
                    "$ref": "#/components/examples/error_phone_number_not_usable"
                  },
                  "phone_number_required": {
                    "$ref": "#/components/examples/error_phone_number_required"
                  },
                  "dnc_listed": {
                    "$ref": "#/components/examples/error_dnc_listed"
                  },
                  "consent_required": {
                    "$ref": "#/components/examples/error_consent_required"
                  },
                  "contact_daily_limit_reached": {
                    "$ref": "#/components/examples/error_contact_daily_limit_reached"
                  },
                  "call_not_accepted": {
                    "$ref": "#/components/examples/error_call_not_accepted"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.\n- `daily_call_limit_reached`: Daily call limit reached.\n- `calling_capacity_reached`: Calling capacity reached.",
            "x-error-codes": [
              "rate_limited",
              "daily_call_limit_reached",
              "calling_capacity_reached"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  },
                  "daily_call_limit_reached": {
                    "$ref": "#/components/examples/error_daily_call_limit_reached"
                  },
                  "calling_capacity_reached": {
                    "$ref": "#/components/examples/error_calling_capacity_reached"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listCalls",
        "summary": "List calls",
        "externalDocs": {
          "description": "Guide: Tracking call progress",
          "url": "https://docs.relationsai.com/guides/tracking-call-progress"
        },
        "description": "Lists calls, newest first, including calls placed from the console and by campaigns. Filter by\nagent, campaign, destination, status, outcome and creation time. List entries are the full call\nobject without the transcript; read artifacts from their own endpoints.\n\nCalls appear here as soon as they are accepted. Status and outcome are refreshed as the call\nprogresses, typically within seconds, occasionally a minute or more behind; `settled` marks a call\nwhose details are final.\n\nWhen you filter by `status`, a page can hold fewer than `limit` calls while `has_more` is true; keep\nfollowing `next_cursor` until it is null.\n",
        "tags": [
          "Calls"
        ],
        "x-required-scopes": [
          "calls:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Lists test-mode calls only.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/CreatedAfter"
          },
          {
            "$ref": "#/components/parameters/CreatedBefore"
          },
          {
            "name": "agent_id",
            "in": "query",
            "required": false,
            "description": "Only calls handled by this agent.",
            "schema": {
              "type": "string",
              "pattern": "^agent_[A-Za-z0-9_-]{1,58}$"
            }
          },
          {
            "name": "campaign_id",
            "in": "query",
            "required": false,
            "description": "Only calls placed by this campaign.",
            "schema": {
              "type": "string",
              "pattern": "^cmp_[A-Za-z0-9_-]{1,60}$"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Only calls to this number (E.164).",
            "schema": {
              "type": "string",
              "format": "e164",
              "pattern": "^\\+[1-9][0-9]{7,14}$"
            },
            "example": "+919000000001"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Only calls in this status.",
            "schema": {
              "type": "string",
              "enum": [
                "queued",
                "ringing",
                "in_progress",
                "ended",
                "unknown"
              ]
            }
          },
          {
            "name": "outcome",
            "in": "query",
            "required": false,
            "description": "Only ended calls with this outcome.",
            "schema": {
              "type": "string",
              "enum": [
                "completed",
                "no_response",
                "no_answer",
                "busy",
                "failed",
                "unknown"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of calls.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CallList"
                },
                "examples": {
                  "calls": {
                    "summary": "Two test-mode calls",
                    "value": {
                      "object": "list",
                      "data": [
                        {
                          "id": "call_9Tg5Yh2Uj8Ik4Ol7Pm3Nb6",
                          "object": "call",
                          "livemode": false,
                          "status": "ended",
                          "outcome": "no_answer",
                          "end_reason": "no_answer",
                          "direction": "outbound",
                          "source": "api",
                          "agent_id": "agent_1ZltiWzxrXmMprGD6q63",
                          "campaign_id": null,
                          "phone_number_id": "pn_6Vhm3sFrB5UpmXAnsvmDu",
                          "from": "+12025550150",
                          "to": "+12025550101",
                          "metadata": {},
                          "created_at": "2026-10-21T09:35:00.000Z",
                          "ended_at": "2026-10-21T09:35:18.000Z",
                          "duration_seconds": 0,
                          "billable_minutes": 0,
                          "cost": {
                            "amount": 0,
                            "currency": "INR"
                          },
                          "artifacts": {
                            "transcript": {
                              "state": "absent"
                            },
                            "recording": {
                              "state": "absent"
                            },
                            "analysis": {
                              "state": "absent"
                            }
                          },
                          "settled": true,
                          "settled_at": "2026-10-21T09:35:30.000Z"
                        },
                        {
                          "id": "call_6Vb3Nm8Qw2Er5Ty9Ui4Op7",
                          "object": "call",
                          "livemode": false,
                          "status": "queued",
                          "outcome": null,
                          "end_reason": null,
                          "direction": "outbound",
                          "source": "api",
                          "agent_id": "agent_1ZltiWzxrXmMprGD6q63",
                          "campaign_id": null,
                          "phone_number_id": "pn_6Vhm3sFrB5UpmXAnsvmDu",
                          "from": "+12025550150",
                          "to": "+12025550100",
                          "metadata": {
                            "crm_lead_id": "L-20931"
                          },
                          "created_at": "2026-10-21T09:30:00.000Z",
                          "ended_at": null,
                          "duration_seconds": null,
                          "billable_minutes": null,
                          "cost": null,
                          "artifacts": {
                            "transcript": {
                              "state": "pending"
                            },
                            "recording": {
                              "state": "pending"
                            },
                            "analysis": {
                              "state": "pending"
                            }
                          },
                          "settled": false,
                          "settled_at": null
                        }
                      ],
                      "has_more": false,
                      "next_cursor": null
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_cursor`: Invalid pagination cursor.\n- `invalid_phone_number`: Invalid phone number.",
            "x-error-codes": [
              "validation_error",
              "invalid_cursor",
              "invalid_phone_number"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_cursor": {
                    "$ref": "#/components/examples/error_invalid_cursor"
                  },
                  "invalid_phone_number": {
                    "$ref": "#/components/examples/error_invalid_phone_number"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/calls/{call_id}": {
      "get": {
        "operationId": "getCall",
        "summary": "Retrieve a call",
        "externalDocs": {
          "description": "Guide: Tracking call progress",
          "url": "https://docs.relationsai.com/guides/tracking-call-progress"
        },
        "description": "Returns one call with its status, outcome, timing, cost and the readiness of its artifacts.\nPoll it (no more than every few seconds) or, better, use webhooks. `outcome`, `duration_seconds`,\n`billable_minutes` and `cost` can still change until `settled` is true.\n",
        "tags": [
          "Calls"
        ],
        "x-required-scopes": [
          "calls:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Returns test-mode calls; status advances on the simulated timeline.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/CallId"
          }
        ],
        "responses": {
          "200": {
            "description": "The call.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Call"
                },
                "examples": {
                  "settled": {
                    "$ref": "#/components/examples/call_settled"
                  },
                  "no_answer": {
                    "$ref": "#/components/examples/call_no_answer"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.",
            "x-error-codes": [
              "validation_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/calls/{call_id}/transcript": {
      "get": {
        "operationId": "getCallTranscript",
        "summary": "Retrieve a call transcript",
        "externalDocs": {
          "description": "Guide: Retrieving recordings and transcripts",
          "url": "https://docs.relationsai.com/guides/retrieving-recordings-and-transcripts"
        },
        "description": "Returns the conversation turn by turn, verbatim. Transcripts are produced after the call ends\n(live transcripts are not available); until then `state` is `pending` and `turns` is empty. A call\nthat was not connected has `state: absent`. Reading the transcript never changes the call.\n",
        "tags": [
          "Calls"
        ],
        "x-required-scopes": [
          "transcripts:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Returns a fixture transcript with `simulated` true for completed test calls.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/CallId"
          }
        ],
        "responses": {
          "200": {
            "description": "The transcript, or its state while not ready.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CallTranscript"
                },
                "examples": {
                  "ready": {
                    "summary": "A ready transcript",
                    "value": {
                      "object": "call_transcript",
                      "livemode": true,
                      "call_id": "call_2Hd8Ks4Lq7Mw3Nx9Pz5Rc1",
                      "state": "ready",
                      "simulated": false,
                      "turns": [
                        {
                          "index": 0,
                          "speaker": "agent",
                          "text": "Hello, this is an AI assistant calling from Acme Lending. Am I speaking with Asha?",
                          "start_ms": 400,
                          "end_ms": 4900
                        },
                        {
                          "index": 1,
                          "speaker": "caller",
                          "text": "Yes, speaking.",
                          "start_ms": 5600,
                          "end_ms": 6500
                        }
                      ]
                    }
                  },
                  "pending": {
                    "summary": "Not ready yet",
                    "value": {
                      "object": "call_transcript",
                      "livemode": true,
                      "call_id": "call_6Vb3Nm8Qw2Er5Ty9Ui4Op7",
                      "state": "pending",
                      "simulated": false,
                      "turns": []
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.",
            "x-error-codes": [
              "validation_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/calls/{call_id}/recording": {
      "get": {
        "operationId": "getCallRecording",
        "summary": "Retrieve a call recording link",
        "externalDocs": {
          "description": "Guide: Retrieving recordings and transcripts",
          "url": "https://docs.relationsai.com/guides/retrieving-recordings-and-transcripts"
        },
        "description": "Returns the recording's state and, when it is ready, a short-lived HTTPS link to the audio\n(about 15 minutes; see `expires_at`). The link needs no API key, so treat it like a password and do\nnot log or store it; ask for a new one when you need it. Recordings are usually ready within a\nminute of the call ending. A call that was not answered has no recording (`state: absent`).\n",
        "tags": [
          "Calls"
        ],
        "x-required-scopes": [
          "recordings:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Completed test calls return a link to a short synthetic audio file with `simulated` true.",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/CallId"
          }
        ],
        "responses": {
          "200": {
            "description": "The recording state and, when ready, a fresh link.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CallRecording"
                },
                "examples": {
                  "ready": {
                    "summary": "Ready",
                    "value": {
                      "object": "call_recording",
                      "livemode": true,
                      "call_id": "call_2Hd8Ks4Lq7Mw3Nx9Pz5Rc1",
                      "state": "ready",
                      "simulated": false,
                      "url": "https://voice-api.relationsai.com/v1/recordings/rec_tok_Y2FsbF8ySGQ4S3M0THE3TXczTng5UHo1UmMx",
                      "expires_at": "2026-10-21T10:00:00.000Z",
                      "content_type": "audio/ogg"
                    }
                  },
                  "absent": {
                    "summary": "No recording",
                    "value": {
                      "object": "call_recording",
                      "livemode": false,
                      "call_id": "call_9Tg5Yh2Uj8Ik4Ol7Pm3Nb6",
                      "state": "absent",
                      "simulated": false,
                      "url": null,
                      "expires_at": null,
                      "content_type": null
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.",
            "x-error-codes": [
              "validation_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/calls/{call_id}/analysis": {
      "get": {
        "operationId": "getCallAnalysis",
        "summary": "Retrieve a call analysis",
        "externalDocs": {
          "description": "Guide: Working with analysis results",
          "url": "https://docs.relationsai.com/guides/working-with-analysis-results"
        },
        "description": "Returns the call summary, the fields the agent extracts from the conversation (configured in the\nconsole), and whether the call met its goal. Analysis is produced after the call ends, usually\nwithin a minute; each part has its own `state`. Sentiment is not offered.\n",
        "tags": [
          "Calls"
        ],
        "x-required-scopes": [
          "analysis:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Completed test calls return a fixture analysis with `simulated` true.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/CallId"
          }
        ],
        "responses": {
          "200": {
            "description": "The analysis, or its state while not ready.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CallAnalysis"
                },
                "examples": {
                  "ready": {
                    "summary": "Ready",
                    "value": {
                      "object": "call_analysis",
                      "livemode": true,
                      "call_id": "call_2Hd8Ks4Lq7Mw3Nx9Pz5Rc1",
                      "state": "ready",
                      "simulated": false,
                      "summary": {
                        "state": "ready",
                        "text": "The customer confirmed the renewal and asked for a callback on Friday afternoon."
                      },
                      "extracted_fields": [
                        {
                          "name": "wants_renewal",
                          "type": "boolean",
                          "state": "ready",
                          "value": true
                        },
                        {
                          "name": "callback_day",
                          "type": "string",
                          "state": "ready",
                          "value": "Friday"
                        }
                      ],
                      "goal_met": true
                    }
                  },
                  "pending": {
                    "summary": "Still being produced",
                    "value": {
                      "object": "call_analysis",
                      "livemode": true,
                      "call_id": "call_6Vb3Nm8Qw2Er5Ty9Ui4Op7",
                      "state": "pending",
                      "simulated": false,
                      "summary": {
                        "state": "pending",
                        "text": null
                      },
                      "extracted_fields": [],
                      "goal_met": null
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.",
            "x-error-codes": [
              "validation_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/recordings/{recording_token}": {
      "get": {
        "operationId": "downloadRecording",
        "summary": "Download recording audio",
        "externalDocs": {
          "description": "Guide: Retrieving recordings and transcripts",
          "url": "https://docs.relationsai.com/guides/retrieving-recordings-and-transcripts"
        },
        "description": "Streams the audio of a recording. You do not build this URL yourself: it is the `url` returned by\n`GET /v1/calls/{call_id}/recording`. The token in the path is the credential, so no\n`Authorization` header is needed (it is ignored), and the link stops working at its `expires_at`.\nScope: the key that calls `GET /v1/calls/{call_id}/recording` needs `recordings:read` to obtain the link;\nthe download itself needs no key and no scope (`x-required-scopes` names the scope behind the link).\nSupports `Range` requests for seeking; a range that cannot be served is answered with the whole file (200).\n",
        "tags": [
          "Calls"
        ],
        "security": [],
        "x-auth": "signed-url",
        "x-required-scopes": [
          "recordings:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Serves a short synthetic audio file (`audio/wav`, about one second).",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/RecordingToken"
          },
          {
            "name": "Range",
            "in": "header",
            "required": false,
            "description": "A byte range, for example `bytes=0-65535`.",
            "schema": {
              "type": "string",
              "pattern": "^bytes=[0-9]*-[0-9]*$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The whole audio file. The media type is the recording's own (`content_type` on the recording object); test-mode recordings are `audio/wav`.",
            "content": {
              "audio/ogg": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "audio/ogg",
                  "description": "Audio bytes."
                }
              },
              "audio/mpeg": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "audio/mpeg",
                  "description": "Audio bytes."
                }
              },
              "audio/wav": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "audio/wav",
                  "description": "Audio bytes (test-mode synthetic audio)."
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "206": {
            "description": "The requested byte range.",
            "content": {
              "audio/ogg": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "audio/ogg",
                  "description": "Audio bytes."
                }
              },
              "audio/mpeg": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "audio/mpeg",
                  "description": "Audio bytes."
                }
              },
              "audio/wav": {
                "schema": {
                  "type": "string",
                  "contentMediaType": "audio/wav",
                  "description": "Audio bytes (test-mode synthetic audio)."
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "410": {
            "description": "Error. One of:\n- `media_link_expired`: Recording link expired.",
            "x-error-codes": [
              "media_link_expired"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_link_expired": {
                    "$ref": "#/components/examples/error_media_link_expired"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/campaigns": {
      "post": {
        "operationId": "createCampaign",
        "summary": "Create a campaign",
        "externalDocs": {
          "description": "Guide: Running campaigns",
          "url": "https://docs.relationsai.com/guides/running-campaigns"
        },
        "description": "Creates a campaign in `draft` status. Nothing is dialled until you start it. You can add\nrecipients now (`contact_ids`) or later with the recipients endpoint, while the campaign is a\ndraft. Recipients are contacts: create them first, for example with the contact upsert.\n\nDo-not-call numbers are left out when a campaign starts and block a resume; there is no API option\nto include them. A campaign whose screening was switched off in the console is refused by start and\nresume (`409 campaign_dnc_override_enabled`).\n",
        "tags": [
          "Campaigns"
        ],
        "x-required-scopes": [
          "campaigns:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Creates a test-mode campaign that can only use test-mode contacts.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignCreateRequest"
              },
              "examples": {
                "campaign": {
                  "summary": "A campaign with two recipients",
                  "value": {
                    "name": "November renewals",
                    "agent_id": "agent_1ZltiWzxrXmMprGD6q63",
                    "concurrency_limit": 5,
                    "budget_cap": {
                      "amount": 500000,
                      "currency": "INR"
                    },
                    "contact_ids": [
                      "ct_8Rw2Tq5Lm9Xc3Vb7Nz4Kp1",
                      "ct_2Mh7Yd4Qs8Fv1Kc6Bx9Tn3"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The campaign was created as a draft.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                },
                "examples": {
                  "draft": {
                    "$ref": "#/components/examples/campaign_draft"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_json`: Invalid JSON body.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_json",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_json": {
                    "$ref": "#/components/examples/error_invalid_json"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "413": {
            "description": "Payload too large. One of:\n- `payload_too_large`: Payload too large.",
            "x-error-codes": [
              "payload_too_large"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "$ref": "#/components/examples/error_payload_too_large"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "415": {
            "description": "Unsupported media type. One of:\n- `unsupported_media_type`: Unsupported media type.",
            "x-error-codes": [
              "unsupported_media_type"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unsupported_media_type": {
                    "$ref": "#/components/examples/error_unsupported_media_type"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Unprocessable. One of:\n- `recipient_contacts_not_found`: Contacts not found.",
            "x-error-codes": [
              "recipient_contacts_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "recipient_contacts_not_found": {
                    "$ref": "#/components/examples/error_recipient_contacts_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listCampaigns",
        "summary": "List campaigns",
        "externalDocs": {
          "description": "Guide: Running campaigns",
          "url": "https://docs.relationsai.com/guides/running-campaigns"
        },
        "description": "Lists campaigns, newest first. Filter by `status`. Status and progress are refreshed in the background and can be up to a minute behind; a terminal status reached by the run itself (`completed`, `failed`) can take longer to appear.",
        "tags": [
          "Campaigns"
        ],
        "x-required-scopes": [
          "campaigns:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Lists test-mode campaigns only.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/CreatedAfter"
          },
          {
            "$ref": "#/components/parameters/CreatedBefore"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Only campaigns in this status.",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "running",
                "paused",
                "stopped",
                "completed",
                "failed",
                "unknown"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of campaigns.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignList"
                },
                "examples": {
                  "campaigns": {
                    "summary": "One running campaign",
                    "value": {
                      "object": "list",
                      "data": [
                        {
                          "id": "cmp_7Wq3Er9Ty2Ui5Op8As4Df6",
                          "object": "campaign",
                          "livemode": true,
                          "name": "November renewals",
                          "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                          "status": "running",
                          "capabilities": {
                            "start": false,
                            "pause": true,
                            "resume": false,
                            "stop": true,
                            "update": false,
                            "add_recipients": false
                          },
                          "concurrency_limit": 5,
                          "budget_cap": {
                            "amount": 500000,
                            "currency": "INR"
                          },
                          "recipient_count": 1200,
                          "progress": {
                            "calls": 640,
                            "connected": 410,
                            "no_answer": 190,
                            "failed": 35,
                            "in_progress": 5
                          },
                          "spend": {
                            "amount": 246000,
                            "currency": "INR"
                          },
                          "run_number": 1,
                          "dnc_screening": "enforced",
                          "created_at": "2026-10-20T08:00:00.000Z"
                        }
                      ],
                      "has_more": false,
                      "next_cursor": null
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_cursor`: Invalid pagination cursor.",
            "x-error-codes": [
              "validation_error",
              "invalid_cursor"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_cursor": {
                    "$ref": "#/components/examples/error_invalid_cursor"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/campaigns/{campaign_id}": {
      "get": {
        "operationId": "getCampaign",
        "summary": "Retrieve a campaign",
        "externalDocs": {
          "description": "Guide: Running campaigns",
          "url": "https://docs.relationsai.com/guides/running-campaigns"
        },
        "description": "Returns one campaign with its status, allowed actions (`capabilities`), progress and spend. The `ETag` header is the version to send as `If-Match` when you update it.",
        "tags": [
          "Campaigns"
        ],
        "x-required-scopes": [
          "campaigns:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Returns test-mode campaigns; their calls progress on the simulated timeline.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/CampaignId"
          }
        ],
        "responses": {
          "200": {
            "description": "The campaign.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                },
                "examples": {
                  "running": {
                    "$ref": "#/components/examples/campaign_running"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.",
            "x-error-codes": [
              "validation_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateCampaign",
        "summary": "Update a campaign",
        "externalDocs": {
          "description": "Guide: Running campaigns",
          "url": "https://docs.relationsai.com/guides/running-campaigns"
        },
        "description": "Changes a campaign's name, agent, concurrency or budget cap. Allowed in every status except\n`running` (pause it first). Changes take effect at the **next start**: a resume continues the paused\nrun with the settings it began with. Requires `If-Match` with the campaign's current `ETag`.\n",
        "tags": [
          "Campaigns"
        ],
        "x-required-scopes": [
          "campaigns:write"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "write",
        "x-test-mode": "Updates a test-mode campaign.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/CampaignId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignUpdateRequest"
              },
              "examples": {
                "raise_cap": {
                  "summary": "Raise the budget cap",
                  "value": {
                    "budget_cap": {
                      "amount": 750000,
                      "currency": "INR"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated campaign, with its new `ETag`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                },
                "examples": {
                  "updated": {
                    "$ref": "#/components/examples/campaign_paused"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_json`: Invalid JSON body.",
            "x-error-codes": [
              "validation_error",
              "invalid_json"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_json": {
                    "$ref": "#/components/examples/error_invalid_json"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `campaign_state_conflict`: Campaign is in the wrong state.",
            "x-error-codes": [
              "campaign_state_conflict"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "campaign_state_conflict": {
                    "$ref": "#/components/examples/error_campaign_state_conflict"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "412": {
            "description": "Precondition failed. One of:\n- `version_conflict`: Version conflict.",
            "x-error-codes": [
              "version_conflict"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "version_conflict": {
                    "$ref": "#/components/examples/error_version_conflict"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "413": {
            "description": "Payload too large. One of:\n- `payload_too_large`: Payload too large.",
            "x-error-codes": [
              "payload_too_large"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "$ref": "#/components/examples/error_payload_too_large"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "415": {
            "description": "Unsupported media type. One of:\n- `unsupported_media_type`: Unsupported media type.",
            "x-error-codes": [
              "unsupported_media_type"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unsupported_media_type": {
                    "$ref": "#/components/examples/error_unsupported_media_type"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "428": {
            "description": "Precondition required. One of:\n- `precondition_required`: If-Match required.",
            "x-error-codes": [
              "precondition_required"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "precondition_required": {
                    "$ref": "#/components/examples/error_precondition_required"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/campaigns/{campaign_id}/recipients": {
      "post": {
        "operationId": "addCampaignRecipients",
        "summary": "Add recipients",
        "externalDocs": {
          "description": "Guide: Running campaigns",
          "url": "https://docs.relationsai.com/guides/running-campaigns"
        },
        "description": "Adds contacts to a `draft` campaign. Contacts already in the campaign are skipped. Once a campaign\nhas started, its recipients are fixed: a later start calls the previous run's recipients again.\nTo call a different audience, create a new campaign. Up to 1000 contacts per request and 10,000\nper campaign.\n",
        "tags": [
          "Campaigns"
        ],
        "x-required-scopes": [
          "campaigns:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Adds test-mode contacts to a test-mode campaign.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/CampaignId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignRecipientsAddRequest"
              },
              "examples": {
                "add": {
                  "summary": "Add two contacts",
                  "value": {
                    "contact_ids": [
                      "ct_8Rw2Tq5Lm9Xc3Vb7Nz4Kp1",
                      "ct_2Mh7Yd4Qs8Fv1Kc6Bx9Tn3"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Recipients were added (or were already present).",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignRecipientsAddResult"
                },
                "examples": {
                  "added": {
                    "summary": "One new recipient",
                    "value": {
                      "object": "campaign_recipients_added",
                      "livemode": false,
                      "campaign_id": "cmp_2Kd7Fg4Hj9Lz3Xc8Vb5Nm1",
                      "added": 1,
                      "recipient_count": 3
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_json`: Invalid JSON body.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_json",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_json": {
                    "$ref": "#/components/examples/error_invalid_json"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.\n- `campaign_state_conflict`: Campaign is in the wrong state.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown",
              "campaign_state_conflict"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  },
                  "campaign_state_conflict": {
                    "$ref": "#/components/examples/error_campaign_state_conflict"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "413": {
            "description": "Payload too large. One of:\n- `payload_too_large`: Payload too large.",
            "x-error-codes": [
              "payload_too_large"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "$ref": "#/components/examples/error_payload_too_large"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "415": {
            "description": "Unsupported media type. One of:\n- `unsupported_media_type`: Unsupported media type.",
            "x-error-codes": [
              "unsupported_media_type"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unsupported_media_type": {
                    "$ref": "#/components/examples/error_unsupported_media_type"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Unprocessable. One of:\n- `recipient_contacts_not_found`: Contacts not found.",
            "x-error-codes": [
              "recipient_contacts_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "recipient_contacts_not_found": {
                    "$ref": "#/components/examples/error_recipient_contacts_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listCampaignRecipients",
        "summary": "List recipients",
        "externalDocs": {
          "description": "Guide: Running campaigns",
          "url": "https://docs.relationsai.com/guides/running-campaigns"
        },
        "description": "Lists a campaign's recipients with what happened to each in the current or latest run: status,\nattempts, the last call and its outcome, or why the recipient was left out. Recipients are listed\nin a stable order (not by time). Use the cursor to page; do not rely on the order meaning anything\nelse. Per-recipient results are refreshed in the background and can be\nup to a minute behind the calls themselves.\n",
        "tags": [
          "Campaigns"
        ],
        "x-required-scopes": [
          "campaigns:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Lists recipients of a test-mode campaign with simulated results.",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/CampaignId"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Only recipients in this status.",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "in_progress",
                "completed",
                "failed",
                "suppressed",
                "cancelled",
                "unknown"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of recipients.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignRecipientList"
                },
                "examples": {
                  "recipients": {
                    "summary": "Two recipients",
                    "value": {
                      "object": "list",
                      "data": [
                        {
                          "id": "rcp_3Gh8Jk2Lz5Xc9Vb4Nm7Qw1",
                          "object": "campaign_recipient",
                          "livemode": true,
                          "campaign_id": "cmp_7Wq3Er9Ty2Ui5Op8As4Df6",
                          "contact_id": "ct_8Rw2Tq5Lm9Xc3Vb7Nz4Kp1",
                          "phone_number": "+919000000001",
                          "status": "completed",
                          "attempts": 1,
                          "last_call_id": "call_2Hd8Ks4Lq7Mw3Nx9Pz5Rc1",
                          "outcome": "completed",
                          "suppression_reason": null
                        },
                        {
                          "id": "rcp_6Tr1Yu4Io7Pa2Sd5Fg8Hj3",
                          "object": "campaign_recipient",
                          "livemode": true,
                          "campaign_id": "cmp_7Wq3Er9Ty2Ui5Op8As4Df6",
                          "contact_id": "ct_2Mh7Yd4Qs8Fv1Kc6Bx9Tn3",
                          "phone_number": "+919000000002",
                          "status": "suppressed",
                          "attempts": 0,
                          "last_call_id": null,
                          "outcome": null,
                          "suppression_reason": "dnc_listed"
                        }
                      ],
                      "has_more": true,
                      "next_cursor": "eyJ2IjoxLCJrIjoicmNwXzZUcjFZdTRJbzdQYTJTZDVGZzhIajMifQ.4f7a2c"
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_cursor`: Invalid pagination cursor.",
            "x-error-codes": [
              "validation_error",
              "invalid_cursor"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_cursor": {
                    "$ref": "#/components/examples/error_invalid_cursor"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/campaigns/{campaign_id}/start": {
      "post": {
        "operationId": "startCampaign",
        "summary": "Start a campaign",
        "externalDocs": {
          "description": "Guide: Running campaigns",
          "url": "https://docs.relationsai.com/guides/running-campaigns"
        },
        "description": "Starts a run: from `draft` it calls the recipients you added; from `stopped`, `completed` or\n`paused` it begins a new run with the previous run's recipients (a paused run is abandoned; use\nresume to continue it instead).\n\nBefore anything is dialled the API checks the agent, the account, balance and spend limits, the\ncampaign budget cap, calling hours and the telephony connection, and screens every recipient\nagainst the do-not-call list, consent and the per-number daily limit. Blocked recipients are left\nout (see the recipients list); if that leaves nobody, the start is refused. Screening happens at the\nstart: a number added to the do-not-call list while the run is going is still called by it (pause and\nresume to re-screen, or stop). A campaign whose do-not-call screening was switched off in the console\nis refused (`409 campaign_dnc_override_enabled`).\n\n**Daily call limit.** In live mode a start counts every recipient of the campaign against the\nworkspace's daily limit of calls placed through the API (see `limits.daily_call_limit` on the\nworkspace), before anything is dialled, because the run may call each of them. A start that would go\npast the limit is refused whole with `429 daily_call_limit_reached`, and the message says how many calls\nit needed. A start refused for any other reason before dialling does not count. Test mode has no limit.\n\n**What 200 means.** The run was started and the campaign is `running`; calls are placed at up to\n`concurrency_limit` at a time. **202** means the start was sent but its confirmation has not\narrived yet; the campaign shows `running` and is reconciled automatically, so retrieve it in a\nminute rather than starting it again.\n",
        "tags": [
          "Campaigns"
        ],
        "x-required-scopes": [
          "campaigns:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "dial",
        "x-test-mode": "Nothing is dialled or charged; each recipient gets a simulated call chosen by their number, and campaign webhooks fire with `livemode` false.",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/CampaignId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "The run started.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                },
                "examples": {
                  "started": {
                    "$ref": "#/components/examples/campaign_started_test"
                  }
                }
              }
            }
          },
          "202": {
            "description": "The start was sent and is being confirmed. The campaign shows `running`; check it again shortly.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                },
                "examples": {
                  "unconfirmed": {
                    "$ref": "#/components/examples/campaign_running"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "402": {
            "description": "Payment required. One of:\n- `insufficient_balance`: Insufficient balance.\n- `spend_limit_reached`: Monthly spend limit reached.\n- `campaign_budget_reached`: Campaign budget reached.",
            "x-error-codes": [
              "insufficient_balance",
              "spend_limit_reached",
              "campaign_budget_reached"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_balance": {
                    "$ref": "#/components/examples/error_insufficient_balance"
                  },
                  "spend_limit_reached": {
                    "$ref": "#/components/examples/error_spend_limit_reached"
                  },
                  "campaign_budget_reached": {
                    "$ref": "#/components/examples/error_campaign_budget_reached"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.\n- `account_inactive`: Workspace account inactive.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser",
              "account_inactive"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  },
                  "account_inactive": {
                    "$ref": "#/components/examples/error_account_inactive"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.\n- `campaign_state_conflict`: Campaign is in the wrong state.\n- `campaign_operation_in_progress`: Another start or resume is in progress.\n- `campaign_outcome_unknown`: Campaign start or resume not confirmed.\n- `campaign_has_no_recipients`: Campaign has no recipients.\n- `campaign_dnc_override_enabled`: Campaign calls numbers on the do-not-call list.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown",
              "campaign_state_conflict",
              "campaign_operation_in_progress",
              "campaign_outcome_unknown",
              "campaign_has_no_recipients",
              "campaign_dnc_override_enabled"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  },
                  "campaign_state_conflict": {
                    "$ref": "#/components/examples/error_campaign_state_conflict"
                  },
                  "campaign_operation_in_progress": {
                    "$ref": "#/components/examples/error_campaign_operation_in_progress"
                  },
                  "campaign_outcome_unknown": {
                    "$ref": "#/components/examples/error_campaign_outcome_unknown"
                  },
                  "campaign_has_no_recipients": {
                    "$ref": "#/components/examples/error_campaign_has_no_recipients"
                  },
                  "campaign_dnc_override_enabled": {
                    "$ref": "#/components/examples/error_campaign_dnc_override_enabled"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "422": {
            "description": "Unprocessable. One of:\n- `agent_not_ready`: Agent not ready to call.\n- `calling_not_configured`: Calling not set up.\n- `outside_calling_hours`: Outside calling hours.\n- `campaign_recipients_suppressed`: Every recipient is suppressed.\n- `campaign_too_large`: Campaign too large.\n- `phone_number_required`: Caller number must be chosen.\n- `telephony_disconnected`: Telephony connection down.",
            "x-error-codes": [
              "agent_not_ready",
              "calling_not_configured",
              "outside_calling_hours",
              "campaign_recipients_suppressed",
              "campaign_too_large",
              "phone_number_required",
              "telephony_disconnected"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "agent_not_ready": {
                    "$ref": "#/components/examples/error_agent_not_ready"
                  },
                  "calling_not_configured": {
                    "$ref": "#/components/examples/error_calling_not_configured"
                  },
                  "outside_calling_hours": {
                    "$ref": "#/components/examples/error_outside_calling_hours"
                  },
                  "campaign_recipients_suppressed": {
                    "$ref": "#/components/examples/error_campaign_recipients_suppressed"
                  },
                  "campaign_too_large": {
                    "$ref": "#/components/examples/error_campaign_too_large"
                  },
                  "phone_number_required": {
                    "$ref": "#/components/examples/error_phone_number_required"
                  },
                  "telephony_disconnected": {
                    "$ref": "#/components/examples/error_telephony_disconnected"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.\n- `daily_call_limit_reached`: Daily call limit reached.",
            "x-error-codes": [
              "rate_limited",
              "daily_call_limit_reached"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  },
                  "daily_call_limit_reached": {
                    "$ref": "#/components/examples/error_daily_call_limit_reached"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.\n- `campaign_recipients_unavailable`: Recipients could not be checked.",
            "x-error-codes": [
              "service_unavailable",
              "campaign_recipients_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  },
                  "campaign_recipients_unavailable": {
                    "$ref": "#/components/examples/error_campaign_recipients_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/campaigns/{campaign_id}/pause": {
      "post": {
        "operationId": "pauseCampaign",
        "summary": "Pause a campaign",
        "externalDocs": {
          "description": "Guide: Running campaigns",
          "url": "https://docs.relationsai.com/guides/running-campaigns"
        },
        "description": "Pauses a `running` campaign: no new calls are started. Calls already connected finish normally and\nare charged as usual. The campaign is reported `paused` only once the pause is confirmed; if it is\nnot confirmed you get `409 campaign_pause_not_confirmed` and the campaign may still be dialling.\n",
        "tags": [
          "Campaigns"
        ],
        "x-required-scopes": [
          "campaigns:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Pauses the simulated run immediately.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/CampaignId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "The campaign is paused.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                },
                "examples": {
                  "paused": {
                    "$ref": "#/components/examples/campaign_paused"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.\n- `campaign_state_conflict`: Campaign is in the wrong state.\n- `campaign_pause_not_confirmed`: Pause not confirmed.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown",
              "campaign_state_conflict",
              "campaign_pause_not_confirmed"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  },
                  "campaign_state_conflict": {
                    "$ref": "#/components/examples/error_campaign_state_conflict"
                  },
                  "campaign_pause_not_confirmed": {
                    "$ref": "#/components/examples/error_campaign_pause_not_confirmed"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/campaigns/{campaign_id}/resume": {
      "post": {
        "operationId": "resumeCampaign",
        "summary": "Resume a campaign",
        "externalDocs": {
          "description": "Guide: Running campaigns",
          "url": "https://docs.relationsai.com/guides/running-campaigns"
        },
        "description": "Continues a `paused` campaign's run from where it stopped. Before anything is sent, the API checks\nthe agent, the account, balance and spend limits, the budget cap, calling hours and the telephony\nconnection, and screens **every recipient the run could still call** against the do-not-call list,\nconsent and the per-number daily limit.\n\nA resume cannot drop recipients from a run. So if any remaining recipient is now blocked (for\nexample added to the do-not-call list after the campaign started), nothing is resumed, the\ncampaign stays `paused`, and you get `409 campaign_recipients_blocked` with the blocked contacts.\nTo continue without them, list the recipients still `pending`, create a new campaign with those\ncontacts minus the blocked ones, start it, and stop this one (stopping does not hang up calls in\nprogress). Do not stop and start this campaign: a new start calls every recipient of the previous\nrun again, including people already reached, and charges for those calls. If too many recipients\nremain to re-screen, the resume is refused with `422 campaign_too_large`.\n\nA resume continues a run its start already counted against the daily call limit, so it counts\nnothing again.\n",
        "tags": [
          "Campaigns"
        ],
        "x-required-scopes": [
          "campaigns:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "dial",
        "x-test-mode": "Resumes the simulated run, with the same screening as live mode.",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/CampaignId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "The run resumed and the campaign is `running`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                },
                "examples": {
                  "resumed": {
                    "$ref": "#/components/examples/campaign_running"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "402": {
            "description": "Payment required. One of:\n- `insufficient_balance`: Insufficient balance.\n- `spend_limit_reached`: Monthly spend limit reached.\n- `campaign_budget_reached`: Campaign budget reached.",
            "x-error-codes": [
              "insufficient_balance",
              "spend_limit_reached",
              "campaign_budget_reached"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_balance": {
                    "$ref": "#/components/examples/error_insufficient_balance"
                  },
                  "spend_limit_reached": {
                    "$ref": "#/components/examples/error_spend_limit_reached"
                  },
                  "campaign_budget_reached": {
                    "$ref": "#/components/examples/error_campaign_budget_reached"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.\n- `account_inactive`: Workspace account inactive.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser",
              "account_inactive"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  },
                  "account_inactive": {
                    "$ref": "#/components/examples/error_account_inactive"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.\n- `campaign_state_conflict`: Campaign is in the wrong state.\n- `campaign_operation_in_progress`: Another start or resume is in progress.\n- `campaign_outcome_unknown`: Campaign start or resume not confirmed.\n- `campaign_not_resumable`: Campaign cannot be resumed.\n- `campaign_recipients_blocked`: Recipients now blocked by compliance.\n- `campaign_dnc_override_enabled`: Campaign calls numbers on the do-not-call list.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown",
              "campaign_state_conflict",
              "campaign_operation_in_progress",
              "campaign_outcome_unknown",
              "campaign_not_resumable",
              "campaign_recipients_blocked",
              "campaign_dnc_override_enabled"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  },
                  "campaign_state_conflict": {
                    "$ref": "#/components/examples/error_campaign_state_conflict"
                  },
                  "campaign_operation_in_progress": {
                    "$ref": "#/components/examples/error_campaign_operation_in_progress"
                  },
                  "campaign_outcome_unknown": {
                    "$ref": "#/components/examples/error_campaign_outcome_unknown"
                  },
                  "campaign_not_resumable": {
                    "$ref": "#/components/examples/error_campaign_not_resumable"
                  },
                  "campaign_recipients_blocked": {
                    "$ref": "#/components/examples/error_campaign_recipients_blocked"
                  },
                  "campaign_dnc_override_enabled": {
                    "$ref": "#/components/examples/error_campaign_dnc_override_enabled"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "422": {
            "description": "Unprocessable. One of:\n- `agent_not_ready`: Agent not ready to call.\n- `calling_not_configured`: Calling not set up.\n- `outside_calling_hours`: Outside calling hours.\n- `campaign_too_large`: Campaign too large.\n- `telephony_disconnected`: Telephony connection down.",
            "x-error-codes": [
              "agent_not_ready",
              "calling_not_configured",
              "outside_calling_hours",
              "campaign_too_large",
              "telephony_disconnected"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "agent_not_ready": {
                    "$ref": "#/components/examples/error_agent_not_ready"
                  },
                  "calling_not_configured": {
                    "$ref": "#/components/examples/error_calling_not_configured"
                  },
                  "outside_calling_hours": {
                    "$ref": "#/components/examples/error_outside_calling_hours"
                  },
                  "campaign_too_large": {
                    "$ref": "#/components/examples/error_campaign_too_large"
                  },
                  "telephony_disconnected": {
                    "$ref": "#/components/examples/error_telephony_disconnected"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.\n- `campaign_recipients_unavailable`: Recipients could not be checked.",
            "x-error-codes": [
              "service_unavailable",
              "campaign_recipients_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  },
                  "campaign_recipients_unavailable": {
                    "$ref": "#/components/examples/error_campaign_recipients_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/campaigns/{campaign_id}/stop": {
      "post": {
        "operationId": "stopCampaign",
        "summary": "Stop a campaign",
        "externalDocs": {
          "description": "Guide: Running campaigns",
          "url": "https://docs.relationsai.com/guides/running-campaigns"
        },
        "description": "Stops a `draft`, `running` or `paused` campaign. No further calls are started; calls already\nconnected finish normally. A stopped campaign can be started again, which begins a new run with\nthe same recipients.\n",
        "tags": [
          "Campaigns"
        ],
        "x-required-scopes": [
          "campaigns:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Stops the simulated run immediately.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/CampaignId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "The campaign is stopped.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign"
                },
                "examples": {
                  "stopped": {
                    "$ref": "#/components/examples/campaign_stopped"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.\n- `campaign_state_conflict`: Campaign is in the wrong state.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown",
              "campaign_state_conflict"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  },
                  "campaign_state_conflict": {
                    "$ref": "#/components/examples/error_campaign_state_conflict"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/contacts": {
      "post": {
        "operationId": "createContact",
        "summary": "Create a contact",
        "externalDocs": {
          "description": "Guide: Managing contacts",
          "url": "https://docs.relationsai.com/guides/managing-contacts"
        },
        "description": "Creates a contact. Phone numbers are unique within a workspace and mode; creating a second contact\nwith the same number is `409 contact_already_exists` (use the upsert to create-or-update).\n\nSetting `consent_granted: true` records that the person consented to be called, with the time and\nthe API as its source. Only set it when they really did: when the workspace requires consent, it\nis what allows calls to this contact.\n",
        "tags": [
          "Contacts"
        ],
        "x-required-scopes": [
          "contacts:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Creates a test-mode contact, visible only to test keys.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactCreateRequest"
              },
              "examples": {
                "contact": {
                  "summary": "A contact with consent and custom fields",
                  "value": {
                    "phone_number": "+12025550100",
                    "name": "Asha Rao",
                    "language": "en",
                    "country_code": "US",
                    "consent_granted": true,
                    "custom_fields": {
                      "policy_number": "PN-55012",
                      "due_date": "2026-11-05"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The contact was created.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                },
                "examples": {
                  "created": {
                    "$ref": "#/components/examples/contact"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_json`: Invalid JSON body.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.\n- `invalid_phone_number`: Invalid phone number.",
            "x-error-codes": [
              "validation_error",
              "invalid_json",
              "invalid_idempotency_key",
              "invalid_phone_number"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_json": {
                    "$ref": "#/components/examples/error_invalid_json"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  },
                  "invalid_phone_number": {
                    "$ref": "#/components/examples/error_invalid_phone_number"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.\n- `contact_already_exists`: Contact already exists.\n- `contact_limit_reached`: Contact limit reached.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown",
              "contact_already_exists",
              "contact_limit_reached"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  },
                  "contact_already_exists": {
                    "$ref": "#/components/examples/error_contact_already_exists"
                  },
                  "contact_limit_reached": {
                    "$ref": "#/components/examples/error_contact_limit_reached"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "413": {
            "description": "Payload too large. One of:\n- `payload_too_large`: Payload too large.",
            "x-error-codes": [
              "payload_too_large"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "$ref": "#/components/examples/error_payload_too_large"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "415": {
            "description": "Unsupported media type. One of:\n- `unsupported_media_type`: Unsupported media type.",
            "x-error-codes": [
              "unsupported_media_type"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unsupported_media_type": {
                    "$ref": "#/components/examples/error_unsupported_media_type"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Unprocessable. One of:\n- `custom_field_not_found`: Custom field not found.",
            "x-error-codes": [
              "custom_field_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "custom_field_not_found": {
                    "$ref": "#/components/examples/error_custom_field_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listContacts",
        "summary": "List contacts",
        "externalDocs": {
          "description": "Guide: Managing contacts",
          "url": "https://docs.relationsai.com/guides/managing-contacts"
        },
        "description": "Lists contacts, newest first. Filter by exact phone number, consent or do-not-call status.",
        "tags": [
          "Contacts"
        ],
        "x-required-scopes": [
          "contacts:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Lists test-mode contacts only.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/CreatedAfter"
          },
          {
            "$ref": "#/components/parameters/CreatedBefore"
          },
          {
            "name": "phone_number",
            "in": "query",
            "required": false,
            "description": "Only the contact with this number (E.164). Matches the same way the do-not-call check does.",
            "schema": {
              "type": "string",
              "format": "e164"
            },
            "example": "+919000000001"
          },
          {
            "name": "consent_granted",
            "in": "query",
            "required": false,
            "description": "Only contacts with (`true`) or without (`false`) recorded consent.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "do_not_call",
            "in": "query",
            "required": false,
            "description": "Only contacts on (`true`) or off (`false`) the do-not-call list.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of contacts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactList"
                },
                "examples": {
                  "contacts": {
                    "summary": "One contact",
                    "value": {
                      "object": "list",
                      "data": [
                        {
                          "id": "ct_8Rw2Tq5Lm9Xc3Vb7Nz4Kp1",
                          "object": "contact",
                          "livemode": false,
                          "phone_number": "+12025550100",
                          "name": "Asha Rao",
                          "language": "en",
                          "country_code": "US",
                          "consent_granted": true,
                          "do_not_call": false,
                          "custom_fields": {
                            "policy_number": "PN-55012",
                            "due_date": "2026-11-05"
                          },
                          "created_at": "2026-10-21T08:30:00.000Z"
                        }
                      ],
                      "has_more": false,
                      "next_cursor": null
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_cursor`: Invalid pagination cursor.\n- `invalid_phone_number`: Invalid phone number.",
            "x-error-codes": [
              "validation_error",
              "invalid_cursor",
              "invalid_phone_number"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_cursor": {
                    "$ref": "#/components/examples/error_invalid_cursor"
                  },
                  "invalid_phone_number": {
                    "$ref": "#/components/examples/error_invalid_phone_number"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/contacts/upsert": {
      "post": {
        "operationId": "upsertContact",
        "summary": "Create or update a contact by phone number",
        "externalDocs": {
          "description": "Guide: Managing contacts",
          "url": "https://docs.relationsai.com/guides/managing-contacts"
        },
        "description": "Creates the contact with this phone number, or updates it if one exists, in one request. The\nnumber is matched the same way the do-not-call check matches numbers, so a contact entered\nwithout the `+` and country code in the console is found too. Fields you omit are left unchanged\non an existing contact. The response is `201` when a contact was created and `200` when one was\nupdated. This is the recommended way to sync contacts from your CRM.\n",
        "tags": [
          "Contacts"
        ],
        "x-required-scopes": [
          "contacts:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Upserts a test-mode contact.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactUpsertRequest"
              },
              "examples": {
                "upsert": {
                  "summary": "Sync from a CRM",
                  "value": {
                    "phone_number": "+919000000001",
                    "name": "Asha Rao",
                    "consent_granted": true,
                    "custom_fields": {
                      "policy_number": "PN-55012"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "An existing contact was updated.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                },
                "examples": {
                  "updated": {
                    "$ref": "#/components/examples/contact_live"
                  }
                }
              }
            }
          },
          "201": {
            "description": "A new contact was created.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                },
                "examples": {
                  "created": {
                    "$ref": "#/components/examples/contact"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_json`: Invalid JSON body.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.\n- `invalid_phone_number`: Invalid phone number.",
            "x-error-codes": [
              "validation_error",
              "invalid_json",
              "invalid_idempotency_key",
              "invalid_phone_number"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_json": {
                    "$ref": "#/components/examples/error_invalid_json"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  },
                  "invalid_phone_number": {
                    "$ref": "#/components/examples/error_invalid_phone_number"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.\n- `contact_limit_reached`: Contact limit reached.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown",
              "contact_limit_reached"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  },
                  "contact_limit_reached": {
                    "$ref": "#/components/examples/error_contact_limit_reached"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "413": {
            "description": "Payload too large. One of:\n- `payload_too_large`: Payload too large.",
            "x-error-codes": [
              "payload_too_large"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "$ref": "#/components/examples/error_payload_too_large"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "415": {
            "description": "Unsupported media type. One of:\n- `unsupported_media_type`: Unsupported media type.",
            "x-error-codes": [
              "unsupported_media_type"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unsupported_media_type": {
                    "$ref": "#/components/examples/error_unsupported_media_type"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Unprocessable. One of:\n- `custom_field_not_found`: Custom field not found.",
            "x-error-codes": [
              "custom_field_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "custom_field_not_found": {
                    "$ref": "#/components/examples/error_custom_field_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/contacts/{contact_id}": {
      "get": {
        "operationId": "getContact",
        "summary": "Retrieve a contact",
        "externalDocs": {
          "description": "Guide: Managing contacts",
          "url": "https://docs.relationsai.com/guides/managing-contacts"
        },
        "description": "Returns one contact, with its consent, do-not-call status and custom field values. The `ETag` header is the version to send as `If-Match` when you update it.",
        "tags": [
          "Contacts"
        ],
        "x-required-scopes": [
          "contacts:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Returns test-mode contacts.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/ContactId"
          }
        ],
        "responses": {
          "200": {
            "description": "The contact.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                },
                "examples": {
                  "contact": {
                    "$ref": "#/components/examples/contact_live"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.",
            "x-error-codes": [
              "validation_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateContact",
        "summary": "Update a contact",
        "externalDocs": {
          "description": "Guide: Managing contacts",
          "url": "https://docs.relationsai.com/guides/managing-contacts"
        },
        "description": "Changes the fields you send. `custom_fields` merges: listed fields are set, a null value clears a\nfield, omitted fields are kept. `consent_granted` records consent (true) or its withdrawal (false)\nwith the time and the API as source. The do-not-call status cannot be changed here; use the\ndo-not-call endpoints. Requires `If-Match` with the contact's current `ETag`.\n",
        "tags": [
          "Contacts"
        ],
        "x-required-scopes": [
          "contacts:write"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "write",
        "x-test-mode": "Updates a test-mode contact.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/ContactId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactUpdateRequest"
              },
              "examples": {
                "withdraw": {
                  "summary": "Record that consent was withdrawn",
                  "value": {
                    "consent_granted": false
                  }
                },
                "fields": {
                  "summary": "Update a custom field and clear another",
                  "value": {
                    "custom_fields": {
                      "due_date": "2026-12-05",
                      "policy_number": null
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated contact, with its new `ETag`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                },
                "examples": {
                  "updated": {
                    "$ref": "#/components/examples/contact_live"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_json`: Invalid JSON body.\n- `invalid_phone_number`: Invalid phone number.",
            "x-error-codes": [
              "validation_error",
              "invalid_json",
              "invalid_phone_number"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_json": {
                    "$ref": "#/components/examples/error_invalid_json"
                  },
                  "invalid_phone_number": {
                    "$ref": "#/components/examples/error_invalid_phone_number"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `contact_already_exists`: Contact already exists.",
            "x-error-codes": [
              "contact_already_exists"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "contact_already_exists": {
                    "$ref": "#/components/examples/error_contact_already_exists"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "412": {
            "description": "Precondition failed. One of:\n- `version_conflict`: Version conflict.",
            "x-error-codes": [
              "version_conflict"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "version_conflict": {
                    "$ref": "#/components/examples/error_version_conflict"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "413": {
            "description": "Payload too large. One of:\n- `payload_too_large`: Payload too large.",
            "x-error-codes": [
              "payload_too_large"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "$ref": "#/components/examples/error_payload_too_large"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "415": {
            "description": "Unsupported media type. One of:\n- `unsupported_media_type`: Unsupported media type.",
            "x-error-codes": [
              "unsupported_media_type"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unsupported_media_type": {
                    "$ref": "#/components/examples/error_unsupported_media_type"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Unprocessable. One of:\n- `custom_field_not_found`: Custom field not found.",
            "x-error-codes": [
              "custom_field_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "custom_field_not_found": {
                    "$ref": "#/components/examples/error_custom_field_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "428": {
            "description": "Precondition required. One of:\n- `precondition_required`: If-Match required.",
            "x-error-codes": [
              "precondition_required"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "precondition_required": {
                    "$ref": "#/components/examples/error_precondition_required"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteContact",
        "summary": "Delete a contact",
        "externalDocs": {
          "description": "Guide: Managing contacts",
          "url": "https://docs.relationsai.com/guides/managing-contacts"
        },
        "description": "Permanently deletes a contact, its custom field values and its consent history, and removes it\nfrom every campaign's recipient list (a campaign that has already started keeps calling the\nrecipients its run began with). Calls to the contact remain in the call list. A contact on\nthe do-not-call list cannot be deleted (`409 contact_on_dnc_list`), so a deletion never removes a\ndo-not-call protection.\n",
        "tags": [
          "Contacts"
        ],
        "x-required-scopes": [
          "contacts:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Deletes a test-mode contact.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/ContactId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "The contact was deleted.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedObject"
                },
                "examples": {
                  "deleted": {
                    "summary": "Deleted",
                    "value": {
                      "id": "ct_8Rw2Tq5Lm9Xc3Vb7Nz4Kp1",
                      "object": "contact",
                      "livemode": false,
                      "deleted": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.\n- `contact_on_dnc_list`: Contact is on the do-not-call list.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown",
              "contact_on_dnc_list"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  },
                  "contact_on_dnc_list": {
                    "$ref": "#/components/examples/error_contact_on_dnc_list"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/dnc-entries": {
      "post": {
        "operationId": "createDncEntry",
        "summary": "Add a number to the do-not-call list",
        "externalDocs": {
          "description": "Guide: Consent and the do-not-call list",
          "url": "https://docs.relationsai.com/guides/consent-and-dnc"
        },
        "description": "Adds a number to the workspace do-not-call list, in the key's mode. From then on calls to it are\nrefused, campaigns leave it out when they start, and a paused campaign that still holds it cannot be\nresumed. A campaign that is already running is not screened again: pause and resume it (the resume\nis then refused while the number is a remaining recipient) or stop it.\n\nIf a contact has this number, it is marked `do_not_call: true` and its consent is withdrawn. If no\ncontact has it, a contact holding only the number is created so the number is visible in the\nconsole. Adding a number that is already on the list returns the existing entry with `200`.\n",
        "tags": [
          "Do-not-call list"
        ],
        "x-required-scopes": [
          "dnc:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Adds the number to the test-mode list, which blocks test calls exactly like live mode.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DncEntryCreateRequest"
              },
              "examples": {
                "add": {
                  "summary": "Block a number",
                  "value": {
                    "phone_number": "+919000000003"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The number was already on the list; the existing entry is returned.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DncEntry"
                },
                "examples": {
                  "existing": {
                    "summary": "Already listed",
                    "value": {
                      "id": "dnc_4Ty8Ui2Op6As3Df9Gh7Jk5",
                      "object": "dnc_entry",
                      "livemode": true,
                      "phone_number": "+919000000003",
                      "contact_id": "ct_5Qw8Er2Ty6Ui9Op3As7Df4",
                      "created_at": null
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "The number was added.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DncEntry"
                },
                "examples": {
                  "created": {
                    "summary": "Added",
                    "value": {
                      "id": "dnc_4Ty8Ui2Op6As3Df9Gh7Jk5",
                      "object": "dnc_entry",
                      "livemode": true,
                      "phone_number": "+919000000003",
                      "contact_id": "ct_5Qw8Er2Ty6Ui9Op3As7Df4",
                      "created_at": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_json`: Invalid JSON body.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.\n- `invalid_phone_number`: Invalid phone number.",
            "x-error-codes": [
              "validation_error",
              "invalid_json",
              "invalid_idempotency_key",
              "invalid_phone_number"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_json": {
                    "$ref": "#/components/examples/error_invalid_json"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  },
                  "invalid_phone_number": {
                    "$ref": "#/components/examples/error_invalid_phone_number"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.\n- `contact_limit_reached`: Contact limit reached.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown",
              "contact_limit_reached"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  },
                  "contact_limit_reached": {
                    "$ref": "#/components/examples/error_contact_limit_reached"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "413": {
            "description": "Payload too large. One of:\n- `payload_too_large`: Payload too large.",
            "x-error-codes": [
              "payload_too_large"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "$ref": "#/components/examples/error_payload_too_large"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "415": {
            "description": "Unsupported media type. One of:\n- `unsupported_media_type`: Unsupported media type.",
            "x-error-codes": [
              "unsupported_media_type"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unsupported_media_type": {
                    "$ref": "#/components/examples/error_unsupported_media_type"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listDncEntries",
        "summary": "List or look up do-not-call entries",
        "externalDocs": {
          "description": "Guide: Consent and the do-not-call list",
          "url": "https://docs.relationsai.com/guides/consent-and-dnc"
        },
        "description": "Lists the do-not-call list: in test mode newest entry first; in live mode by the contact,\nnewest first (live mode does not record when an entry was added). To check one number, pass `phone_number`: the result has\none entry if the number is on the list and none if it is not, using the same matching as the call\ncheck (formatting is ignored).\n",
        "tags": [
          "Do-not-call list"
        ],
        "x-required-scopes": [
          "dnc:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Lists the test-mode list only.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "name": "phone_number",
            "in": "query",
            "required": false,
            "description": "Look up one number (E.164).",
            "schema": {
              "type": "string",
              "format": "e164"
            },
            "example": "+919000000003"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of entries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DncEntryList"
                },
                "examples": {
                  "lookup_hit": {
                    "summary": "The number is listed",
                    "value": {
                      "object": "list",
                      "data": [
                        {
                          "id": "dnc_4Ty8Ui2Op6As3Df9Gh7Jk5",
                          "object": "dnc_entry",
                          "livemode": true,
                          "phone_number": "+919000000003",
                          "contact_id": "ct_5Qw8Er2Ty6Ui9Op3As7Df4",
                          "created_at": null
                        }
                      ],
                      "has_more": false,
                      "next_cursor": null
                    }
                  },
                  "lookup_miss": {
                    "summary": "The number is not listed",
                    "value": {
                      "object": "list",
                      "data": [],
                      "has_more": false,
                      "next_cursor": null
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_cursor`: Invalid pagination cursor.\n- `invalid_phone_number`: Invalid phone number.",
            "x-error-codes": [
              "validation_error",
              "invalid_cursor",
              "invalid_phone_number"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_cursor": {
                    "$ref": "#/components/examples/error_invalid_cursor"
                  },
                  "invalid_phone_number": {
                    "$ref": "#/components/examples/error_invalid_phone_number"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/dnc-entries/{dnc_entry_id}": {
      "delete": {
        "operationId": "deleteDncEntry",
        "summary": "Remove a number from the do-not-call list",
        "externalDocs": {
          "description": "Guide: Consent and the do-not-call list",
          "url": "https://docs.relationsai.com/guides/consent-and-dnc"
        },
        "description": "Removes a number from the do-not-call list, so it can be called again. The removal is recorded in\nthe workspace audit log with the API key that made it. Consent is not restored: if the workspace\nrequires consent, record it again on the contact only if the person gives it.\n",
        "tags": [
          "Do-not-call list"
        ],
        "x-required-scopes": [
          "dnc:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Removes a test-mode entry.",
        "x-availability": "ga-candidate",
        "parameters": [
          {
            "$ref": "#/components/parameters/DncEntryId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "The number is no longer on the list.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedObject"
                },
                "examples": {
                  "deleted": {
                    "summary": "Removed",
                    "value": {
                      "id": "dnc_4Ty8Ui2Op6As3Df9Gh7Jk5",
                      "object": "dnc_entry",
                      "livemode": true,
                      "deleted": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/webhook-endpoints": {
      "post": {
        "operationId": "createWebhookEndpoint",
        "externalDocs": {
          "description": "Guide: Receiving webhooks",
          "url": "https://docs.relationsai.com/guides/receiving-webhooks"
        },
        "summary": "Create a webhook endpoint",
        "description": "Registers an HTTPS URL to receive events of the key's mode. The response contains the signing\nsecret (`whsec_...`) **once**; store it to verify signatures. A replay with the same Idempotency-Key\nreturns the same endpoint with `secret: null` (the secret is never stored in readable form; if it was lost,\nrotate it). Every delivery is a POST with the\nevent as JSON and these headers: `RelationsAI-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of\n\"<t>.<raw body>\" with the secret>`, `RelationsAI-Event-Id`, `RelationsAI-Event-Type`,\n`RelationsAI-Delivery-Id` and `User-Agent: RelationsAI-Webhooks/1.0`. Reject a signature older\nthan 5 minutes.\n\nAnswer with any 2xx within 10 seconds. Anything else is retried after about 10 seconds, 1 minute,\n5 minutes, 30 minutes, 2 hours, 6 hours and 12 hours, then marked `failed`. Delivery is\nat-least-once and unordered. Redirects are not followed. The URL must be public HTTPS on port 443.\nBack-pressure: at most 2 attempts are in flight to one endpoint at a time; after 5 failed attempts in a\nrow an endpoint is paused (1 minute, doubling up to 1 hour) and its waiting deliveries are attempted\nafter the pause, without using up their attempts; one success resumes it. The endpoint is never\ndisabled automatically. Live-mode deliveries are attempted before test-mode ones, and a workspace's\ntest-mode deliveries are limited to 60 attempts a minute.\n",
        "tags": [
          "Webhook endpoints"
        ],
        "x-required-scopes": [
          "webhooks:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Creates a test-mode endpoint that receives only test-mode events (`livemode` false).",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointCreateRequest"
              },
              "examples": {
                "endpoint": {
                  "summary": "Call and campaign events",
                  "value": {
                    "url": "https://example.com/webhooks/relationsai",
                    "description": "CRM sync (test)",
                    "events": [
                      "call.ended",
                      "call.settled",
                      "campaign.completed"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The endpoint was created. Store `secret` now; it is not shown again.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointWithSecret"
                },
                "examples": {
                  "created": {
                    "$ref": "#/components/examples/endpoint_with_secret"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_json`: Invalid JSON body.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_json",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_json": {
                    "$ref": "#/components/examples/error_invalid_json"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.\n- `webhooks_not_enabled`: Webhooks not enabled.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser",
              "webhooks_not_enabled"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  },
                  "webhooks_not_enabled": {
                    "$ref": "#/components/examples/error_webhooks_not_enabled"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.\n- `webhook_endpoint_limit_reached`: Webhook endpoint limit reached.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown",
              "webhook_endpoint_limit_reached"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  },
                  "webhook_endpoint_limit_reached": {
                    "$ref": "#/components/examples/error_webhook_endpoint_limit_reached"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "413": {
            "description": "Payload too large. One of:\n- `payload_too_large`: Payload too large.",
            "x-error-codes": [
              "payload_too_large"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "$ref": "#/components/examples/error_payload_too_large"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "415": {
            "description": "Unsupported media type. One of:\n- `unsupported_media_type`: Unsupported media type.",
            "x-error-codes": [
              "unsupported_media_type"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unsupported_media_type": {
                    "$ref": "#/components/examples/error_unsupported_media_type"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Unprocessable. One of:\n- `webhook_url_not_allowed`: Webhook URL not allowed.",
            "x-error-codes": [
              "webhook_url_not_allowed"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "webhook_url_not_allowed": {
                    "$ref": "#/components/examples/error_webhook_url_not_allowed"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listWebhookEndpoints",
        "externalDocs": {
          "description": "Guide: Receiving webhooks",
          "url": "https://docs.relationsai.com/guides/receiving-webhooks"
        },
        "summary": "List webhook endpoints",
        "description": "Lists the webhook endpoints of the key's mode, newest first. Secrets are never listed, only their last four characters.",
        "tags": [
          "Webhook endpoints"
        ],
        "x-required-scopes": [
          "webhooks:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Lists test-mode endpoints only.",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of endpoints.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointList"
                },
                "examples": {
                  "endpoints": {
                    "summary": "One endpoint",
                    "value": {
                      "object": "list",
                      "data": [
                        {
                          "id": "we_9Pl3Ok7Ij2Uh6Yg4Tf8Rd1",
                          "object": "webhook_endpoint",
                          "livemode": false,
                          "url": "https://example.com/webhooks/relationsai",
                          "description": "CRM sync (test)",
                          "events": [
                            "call.ended",
                            "call.settled",
                            "campaign.completed"
                          ],
                          "status": "enabled",
                          "secret_last4": "x9Qa",
                          "created_at": "2026-10-21T08:00:00.000Z",
                          "updated_at": "2026-10-21T08:00:00.000Z",
                          "last_delivery": null
                        }
                      ],
                      "has_more": false,
                      "next_cursor": null
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_cursor`: Invalid pagination cursor.",
            "x-error-codes": [
              "validation_error",
              "invalid_cursor"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_cursor": {
                    "$ref": "#/components/examples/error_invalid_cursor"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/webhook-endpoints/{webhook_endpoint_id}": {
      "get": {
        "operationId": "getWebhookEndpoint",
        "externalDocs": {
          "description": "Guide: Receiving webhooks",
          "url": "https://docs.relationsai.com/guides/receiving-webhooks"
        },
        "summary": "Retrieve a webhook endpoint",
        "description": "Returns one webhook endpoint with a summary of its most recent delivery.",
        "tags": [
          "Webhook endpoints"
        ],
        "x-required-scopes": [
          "webhooks:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Returns test-mode endpoints.",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEndpointId"
          }
        ],
        "responses": {
          "200": {
            "description": "The endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                },
                "examples": {
                  "endpoint": {
                    "$ref": "#/components/examples/endpoint"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.",
            "x-error-codes": [
              "validation_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateWebhookEndpoint",
        "externalDocs": {
          "description": "Guide: Receiving webhooks",
          "url": "https://docs.relationsai.com/guides/receiving-webhooks"
        },
        "summary": "Update a webhook endpoint",
        "description": "Changes the URL, description, subscribed events or status. Disabling an endpoint stops new deliveries to it; events that occur while it is disabled are not delivered later.",
        "tags": [
          "Webhook endpoints"
        ],
        "x-required-scopes": [
          "webhooks:write"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "write",
        "x-test-mode": "Updates a test-mode endpoint.",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEndpointId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointUpdateRequest"
              },
              "examples": {
                "disable": {
                  "summary": "Disable the endpoint",
                  "value": {
                    "status": "disabled"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                },
                "examples": {
                  "endpoint": {
                    "$ref": "#/components/examples/endpoint"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_json`: Invalid JSON body.",
            "x-error-codes": [
              "validation_error",
              "invalid_json"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_json": {
                    "$ref": "#/components/examples/error_invalid_json"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "413": {
            "description": "Payload too large. One of:\n- `payload_too_large`: Payload too large.",
            "x-error-codes": [
              "payload_too_large"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "$ref": "#/components/examples/error_payload_too_large"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "415": {
            "description": "Unsupported media type. One of:\n- `unsupported_media_type`: Unsupported media type.",
            "x-error-codes": [
              "unsupported_media_type"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unsupported_media_type": {
                    "$ref": "#/components/examples/error_unsupported_media_type"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Unprocessable. One of:\n- `webhook_url_not_allowed`: Webhook URL not allowed.",
            "x-error-codes": [
              "webhook_url_not_allowed"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "webhook_url_not_allowed": {
                    "$ref": "#/components/examples/error_webhook_url_not_allowed"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhookEndpoint",
        "externalDocs": {
          "description": "Guide: Receiving webhooks",
          "url": "https://docs.relationsai.com/guides/receiving-webhooks"
        },
        "summary": "Delete a webhook endpoint",
        "description": "Deletes the endpoint. Pending deliveries to it are cancelled. This cannot be undone.",
        "tags": [
          "Webhook endpoints"
        ],
        "x-required-scopes": [
          "webhooks:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Deletes a test-mode endpoint.",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEndpointId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "The endpoint was deleted.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedObject"
                },
                "examples": {
                  "deleted": {
                    "summary": "Deleted",
                    "value": {
                      "id": "we_9Pl3Ok7Ij2Uh6Yg4Tf8Rd1",
                      "object": "webhook_endpoint",
                      "livemode": false,
                      "deleted": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/webhook-endpoints/{webhook_endpoint_id}/rotate-secret": {
      "post": {
        "operationId": "rotateWebhookEndpointSecret",
        "externalDocs": {
          "description": "Guide: Verifying webhook signatures",
          "url": "https://docs.relationsai.com/guides/verifying-webhook-signatures"
        },
        "summary": "Rotate a webhook signing secret",
        "description": "Issues a new signing secret, returned once. During the grace period every delivery carries two\n`v1=` signatures, one per secret, so you can deploy the new secret without missing events; after\nit, only the new secret signs. At most two secrets ever sign a delivery.\n\nRotating again while a grace period runs:\n- `grace_period_hours: 0` is always allowed and retires EVERY previous secret immediately: use it when a\n  secret may have leaked, and deploy the new one at once.\n- a grace period above 0 keeps the OLDEST secret still signing (the one your receiver most likely uses)\n  until its original grace end, discards the secret issued by the rotation in between, and issues a new\n  one. Use it when the response to a rotation was lost.\n\nA replay of this request with the same Idempotency-Key returns the endpoint with `secret: null`: the\nsecret is shown only in the first response and is never stored in readable form. To recover a secret\nyou did not receive, rotate again (with a grace period, as above).\n",
        "tags": [
          "Webhook endpoints"
        ],
        "x-required-scopes": [
          "webhooks:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Rotates a test-mode endpoint's secret.",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEndpointId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookSecretRotateRequest"
              },
              "examples": {
                "day": {
                  "summary": "Keep the old secret for 24 hours",
                  "value": {
                    "grace_period_hours": 24
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The endpoint with its new secret. Store it now.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointWithSecret"
                },
                "examples": {
                  "rotated": {
                    "$ref": "#/components/examples/endpoint_with_secret"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_json`: Invalid JSON body.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_json",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_json": {
                    "$ref": "#/components/examples/error_invalid_json"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "413": {
            "description": "Payload too large. One of:\n- `payload_too_large`: Payload too large.",
            "x-error-codes": [
              "payload_too_large"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "$ref": "#/components/examples/error_payload_too_large"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "415": {
            "description": "Unsupported media type. One of:\n- `unsupported_media_type`: Unsupported media type.",
            "x-error-codes": [
              "unsupported_media_type"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unsupported_media_type": {
                    "$ref": "#/components/examples/error_unsupported_media_type"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/webhook-endpoints/{webhook_endpoint_id}/test": {
      "post": {
        "operationId": "sendWebhookEndpointTestEvent",
        "externalDocs": {
          "description": "Guide: Verifying webhook signatures",
          "url": "https://docs.relationsai.com/guides/verifying-webhook-signatures"
        },
        "summary": "Send a test event",
        "description": "Creates a `webhook_endpoint.test` event and delivers it to this endpoint only, signed like any other event. The response is the delivery, usually `pending`; read the deliveries list to see the result.",
        "tags": [
          "Webhook endpoints"
        ],
        "x-required-scopes": [
          "webhooks:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Works the same in both modes; the event has the endpoint's mode.",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEndpointId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "202": {
            "description": "The test event was created and its delivery scheduled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDelivery"
                },
                "examples": {
                  "scheduled": {
                    "$ref": "#/components/examples/delivery_pending"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.\n- `webhooks_not_enabled`: Webhooks not enabled.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser",
              "webhooks_not_enabled"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  },
                  "webhooks_not_enabled": {
                    "$ref": "#/components/examples/error_webhooks_not_enabled"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.\n- `webhook_endpoint_disabled`: Webhook endpoint disabled.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown",
              "webhook_endpoint_disabled"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  },
                  "webhook_endpoint_disabled": {
                    "$ref": "#/components/examples/error_webhook_endpoint_disabled"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/webhook-endpoints/{webhook_endpoint_id}/deliveries": {
      "get": {
        "operationId": "listWebhookDeliveries",
        "externalDocs": {
          "description": "Guide: Receiving webhooks",
          "url": "https://docs.relationsai.com/guides/receiving-webhooks"
        },
        "summary": "List deliveries",
        "description": "Lists deliveries to this endpoint, newest first, for troubleshooting. Deliveries are kept for 30 days.",
        "tags": [
          "Webhook endpoints"
        ],
        "x-required-scopes": [
          "webhooks:read"
        ],
        "x-idempotency": "none",
        "x-rate-limit-class": "read",
        "x-test-mode": "Lists deliveries of a test-mode endpoint.",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookEndpointId"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Only deliveries in this status.",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "retrying",
                "succeeded",
                "failed"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of deliveries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryList"
                },
                "examples": {
                  "deliveries": {
                    "summary": "One delivery",
                    "value": {
                      "object": "list",
                      "data": [
                        {
                          "id": "wd_1Qa5Ws9Ed3Rf7Tg2Yh6Uj4",
                          "object": "webhook_delivery",
                          "livemode": false,
                          "webhook_endpoint_id": "we_9Pl3Ok7Ij2Uh6Yg4Tf8Rd1",
                          "event_id": "evt_5Zx9Cv3Bn7Mq2Wl8Ek4Rt6",
                          "event_type": "call.ended",
                          "status": "succeeded",
                          "attempts": 1,
                          "last_attempt_at": "2026-10-21T09:31:02.000Z",
                          "next_attempt_at": null,
                          "response_status": 200,
                          "duration_ms": 184,
                          "error": null,
                          "created_at": "2026-10-21T09:31:01.000Z"
                        }
                      ],
                      "has_more": false,
                      "next_cursor": null
                    }
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_cursor`: Invalid pagination cursor.",
            "x-error-codes": [
              "validation_error",
              "invalid_cursor"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_cursor": {
                    "$ref": "#/components/examples/error_invalid_cursor"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    },
    "/webhook-deliveries/{webhook_delivery_id}/retry": {
      "post": {
        "operationId": "retryWebhookDelivery",
        "externalDocs": {
          "description": "Guide: Receiving webhooks",
          "url": "https://docs.relationsai.com/guides/receiving-webhooks"
        },
        "summary": "Retry a delivery",
        "description": "Schedules an immediate new attempt of a `failed` or `retrying` delivery. The event and its id are unchanged, so your duplicate check still works.",
        "tags": [
          "Webhook endpoints"
        ],
        "x-required-scopes": [
          "webhooks:write"
        ],
        "x-idempotency": "optional",
        "x-rate-limit-class": "write",
        "x-test-mode": "Retries a test-mode delivery.",
        "x-availability": "preview",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookDeliveryId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "202": {
            "description": "A new attempt was scheduled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDelivery"
                },
                "examples": {
                  "scheduled": {
                    "$ref": "#/components/examples/delivery_pending"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request. One of:\n- `validation_error`: Validation failed.\n- `invalid_idempotency_key`: Invalid Idempotency-Key.",
            "x-error-codes": [
              "validation_error",
              "invalid_idempotency_key"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "$ref": "#/components/examples/error_validation_error"
                  },
                  "invalid_idempotency_key": {
                    "$ref": "#/components/examples/error_invalid_idempotency_key"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Unauthorized. One of:\n- `authentication_required`: Authentication required.\n- `invalid_api_key`: Invalid API key.\n- `api_key_expired`: API key expired.\n- `api_key_revoked`: API key revoked.\n- `legacy_api_key_not_supported`: Legacy API key not supported.",
            "x-error-codes": [
              "authentication_required",
              "invalid_api_key",
              "api_key_expired",
              "api_key_revoked",
              "legacy_api_key_not_supported"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "$ref": "#/components/examples/error_authentication_required"
                  },
                  "invalid_api_key": {
                    "$ref": "#/components/examples/error_invalid_api_key"
                  },
                  "api_key_expired": {
                    "$ref": "#/components/examples/error_api_key_expired"
                  },
                  "api_key_revoked": {
                    "$ref": "#/components/examples/error_api_key_revoked"
                  },
                  "legacy_api_key_not_supported": {
                    "$ref": "#/components/examples/error_legacy_api_key_not_supported"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Forbidden. One of:\n- `insufficient_scope`: Insufficient scope.\n- `insufficient_permissions`: Key creator lacks permission.\n- `api_access_not_enabled`: API access not enabled.\n- `ip_not_allowed`: IP address not allowed.\n- `live_key_not_allowed_in_browser`: Live key used from a browser.\n- `webhooks_not_enabled`: Webhooks not enabled.",
            "x-error-codes": [
              "insufficient_scope",
              "insufficient_permissions",
              "api_access_not_enabled",
              "ip_not_allowed",
              "live_key_not_allowed_in_browser",
              "webhooks_not_enabled"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "$ref": "#/components/examples/error_insufficient_scope"
                  },
                  "insufficient_permissions": {
                    "$ref": "#/components/examples/error_insufficient_permissions"
                  },
                  "api_access_not_enabled": {
                    "$ref": "#/components/examples/error_api_access_not_enabled"
                  },
                  "ip_not_allowed": {
                    "$ref": "#/components/examples/error_ip_not_allowed"
                  },
                  "live_key_not_allowed_in_browser": {
                    "$ref": "#/components/examples/error_live_key_not_allowed_in_browser"
                  },
                  "webhooks_not_enabled": {
                    "$ref": "#/components/examples/error_webhooks_not_enabled"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Not found. One of:\n- `resource_not_found`: Resource not found.",
            "x-error-codes": [
              "resource_not_found"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "$ref": "#/components/examples/error_resource_not_found"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Conflict. One of:\n- `idempotency_key_reused`: Idempotency-Key reused.\n- `idempotency_key_in_progress`: Request with this Idempotency-Key in progress.\n- `idempotency_outcome_unknown`: Outcome of the earlier request unknown.\n- `webhook_endpoint_disabled`: Webhook endpoint disabled.\n- `webhook_delivery_not_retryable`: Delivery cannot be retried.",
            "x-error-codes": [
              "idempotency_key_reused",
              "idempotency_key_in_progress",
              "idempotency_outcome_unknown",
              "webhook_endpoint_disabled",
              "webhook_delivery_not_retryable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "$ref": "#/components/examples/error_idempotency_key_reused"
                  },
                  "idempotency_key_in_progress": {
                    "$ref": "#/components/examples/error_idempotency_key_in_progress"
                  },
                  "idempotency_outcome_unknown": {
                    "$ref": "#/components/examples/error_idempotency_outcome_unknown"
                  },
                  "webhook_endpoint_disabled": {
                    "$ref": "#/components/examples/error_webhook_endpoint_disabled"
                  },
                  "webhook_delivery_not_retryable": {
                    "$ref": "#/components/examples/error_webhook_delivery_not_retryable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "429": {
            "description": "Too many requests. One of:\n- `rate_limited`: Rate limit exceeded.",
            "x-error-codes": [
              "rate_limited"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "$ref": "#/components/examples/error_rate_limited"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Internal error. One of:\n- `internal_error`: Internal error.",
            "x-error-codes": [
              "internal_error"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "$ref": "#/components/examples/error_internal_error"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Service unavailable. One of:\n- `service_unavailable`: Service temporarily unavailable.",
            "x-error-codes": [
              "service_unavailable"
            ],
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "$ref": "#/components/examples/error_service_unavailable"
                  }
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "call.ended": {
      "post": {
        "operationId": "onCallEnded",
        "summary": "Call ended",
        "description": "Sent when a call ends, whatever the outcome. `outcome`, `end_reason` and `duration_seconds` are known; the transcript, recording, analysis and charge may still be pending (see `call.settled`). In live mode it is sent once the end is observed, usually within seconds and at most a few minutes after the call ends. Delivered only to enabled endpoints subscribed to `call.ended`, in the event's mode, while webhooks are enabled for the workspace.",
        "tags": [
          "Webhook endpoints"
        ],
        "parameters": [
          {
            "name": "RelationsAI-Signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The HMAC is of `<t>.<raw body>` keyed with the endpoint secret. During a secret rotation a second `v1=` is present; accept the event if any matches. Reject `t` older than 5 minutes.",
            "schema": {
              "type": "string",
              "pattern": "^t=[0-9]+(,v1=[0-9a-f]{64})+$"
            }
          },
          {
            "name": "RelationsAI-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event id; the same as `id` in the body. Use it to discard duplicates.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Event-Type",
            "in": "header",
            "required": true,
            "description": "The event type; the same as `type` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery id (`wd_...`), different for each endpoint and unchanged across retries.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CallEvent"
              },
              "examples": {
                "event": {
                  "summary": "Call ended",
                  "value": {
                    "id": "evt_5Zx9Cv3Bn7Mq2Wl8Ek4Rt6",
                    "object": "event",
                    "type": "call.ended",
                    "created_at": "2026-10-21T09:32:15.000Z",
                    "livemode": true,
                    "api_version": "2026-10-21",
                    "data": {
                      "object": {
                        "id": "call_2Hd8Ks4Lq7Mw3Nx9Pz5Rc1",
                        "object": "call",
                        "livemode": true,
                        "status": "ended",
                        "outcome": "completed",
                        "end_reason": "hangup",
                        "direction": "outbound",
                        "source": "api",
                        "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                        "campaign_id": null,
                        "phone_number_id": "pn_5Lq8Xc2Rk9TzW3mBv7Np4d",
                        "from": "+918000000001",
                        "to": "+919000000001",
                        "metadata": {
                          "crm_lead_id": "L-20931"
                        },
                        "created_at": "2026-10-21T09:30:00.000Z",
                        "ended_at": "2026-10-21T09:32:14.000Z",
                        "duration_seconds": 118,
                        "billable_minutes": null,
                        "cost": null,
                        "artifacts": {
                          "transcript": {
                            "state": "pending"
                          },
                          "recording": {
                            "state": "pending"
                          },
                          "analysis": {
                            "state": "pending"
                          }
                        },
                        "settled": false,
                        "settled_at": null
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx answer within 10 seconds acknowledges the event. The body is ignored. Any other answer, a timeout or a redirect is retried."
          }
        }
      }
    },
    "call.settled": {
      "post": {
        "operationId": "onCallSettled",
        "summary": "Call settled",
        "description": "Sent once everything about a call is final: outcome, duration, transcript, recording, analysis and the charge. This can be several minutes after `call.ended`. Use it to sync final results to your systems. Delivered only to enabled endpoints subscribed to `call.settled`, in the event's mode, while webhooks are enabled for the workspace.",
        "tags": [
          "Webhook endpoints"
        ],
        "parameters": [
          {
            "name": "RelationsAI-Signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The HMAC is of `<t>.<raw body>` keyed with the endpoint secret. During a secret rotation a second `v1=` is present; accept the event if any matches. Reject `t` older than 5 minutes.",
            "schema": {
              "type": "string",
              "pattern": "^t=[0-9]+(,v1=[0-9a-f]{64})+$"
            }
          },
          {
            "name": "RelationsAI-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event id; the same as `id` in the body. Use it to discard duplicates.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Event-Type",
            "in": "header",
            "required": true,
            "description": "The event type; the same as `type` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery id (`wd_...`), different for each endpoint and unchanged across retries.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CallEvent"
              },
              "examples": {
                "event": {
                  "summary": "Call settled",
                  "value": {
                    "id": "evt_8Nm4Bv1Cx6Zl3Kj9Hg2Fd5",
                    "object": "event",
                    "type": "call.settled",
                    "created_at": "2026-10-21T09:41:02.000Z",
                    "livemode": true,
                    "api_version": "2026-10-21",
                    "data": {
                      "object": {
                        "id": "call_2Hd8Ks4Lq7Mw3Nx9Pz5Rc1",
                        "object": "call",
                        "livemode": true,
                        "status": "ended",
                        "outcome": "completed",
                        "end_reason": "hangup",
                        "direction": "outbound",
                        "source": "api",
                        "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                        "campaign_id": null,
                        "phone_number_id": "pn_5Lq8Xc2Rk9TzW3mBv7Np4d",
                        "from": "+918000000001",
                        "to": "+919000000001",
                        "metadata": {
                          "crm_lead_id": "L-20931"
                        },
                        "created_at": "2026-10-21T09:30:00.000Z",
                        "ended_at": "2026-10-21T09:32:14.000Z",
                        "duration_seconds": 118,
                        "billable_minutes": 2,
                        "cost": {
                          "amount": 600,
                          "currency": "INR"
                        },
                        "artifacts": {
                          "transcript": {
                            "state": "ready"
                          },
                          "recording": {
                            "state": "ready"
                          },
                          "analysis": {
                            "state": "ready"
                          }
                        },
                        "settled": true,
                        "settled_at": "2026-10-21T09:41:02.000Z"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx answer within 10 seconds acknowledges the event. The body is ignored. Any other answer, a timeout or a redirect is retried."
          }
        }
      }
    },
    "campaign.started": {
      "post": {
        "operationId": "onCampaignStarted",
        "summary": "Campaign started",
        "description": "Sent when a campaign run starts dialling, after a start request or when a start that was being confirmed is confirmed. Delivered only to enabled endpoints subscribed to `campaign.started`, in the event's mode, while webhooks are enabled for the workspace.",
        "tags": [
          "Webhook endpoints"
        ],
        "parameters": [
          {
            "name": "RelationsAI-Signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The HMAC is of `<t>.<raw body>` keyed with the endpoint secret. During a secret rotation a second `v1=` is present; accept the event if any matches. Reject `t` older than 5 minutes.",
            "schema": {
              "type": "string",
              "pattern": "^t=[0-9]+(,v1=[0-9a-f]{64})+$"
            }
          },
          {
            "name": "RelationsAI-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event id; the same as `id` in the body. Use it to discard duplicates.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Event-Type",
            "in": "header",
            "required": true,
            "description": "The event type; the same as `type` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery id (`wd_...`), different for each endpoint and unchanged across retries.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignEvent"
              },
              "examples": {
                "event": {
                  "summary": "Campaign started",
                  "value": {
                    "id": "evt_1Aq2Sw3De4Fr5Gt6Hy7Ju8",
                    "object": "event",
                    "type": "campaign.started",
                    "created_at": "2026-10-20T08:05:00.000Z",
                    "livemode": true,
                    "api_version": "2026-10-21",
                    "data": {
                      "object": {
                        "id": "cmp_7Wq3Er9Ty2Ui5Op8As4Df6",
                        "object": "campaign",
                        "livemode": true,
                        "name": "November renewals",
                        "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                        "dnc_screening": "enforced",
                        "status": "running",
                        "capabilities": {
                          "start": false,
                          "pause": true,
                          "resume": false,
                          "stop": true,
                          "update": false,
                          "add_recipients": false
                        },
                        "concurrency_limit": 5,
                        "budget_cap": {
                          "amount": 500000,
                          "currency": "INR"
                        },
                        "recipient_count": 1200,
                        "progress": {
                          "calls": 702,
                          "connected": 451,
                          "no_answer": 210,
                          "failed": 41,
                          "in_progress": 0
                        },
                        "spend": {
                          "amount": 270600,
                          "currency": "INR"
                        },
                        "run_number": 1,
                        "created_at": "2026-10-20T08:00:00.000Z"
                      },
                      "reason": null
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx answer within 10 seconds acknowledges the event. The body is ignored. Any other answer, a timeout or a redirect is retried."
          }
        }
      }
    },
    "campaign.paused": {
      "post": {
        "operationId": "onCampaignPaused",
        "summary": "Campaign paused",
        "description": "Sent when a campaign is paused, by a request or automatically. `data.reason` says why, for example `budget_cap_reached` or `insufficient_balance`. A campaign paused automatically can be resumed once the cause is fixed. Delivered only to enabled endpoints subscribed to `campaign.paused`, in the event's mode, while webhooks are enabled for the workspace.",
        "tags": [
          "Webhook endpoints"
        ],
        "parameters": [
          {
            "name": "RelationsAI-Signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The HMAC is of `<t>.<raw body>` keyed with the endpoint secret. During a secret rotation a second `v1=` is present; accept the event if any matches. Reject `t` older than 5 minutes.",
            "schema": {
              "type": "string",
              "pattern": "^t=[0-9]+(,v1=[0-9a-f]{64})+$"
            }
          },
          {
            "name": "RelationsAI-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event id; the same as `id` in the body. Use it to discard duplicates.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Event-Type",
            "in": "header",
            "required": true,
            "description": "The event type; the same as `type` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery id (`wd_...`), different for each endpoint and unchanged across retries.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignEvent"
              },
              "examples": {
                "event": {
                  "summary": "Campaign paused",
                  "value": {
                    "id": "evt_2Ws3Ed4Rf5Tg6Yh7Uj8Ik9",
                    "object": "event",
                    "type": "campaign.paused",
                    "created_at": "2026-10-20T11:42:00.000Z",
                    "livemode": true,
                    "api_version": "2026-10-21",
                    "data": {
                      "object": {
                        "id": "cmp_7Wq3Er9Ty2Ui5Op8As4Df6",
                        "object": "campaign",
                        "livemode": true,
                        "name": "November renewals",
                        "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                        "dnc_screening": "enforced",
                        "status": "paused",
                        "capabilities": {
                          "start": true,
                          "pause": false,
                          "resume": true,
                          "stop": true,
                          "update": true,
                          "add_recipients": false
                        },
                        "concurrency_limit": 5,
                        "budget_cap": {
                          "amount": 500000,
                          "currency": "INR"
                        },
                        "recipient_count": 1200,
                        "progress": {
                          "calls": 702,
                          "connected": 451,
                          "no_answer": 210,
                          "failed": 41,
                          "in_progress": 0
                        },
                        "spend": {
                          "amount": 270600,
                          "currency": "INR"
                        },
                        "run_number": 1,
                        "created_at": "2026-10-20T08:00:00.000Z"
                      },
                      "reason": "budget_cap_reached"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx answer within 10 seconds acknowledges the event. The body is ignored. Any other answer, a timeout or a redirect is retried."
          }
        }
      }
    },
    "campaign.resumed": {
      "post": {
        "operationId": "onCampaignResumed",
        "summary": "Campaign resumed",
        "description": "Sent when a paused campaign resumes its run. Delivered only to enabled endpoints subscribed to `campaign.resumed`, in the event's mode, while webhooks are enabled for the workspace.",
        "tags": [
          "Webhook endpoints"
        ],
        "parameters": [
          {
            "name": "RelationsAI-Signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The HMAC is of `<t>.<raw body>` keyed with the endpoint secret. During a secret rotation a second `v1=` is present; accept the event if any matches. Reject `t` older than 5 minutes.",
            "schema": {
              "type": "string",
              "pattern": "^t=[0-9]+(,v1=[0-9a-f]{64})+$"
            }
          },
          {
            "name": "RelationsAI-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event id; the same as `id` in the body. Use it to discard duplicates.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Event-Type",
            "in": "header",
            "required": true,
            "description": "The event type; the same as `type` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery id (`wd_...`), different for each endpoint and unchanged across retries.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignEvent"
              },
              "examples": {
                "event": {
                  "summary": "Campaign resumed",
                  "value": {
                    "id": "evt_3Ed4Rf5Tg6Yh7Uj8Ik9Ol1",
                    "object": "event",
                    "type": "campaign.resumed",
                    "created_at": "2026-10-20T12:10:00.000Z",
                    "livemode": true,
                    "api_version": "2026-10-21",
                    "data": {
                      "object": {
                        "id": "cmp_7Wq3Er9Ty2Ui5Op8As4Df6",
                        "object": "campaign",
                        "livemode": true,
                        "name": "November renewals",
                        "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                        "dnc_screening": "enforced",
                        "status": "running",
                        "capabilities": {
                          "start": false,
                          "pause": true,
                          "resume": false,
                          "stop": true,
                          "update": false,
                          "add_recipients": false
                        },
                        "concurrency_limit": 5,
                        "budget_cap": {
                          "amount": 500000,
                          "currency": "INR"
                        },
                        "recipient_count": 1200,
                        "progress": {
                          "calls": 702,
                          "connected": 451,
                          "no_answer": 210,
                          "failed": 41,
                          "in_progress": 0
                        },
                        "spend": {
                          "amount": 270600,
                          "currency": "INR"
                        },
                        "run_number": 1,
                        "created_at": "2026-10-20T08:00:00.000Z"
                      },
                      "reason": null
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx answer within 10 seconds acknowledges the event. The body is ignored. Any other answer, a timeout or a redirect is retried."
          }
        }
      }
    },
    "campaign.stopped": {
      "post": {
        "operationId": "onCampaignStopped",
        "summary": "Campaign stopped",
        "description": "Sent when a campaign is stopped. `data.reason` is `requested` for a stop request. Delivered only to enabled endpoints subscribed to `campaign.stopped`, in the event's mode, while webhooks are enabled for the workspace.",
        "tags": [
          "Webhook endpoints"
        ],
        "parameters": [
          {
            "name": "RelationsAI-Signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The HMAC is of `<t>.<raw body>` keyed with the endpoint secret. During a secret rotation a second `v1=` is present; accept the event if any matches. Reject `t` older than 5 minutes.",
            "schema": {
              "type": "string",
              "pattern": "^t=[0-9]+(,v1=[0-9a-f]{64})+$"
            }
          },
          {
            "name": "RelationsAI-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event id; the same as `id` in the body. Use it to discard duplicates.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Event-Type",
            "in": "header",
            "required": true,
            "description": "The event type; the same as `type` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery id (`wd_...`), different for each endpoint and unchanged across retries.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignEvent"
              },
              "examples": {
                "event": {
                  "summary": "Campaign stopped",
                  "value": {
                    "id": "evt_4Rf5Tg6Yh7Uj8Ik9Ol1Pm2",
                    "object": "event",
                    "type": "campaign.stopped",
                    "created_at": "2026-10-20T15:00:00.000Z",
                    "livemode": true,
                    "api_version": "2026-10-21",
                    "data": {
                      "object": {
                        "id": "cmp_7Wq3Er9Ty2Ui5Op8As4Df6",
                        "object": "campaign",
                        "livemode": true,
                        "name": "November renewals",
                        "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                        "dnc_screening": "enforced",
                        "status": "stopped",
                        "capabilities": {
                          "start": true,
                          "pause": false,
                          "resume": false,
                          "stop": false,
                          "update": true,
                          "add_recipients": false
                        },
                        "concurrency_limit": 5,
                        "budget_cap": {
                          "amount": 500000,
                          "currency": "INR"
                        },
                        "recipient_count": 1200,
                        "progress": {
                          "calls": 702,
                          "connected": 451,
                          "no_answer": 210,
                          "failed": 41,
                          "in_progress": 0
                        },
                        "spend": {
                          "amount": 270600,
                          "currency": "INR"
                        },
                        "run_number": 1,
                        "created_at": "2026-10-20T08:00:00.000Z"
                      },
                      "reason": "requested"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx answer within 10 seconds acknowledges the event. The body is ignored. Any other answer, a timeout or a redirect is retried."
          }
        }
      }
    },
    "campaign.completed": {
      "post": {
        "operationId": "onCampaignCompleted",
        "summary": "Campaign completed",
        "description": "Sent when a campaign run has worked through every recipient. In live mode it can arrive up to about 15 minutes after the last call ends. Delivered only to enabled endpoints subscribed to `campaign.completed`, in the event's mode, while webhooks are enabled for the workspace.",
        "tags": [
          "Webhook endpoints"
        ],
        "parameters": [
          {
            "name": "RelationsAI-Signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The HMAC is of `<t>.<raw body>` keyed with the endpoint secret. During a secret rotation a second `v1=` is present; accept the event if any matches. Reject `t` older than 5 minutes.",
            "schema": {
              "type": "string",
              "pattern": "^t=[0-9]+(,v1=[0-9a-f]{64})+$"
            }
          },
          {
            "name": "RelationsAI-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event id; the same as `id` in the body. Use it to discard duplicates.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Event-Type",
            "in": "header",
            "required": true,
            "description": "The event type; the same as `type` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery id (`wd_...`), different for each endpoint and unchanged across retries.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignEvent"
              },
              "examples": {
                "event": {
                  "summary": "Campaign completed",
                  "value": {
                    "id": "evt_5Tg6Yh7Uj8Ik9Ol1Pm2Nb3",
                    "object": "event",
                    "type": "campaign.completed",
                    "created_at": "2026-10-20T16:20:00.000Z",
                    "livemode": true,
                    "api_version": "2026-10-21",
                    "data": {
                      "object": {
                        "id": "cmp_7Wq3Er9Ty2Ui5Op8As4Df6",
                        "object": "campaign",
                        "livemode": true,
                        "name": "November renewals",
                        "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                        "dnc_screening": "enforced",
                        "status": "completed",
                        "capabilities": {
                          "start": true,
                          "pause": false,
                          "resume": false,
                          "stop": false,
                          "update": true,
                          "add_recipients": false
                        },
                        "concurrency_limit": 5,
                        "budget_cap": {
                          "amount": 500000,
                          "currency": "INR"
                        },
                        "recipient_count": 1200,
                        "progress": {
                          "calls": 702,
                          "connected": 451,
                          "no_answer": 210,
                          "failed": 41,
                          "in_progress": 0
                        },
                        "spend": {
                          "amount": 270600,
                          "currency": "INR"
                        },
                        "run_number": 1,
                        "created_at": "2026-10-20T08:00:00.000Z"
                      },
                      "reason": null
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx answer within 10 seconds acknowledges the event. The body is ignored. Any other answer, a timeout or a redirect is retried."
          }
        }
      }
    },
    "campaign.failed": {
      "post": {
        "operationId": "onCampaignFailed",
        "summary": "Campaign failed",
        "description": "Sent when a campaign run ends in failure before working through its recipients. In live mode it can arrive up to about 15 minutes after the run ends. Retrieve the recipients list to see who was reached. Delivered only to enabled endpoints subscribed to `campaign.failed`, in the event's mode, while webhooks are enabled for the workspace.",
        "tags": [
          "Webhook endpoints"
        ],
        "parameters": [
          {
            "name": "RelationsAI-Signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The HMAC is of `<t>.<raw body>` keyed with the endpoint secret. During a secret rotation a second `v1=` is present; accept the event if any matches. Reject `t` older than 5 minutes.",
            "schema": {
              "type": "string",
              "pattern": "^t=[0-9]+(,v1=[0-9a-f]{64})+$"
            }
          },
          {
            "name": "RelationsAI-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event id; the same as `id` in the body. Use it to discard duplicates.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Event-Type",
            "in": "header",
            "required": true,
            "description": "The event type; the same as `type` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery id (`wd_...`), different for each endpoint and unchanged across retries.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignEvent"
              },
              "examples": {
                "event": {
                  "summary": "Campaign failed",
                  "value": {
                    "id": "evt_6Yh7Uj8Ik9Ol1Pm2Nb3Vc4",
                    "object": "event",
                    "type": "campaign.failed",
                    "created_at": "2026-10-20T16:20:00.000Z",
                    "livemode": true,
                    "api_version": "2026-10-21",
                    "data": {
                      "object": {
                        "id": "cmp_7Wq3Er9Ty2Ui5Op8As4Df6",
                        "object": "campaign",
                        "livemode": true,
                        "name": "November renewals",
                        "agent_id": "agent_3hT9kQ2mVx7RbN4pLc8Wz1",
                        "dnc_screening": "enforced",
                        "status": "failed",
                        "capabilities": {
                          "start": true,
                          "pause": false,
                          "resume": false,
                          "stop": false,
                          "update": true,
                          "add_recipients": false
                        },
                        "concurrency_limit": 5,
                        "budget_cap": {
                          "amount": 500000,
                          "currency": "INR"
                        },
                        "recipient_count": 1200,
                        "progress": {
                          "calls": 702,
                          "connected": 451,
                          "no_answer": 210,
                          "failed": 41,
                          "in_progress": 0
                        },
                        "spend": {
                          "amount": 270600,
                          "currency": "INR"
                        },
                        "run_number": 1,
                        "created_at": "2026-10-20T08:00:00.000Z"
                      },
                      "reason": null
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx answer within 10 seconds acknowledges the event. The body is ignored. Any other answer, a timeout or a redirect is retried."
          }
        }
      }
    },
    "webhook_endpoint.test": {
      "post": {
        "operationId": "onWebhookEndpointTest",
        "summary": "Test event",
        "description": "Sent only when you call POST /v1/webhook-endpoints/{webhook_endpoint_id}/test, and only to that endpoint (which must be enabled). It cannot be subscribed to. `data.object` is the endpoint, never its secret. Use it to check your signature verification.",
        "tags": [
          "Webhook endpoints"
        ],
        "parameters": [
          {
            "name": "RelationsAI-Signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix seconds>,v1=<hex HMAC-SHA256>`. The HMAC is of `<t>.<raw body>` keyed with the endpoint secret. During a secret rotation a second `v1=` is present; accept the event if any matches. Reject `t` older than 5 minutes.",
            "schema": {
              "type": "string",
              "pattern": "^t=[0-9]+(,v1=[0-9a-f]{64})+$"
            }
          },
          {
            "name": "RelationsAI-Event-Id",
            "in": "header",
            "required": true,
            "description": "The event id; the same as `id` in the body. Use it to discard duplicates.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Event-Type",
            "in": "header",
            "required": true,
            "description": "The event type; the same as `type` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RelationsAI-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery id (`wd_...`), different for each endpoint and unchanged across retries.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookTestEvent"
              },
              "examples": {
                "event": {
                  "summary": "Test event",
                  "value": {
                    "id": "evt_3Df7Gh1Jk5Lz9Xc2Vb6Nm8",
                    "object": "event",
                    "type": "webhook_endpoint.test",
                    "created_at": "2026-10-21T09:45:00.000Z",
                    "livemode": false,
                    "api_version": "2026-10-21",
                    "data": {
                      "object": {
                        "id": "we_9Pl3Ok7Ij2Uh6Yg4Tf8Rd1",
                        "object": "webhook_endpoint",
                        "livemode": false,
                        "url": "https://example.com/webhooks/relationsai",
                        "description": "CRM sync (test)",
                        "events": [
                          "call.ended",
                          "call.settled",
                          "campaign.completed"
                        ],
                        "status": "enabled",
                        "secret_last4": "x9Qa",
                        "created_at": "2026-10-21T08:00:00.000Z",
                        "updated_at": "2026-10-21T08:00:00.000Z",
                        "last_delivery": null
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx answer within 10 seconds acknowledges the event. The body is ignored. Any other answer, a timeout or a redirect is retried."
          }
        }
      }
    }
  }
}
