{
  "components": {
    "schemas": {
      "AddDncBulkDto": {
        "properties": {
          "entries": {
            "description": "The suppressions to add, 1-1000. The whole batch is one transaction, so it either all lands or none of it does.",
            "items": {
              "additionalProperties": false,
              "properties": {
                "e164": {
                  "description": "The number to suppress, in E.164. Adding one already on the list is a no-op, not an error.",
                  "examples": [
                    "+919876543210"
                  ],
                  "pattern": "^\\+91\\d{10,11}$",
                  "type": "string"
                },
                "lockout90d": {
                  "default": false,
                  "description": "Apply the TCCCPR 90-day re-consent lockout instead of suppressing permanently — the number becomes contactable again on a specific date rather than never. Only meaningful for an opt-out.",
                  "examples": [
                    false
                  ],
                  "type": "boolean"
                },
                "reason": {
                  "description": "Why this number was suppressed. Free text, kept for the audit trail.",
                  "examples": [
                    "Asked to be removed during a call on 2026-08-20."
                  ],
                  "maxLength": 500,
                  "type": "string"
                },
                "source": {
                  "default": "manual",
                  "description": "Where the suppression came from. Recorded on the entry and shown in the evidence pack. Open set — handle an unrecognised value rather than throwing. Today: `manual`, `csv`, `api`, `caller_request`, `complaint`, `carrier_rejection`.",
                  "enum": [
                    "manual",
                    "csv",
                    "api",
                    "caller_request",
                    "complaint",
                    "carrier_rejection"
                  ],
                  "examples": [
                    "manual"
                  ],
                  "type": "string",
                  "x-known-values": [
                    "manual",
                    "csv",
                    "api",
                    "caller_request",
                    "complaint",
                    "carrier_rejection"
                  ]
                }
              },
              "required": [
                "e164"
              ],
              "type": "object"
            },
            "maxItems": 1000,
            "minItems": 1,
            "type": "array"
          }
        },
        "required": [
          "entries"
        ],
        "type": "object"
      },
      "AddDncDto": {
        "properties": {
          "e164": {
            "description": "The number to suppress, in E.164. Adding one already on the list is a no-op, not an error.",
            "examples": [
              "+919876543210"
            ],
            "pattern": "^\\+91\\d{10,11}$",
            "type": "string"
          },
          "lockout90d": {
            "default": false,
            "description": "Apply the TCCCPR 90-day re-consent lockout instead of suppressing permanently — the number becomes contactable again on a specific date rather than never. Only meaningful for an opt-out.",
            "examples": [
              false
            ],
            "type": "boolean"
          },
          "reason": {
            "description": "Why this number was suppressed. Free text, kept for the audit trail.",
            "examples": [
              "Asked to be removed during a call on 2026-08-20."
            ],
            "maxLength": 500,
            "type": "string"
          },
          "source": {
            "default": "manual",
            "description": "Where the suppression came from. Recorded on the entry and shown in the evidence pack. Open set — handle an unrecognised value rather than throwing. Today: `manual`, `csv`, `api`, `caller_request`, `complaint`, `carrier_rejection`.",
            "enum": [
              "manual",
              "csv",
              "api",
              "caller_request",
              "complaint",
              "carrier_rejection"
            ],
            "examples": [
              "manual"
            ],
            "type": "string",
            "x-known-values": [
              "manual",
              "csv",
              "api",
              "caller_request",
              "complaint",
              "carrier_rejection"
            ]
          }
        },
        "required": [
          "e164"
        ],
        "type": "object"
      },
      "AddRecipientsDto": {
        "properties": {
          "recipients": {
            "description": "The recipients to add, 1-500 per request. Retrying an identical batch is safe: duplicates are counted, not errored, so a timed-out request can simply be resent. A campaign holds at most 20,000 recipients.",
            "items": {
              "additionalProperties": false,
              "properties": {
                "e164": {
                  "description": "The number to dial, in E.164.",
                  "examples": [
                    "+919876543210"
                  ],
                  "pattern": "^\\+91\\d{10,11}$",
                  "type": "string"
                },
                "variables": {
                  "additionalProperties": {
                    "type": "string"
                  },
                  "description": "Per-recipient values for the agent input variables — the mapped CSV columns for this row. Values are strings because that is what a CSV holds; the agent own variable typing does the coercion.",
                  "examples": [
                    {
                      "name": "Priya",
                      "order_id": "AC-4417"
                    }
                  ],
                  "propertyNames": {
                    "type": "string"
                  },
                  "type": "object"
                }
              },
              "required": [
                "e164"
              ],
              "type": "object"
            },
            "maxItems": 500,
            "minItems": 1,
            "type": "array"
          }
        },
        "required": [
          "recipients"
        ],
        "type": "object"
      },
      "AddRecipientsResultResponse": {
        "properties": {
          "added": {
            "description": "How many recipients this request added. Duplicates are counted here rather than rejected, so retrying an identical batch is safe.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "duplicates": {
            "description": "Numbers already on this campaign. Skipped, not an error — which is what makes a retry safe.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "total": {
            "description": "Recipients on the campaign now.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          }
        },
        "required": [
          "added",
          "duplicates",
          "total"
        ],
        "type": "object"
      },
      "AddUrlDocumentDto": {
        "properties": {
          "url": {
            "description": "A public https:// page to fetch and index. Must be reachable from the open internet — private and link-local addresses are refused.",
            "examples": [
              "https://example.com/help/returns"
            ],
            "maxLength": 2000,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "type": "object"
      },
      "AgentResponse": {
        "properties": {
          "callSettings": {
            "description": "How a call RUNS — ambience, quiet-caller nudges, voicemail handling, length cap, farewell.",
            "examples": [
              {
                "background": {
                  "sound": "none",
                  "volume": 0.3
                },
                "hangupLine": {
                  "text": "Thanks for your time. Goodbye."
                },
                "maxCallSeconds": 600,
                "nudges": {
                  "enabled": true,
                  "hangupAfter": true,
                  "steps": [
                    {
                      "afterSeconds": 15,
                      "line": {
                        "text": null
                      }
                    }
                  ]
                },
                "openingLine": {
                  "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                },
                "voicemail": {
                  "enabled": true,
                  "windowSeconds": 30
                }
              }
            ]
          },
          "createdAt": {
            "description": "When the agent was created. RFC 3339, UTC.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          },
          "evaluationCriteria": {
            "description": "What the post-call judge grades each call against; produces `calls.evaluations`.",
            "examples": [
              [
                {
                  "id": "confirmed_order",
                  "name": "Confirmed the order",
                  "prompt": "Did the customer explicitly confirm they still want the order?"
                }
              ]
            ]
          },
          "id": {
            "description": "The agent's unique id.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "inputVariables": {
            "description": "Declared `{{placeholders}}` the prompt can use, with their defaults. Values are supplied per call via `variables`.",
            "examples": [
              [
                {
                  "default": "there",
                  "description": "The customer’s first name, as it appears on the order.",
                  "name": "customer_name"
                }
              ]
            ]
          },
          "knowledgeBaseIds": {
            "description": "Knowledge bases this agent may answer from.",
            "examples": [
              [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ]
            ],
            "items": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            },
            "type": "array"
          },
          "languages": {
            "description": "What the agent SPEAKS, primary first. A detected language outside this list is clamped to it.",
            "examples": [
              [
                "hi-IN",
                "en-IN"
              ]
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "llmProvider": {
            "description": "Who supplies the language model. Open set — read the current options from GET /v1/catalog/voice.",
            "examples": [
              "google"
            ],
            "type": "string"
          },
          "name": {
            "description": "Your name for the agent.",
            "examples": [
              "Order confirmation"
            ],
            "type": "string"
          },
          "outputVariables": {
            "description": "The post-call extraction schema — what shapes `calls.outputs`.",
            "examples": [
              [
                {
                  "description": "Which day the customer agreed to take delivery. Leave empty if they did not commit to one.",
                  "enumValues": [
                    "monday",
                    "tuesday",
                    "wednesday"
                  ],
                  "name": "delivery_day",
                  "type": "enum"
                }
              ]
            ]
          },
          "purpose": {
            "description": "The regulatory classification of calls this agent places. Drives the calling-window rules the compliance gate enforces — it is not cosmetic, and there is deliberately no per-call override. Open set — handle an unrecognised value rather than throwing. Today: `promotional`, `service`, `transactional`, `collections`.",
            "type": "string",
            "x-known-values": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ]
          },
          "status": {
            "description": "A `draft` agent can still be dialled outbound; an INBOUND call is refused until it is `live`, because a half-written prompt should not answer a real customer. Open set — handle an unrecognised value rather than throwing. Today: `draft`, `live`.",
            "type": "string",
            "x-known-values": [
              "draft",
              "live"
            ]
          },
          "sttLanguage": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pinned recognition language, or null to auto-detect.",
            "examples": [
              "auto"
            ]
          },
          "sttMode": {
            "description": "How the transcriber is asked to handle language — transcribing faithfully versus translating. Open set.",
            "examples": [
              "transcribe"
            ],
            "type": "string"
          },
          "sttModel": {
            "description": "Speech-to-text model id.",
            "examples": [
              "saaras:v3"
            ],
            "type": "string"
          },
          "sttProvider": {
            "description": "Who supplies speech-to-text. Open set.",
            "examples": [
              "sarvam"
            ],
            "type": "string"
          },
          "systemPrompt": {
            "description": "The agent’s instructions, verbatim.",
            "examples": [
              "You call customers to confirm a cash-on-delivery order…"
            ],
            "type": "string"
          },
          "tools": {
            "description": "Custom API tools the agent may call mid-conversation. Credentials appear only as `secretId` references, never inline.",
            "examples": [
              [
                {
                  "connectionId": "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d",
                  "description": "Call this once the customer has agreed to a specific delivery date and time window.",
                  "http": {
                    "auth": {
                      "header": "x-api-key",
                      "in": "header",
                      "name": "api_key",
                      "secondary": {
                        "in": "header",
                        "name": "x-acme-secret",
                        "secretId": "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                      },
                      "secretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                      "type": "bearer"
                    },
                    "bodyFormat": "json",
                    "bodyRoot": "object",
                    "headers": {
                      "x-acme-source": "tone"
                    },
                    "method": "POST",
                    "timeoutMs": 5000,
                    "url": "https://api.acme.example/v1/deliveries"
                  },
                  "mock": {
                    "enabled": true,
                    "response": "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                  },
                  "name": "book_delivery_slot",
                  "parameters": [
                    {
                      "description": "The agreed date as YYYY-MM-DD.",
                      "name": "delivery_date",
                      "required": true,
                      "type": "string"
                    }
                  ],
                  "preset": "cal.com/book",
                  "speech": {
                    "en-IN": "Let me check that for you.",
                    "hi-IN": "मैं अभी देखता हूँ।"
                  }
                }
              ]
            ]
          },
          "ttsModel": {
            "description": "Text-to-speech model id, e.g. `bulbul:v3`.",
            "examples": [
              "bulbul:v3"
            ],
            "type": "string"
          },
          "ttsOptions": {
            "description": "Voice tuning (pace, and model-specific fields). The legal keys and ranges differ per TTS model and are documented on the agent write schemas.",
            "examples": [
              {
                "pace": 1
              }
            ]
          },
          "ttsProvider": {
            "description": "Who supplies text-to-speech. Open set.",
            "examples": [
              "sarvam"
            ],
            "type": "string"
          },
          "ttsVoice": {
            "description": "Speaker id. NOT portable across model versions — a voice valid on `bulbul:v3` is a 400 on `bulbul:v2`. `GET /v1/catalog/voice` lists the legal pairings.",
            "examples": [
              "simran"
            ],
            "type": "string"
          },
          "updatedAt": {
            "description": "When the agent was last changed. RFC 3339, UTC.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "systemPrompt",
          "status",
          "purpose",
          "llmProvider",
          "sttProvider",
          "ttsProvider",
          "sttModel",
          "sttMode",
          "sttLanguage",
          "ttsModel",
          "ttsVoice",
          "ttsOptions",
          "languages",
          "inputVariables",
          "outputVariables",
          "evaluationCriteria",
          "tools",
          "callSettings",
          "knowledgeBaseIds",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "AgentVersionResponse": {
        "properties": {
          "agentId": {
            "description": "Which agent this version belongs to.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "callSettings": {
            "description": "Opening line, nudges, voicemail, background, hangup.",
            "examples": [
              {
                "background": {
                  "sound": "none",
                  "volume": 0.3
                },
                "hangupLine": {
                  "text": "Thanks for your time. Goodbye."
                },
                "maxCallSeconds": 600,
                "nudges": {
                  "enabled": true,
                  "hangupAfter": true,
                  "steps": [
                    {
                      "afterSeconds": 15,
                      "line": {
                        "text": null
                      }
                    }
                  ]
                },
                "openingLine": {
                  "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                },
                "voicemail": {
                  "enabled": true,
                  "windowSeconds": 30
                }
              }
            ]
          },
          "createdAt": {
            "description": "When it was published. RFC 3339, UTC.",
            "type": "string"
          },
          "evaluationCriteria": {
            "description": "The post-call judge’s criteria.",
            "examples": [
              [
                {
                  "id": "confirmed_order",
                  "name": "Confirmed the order",
                  "prompt": "Did the customer explicitly confirm they still want the order?"
                }
              ]
            ]
          },
          "id": {
            "description": "The agent version's unique id.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "inputVariables": {
            "description": "Declared input variables.",
            "examples": [
              [
                {
                  "default": "there",
                  "description": "The customer’s first name, as it appears on the order.",
                  "name": "customer_name"
                }
              ]
            ]
          },
          "knowledgeBaseIds": {
            "description": "Bases attached when this version was published. Their CONTENT is not frozen.",
            "items": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            },
            "type": "array"
          },
          "llmModel": {
            "description": "The model this version thought on.",
            "examples": [
              "gemini-2.5-flash"
            ],
            "type": "string"
          },
          "outputVariables": {
            "description": "Declared output variables — what extraction fills in.",
            "examples": [
              [
                {
                  "description": "Which day the customer agreed to take delivery. Leave empty if they did not commit to one.",
                  "enumValues": [
                    "monday",
                    "tuesday",
                    "wednesday"
                  ],
                  "name": "delivery_day",
                  "type": "enum"
                }
              ]
            ]
          },
          "purpose": {
            "description": "The regulatory classification this version ran under. Open set — handle an unrecognised value rather than throwing. Today: `promotional`, `service`, `transactional`, `collections`.",
            "type": "string",
            "x-known-values": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ]
          },
          "systemPrompt": {
            "description": "The prompt exactly as it was when this version was published. Immutable.",
            "examples": [
              "You call customers to confirm a cash-on-delivery order…"
            ],
            "type": "string"
          },
          "tools": {
            "description": "Tool definitions. Credentials appear only as `secretId` references — a version never holds a decrypted secret.",
            "examples": [
              [
                {
                  "connectionId": "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d",
                  "description": "Call this once the customer has agreed to a specific delivery date and time window.",
                  "http": {
                    "auth": {
                      "header": "x-api-key",
                      "in": "header",
                      "name": "api_key",
                      "secondary": {
                        "in": "header",
                        "name": "x-acme-secret",
                        "secretId": "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                      },
                      "secretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                      "type": "bearer"
                    },
                    "bodyFormat": "json",
                    "bodyRoot": "object",
                    "headers": {
                      "x-acme-source": "tone"
                    },
                    "method": "POST",
                    "timeoutMs": 5000,
                    "url": "https://api.acme.example/v1/deliveries"
                  },
                  "mock": {
                    "enabled": true,
                    "response": "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                  },
                  "name": "book_delivery_slot",
                  "parameters": [
                    {
                      "description": "The agreed date as YYYY-MM-DD.",
                      "name": "delivery_date",
                      "required": true,
                      "type": "string"
                    }
                  ],
                  "preset": "cal.com/book",
                  "speech": {
                    "en-IN": "Let me check that for you.",
                    "hi-IN": "मैं अभी देखता हूँ।"
                  }
                }
              ]
            ]
          },
          "ttsOptions": {
            "description": "Model-specific tuning as it stood.",
            "examples": [
              {
                "pace": 1
              }
            ]
          },
          "version": {
            "description": "Monotonic per agent, starting at 1. The number to quote in a rollback.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "voice": {
            "description": "The resolved Sarvam stack. A `(ttsModel, ttsVoice)` pair is validated at write time, so a version always holds a legal one.",
            "properties": {
              "languages": {
                "description": "Every language this version was allowed to speak, most-preferred first.",
                "examples": [
                  [
                    "hi-IN",
                    "en-IN"
                  ]
                ],
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "sttLanguage": {
                "description": "The language expected from the caller, or the auto-detect value.",
                "examples": [
                  "auto"
                ],
                "type": "string"
              },
              "sttMode": {
                "description": "How the transcriber treated the caller's language.",
                "examples": [
                  "transcribe"
                ],
                "type": "string"
              },
              "sttModel": {
                "description": "Which model transcribed the caller on calls pinned to this version.",
                "examples": [
                  "saaras:v3"
                ],
                "type": "string"
              },
              "ttsModel": {
                "description": "Which model spoke.",
                "examples": [
                  "bulbul:v3"
                ],
                "type": "string"
              },
              "ttsVoice": {
                "description": "Which voice spoke. Always legal for `ttsModel` — the pair is validated before a version is published.",
                "examples": [
                  "simran"
                ],
                "type": "string"
              }
            },
            "required": [
              "sttModel",
              "sttMode",
              "sttLanguage",
              "ttsModel",
              "ttsVoice",
              "languages"
            ],
            "type": "object"
          }
        },
        "required": [
          "id",
          "agentId",
          "version",
          "systemPrompt",
          "purpose",
          "llmModel",
          "voice",
          "ttsOptions",
          "inputVariables",
          "outputVariables",
          "evaluationCriteria",
          "tools",
          "callSettings",
          "knowledgeBaseIds",
          "createdAt"
        ],
        "type": "object"
      },
      "AssignNumberDto": {
        "properties": {
          "agentId": {
            "description": "Agent to answer on this number. Defaults to your first agent.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ],
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "series": {
            "description": "Which numbering series to allocate from. Note that `140` and `160` require an approved DLT Principal Entity ID, and neither is purchasable through a carrier API today — search and purchase only ever offer `regular`. Open set — handle an unrecognised value rather than throwing. Today: `regular`, `140`, `160`.",
            "enum": [
              "140",
              "160",
              "regular"
            ],
            "examples": [
              "regular"
            ],
            "type": "string",
            "x-known-values": [
              "regular",
              "140",
              "160"
            ]
          }
        },
        "required": [
          "series"
        ],
        "type": "object"
      },
      "CallOutcomeDto": {
        "properties": {
          "callReference": {
            "description": "Your own identifier for the call, echoed back on reads so you can reconcile against your CDR.",
            "examples": [
              "acme-crm-4417"
            ],
            "maxLength": 200,
            "type": "string"
          },
          "checkId": {
            "description": "The `checks[].id` from the verdict this call acted on, if you pre-flighted it. Ties the outcome to that verdict's audit rows.",
            "examples": [
              "8814"
            ],
            "pattern": "^\\d+$",
            "type": "string"
          },
          "durationSeconds": {
            "description": "How long the call lasted, in whole seconds.",
            "examples": [
              45
            ],
            "maximum": 9007199254740991,
            "minimum": 0,
            "type": "integer"
          },
          "e164": {
            "description": "The number that was called. Repeated even when `checkId` is present, so an outcome for a call you never pre-flighted still lands on the right number's evidence.",
            "examples": [
              "+919876543210"
            ],
            "pattern": "^\\+91\\d{10,11}$",
            "type": "string"
          },
          "notes": {
            "description": "Free text kept with the record and returned in the evidence pack.",
            "examples": [
              "Customer asked to be called after 6pm."
            ],
            "maxLength": 1000,
            "type": "string"
          },
          "occurredAt": {
            "description": "When the call happened. Defaults to now — send it explicitly when reporting in batches after the fact.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          },
          "outcome": {
            "description": "What happened. 🔴 `opt_out` and `complaint` are not just labels: they suppress the number through the same code path a mid-call opt-out uses — `opt_out` applies the 90-day re-consent lockout, `complaint` suppresses permanently. Both revoke every consent on record for that number in the same transaction. Open set — handle an unrecognised value rather than throwing. Today: `connected`, `no_answer`, `busy`, `failed`, `opt_out`, `complaint`, `wrong_number`.",
            "enum": [
              "connected",
              "no_answer",
              "busy",
              "failed",
              "opt_out",
              "complaint",
              "wrong_number"
            ],
            "examples": [
              "connected"
            ],
            "type": "string",
            "x-known-values": [
              "connected",
              "no_answer",
              "busy",
              "failed",
              "opt_out",
              "complaint",
              "wrong_number"
            ]
          }
        },
        "required": [
          "e164",
          "outcome"
        ],
        "type": "object"
      },
      "CallOutcomeResultResponse": {
        "properties": {
          "consentsRevoked": {
            "description": "How many consent records this outcome revoked. Non-zero only for an opt_out or a complaint, which suppress the number as well.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "e164": {
            "description": "The number the outcome was reported for, in E.164.",
            "examples": [
              "+919876543210"
            ],
            "type": "string"
          },
          "id": {
            "description": "The compliance-check row that recorded the outcome.",
            "examples": [
              "8814"
            ],
            "type": "string"
          },
          "outcome": {
            "description": "What you reported. Open set — handle an unrecognised value rather than throwing. Today: `connected`, `no_answer`, `busy`, `failed`, `opt_out`, `complaint`, `wrong_number`.",
            "type": "string",
            "x-known-values": [
              "connected",
              "no_answer",
              "busy",
              "failed",
              "opt_out",
              "complaint",
              "wrong_number"
            ]
          },
          "suppressed": {
            "description": "A suppression entry was written — this number will not be dialled again.",
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "e164",
          "outcome",
          "suppressed",
          "consentsRevoked"
        ],
        "type": "object"
      },
      "CallResponse": {
        "properties": {
          "agent": {
            "anyOf": [
              {
                "properties": {
                  "id": {
                    "description": "The agent's id.",
                    "examples": [
                      "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                    ],
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "type": "string"
                  },
                  "name": {
                    "description": "The agent's name at the time of the call.",
                    "examples": [
                      "Order confirmation"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "name"
                ],
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null for a BYO call — the number routes to your own stack, so there is no Tone agent."
          },
          "agentVersion": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which version of the agent ran this call. Pinned when the call was created, so it keeps saying what ran after the agent is edited — which is what makes bucketing outcomes by prompt possible. Null on a BYO call (no Tone agent) and on calls that predate versioning, where \"we do not know\" is the truthful answer.",
            "examples": [
              3
            ]
          },
          "billedPaise": {
            "description": "What this call actually cost, in paise. One debit per call.",
            "examples": [
              600
            ],
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "campaignId": {
            "anyOf": [
              {
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The campaign that placed this call, or null for a call you placed directly. This is how a `call.*` webhook is attributed when several campaigns are running at once — matching on `peer` cannot separate them, and a recipient row only ever names its LAST attempt, so retries have no other handle.",
            "examples": [
              null
            ]
          },
          "channel": {
            "description": "How it was carried. Open set — handle an unrecognised value rather than throwing. Today: `browser`, `pstn`.",
            "examples": [
              "pstn"
            ],
            "type": "string",
            "x-known-values": [
              "browser",
              "pstn"
            ]
          },
          "compliance": {
            "anyOf": [
              {
                "enum": [
                  "verified",
                  "flagged"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Aggregated posture: `verified` — checks ran and none flagged; `flagged` — one blocked or warned; null — no checks recorded. Per-check evidence is at `GET /v1/compliance/checks?call_id=`.",
            "examples": [
              "passed"
            ]
          },
          "createdAt": {
            "description": "RFC 3339, UTC.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          },
          "direction": {
            "description": "Which way the call went. Open set — handle an unrecognised value rather than throwing. Today: `inbound`, `outbound`.",
            "examples": [
              "outbound"
            ],
            "type": "string",
            "x-known-values": [
              "inbound",
              "outbound"
            ]
          },
          "disposition": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The outcome. Null until the call ends. Open set — handle an unrecognised value rather than throwing. Today: `answered`, `no_answer`, `busy`, `failed`, `voicemail`, `unknown`.",
            "examples": [
              "answered"
            ],
            "x-known-values": [
              "answered",
              "no_answer",
              "busy",
              "failed",
              "voicemail",
              "unknown"
            ]
          },
          "durationSeconds": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "How long the call was connected, in whole seconds. This is the billed quantity, rounded up to the minimum billable duration.",
            "examples": [
              45
            ]
          },
          "endReason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Free-form detail behind the disposition. Diagnostic, not a contract.",
            "examples": [
              "agent_ended"
            ]
          },
          "endedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the call finished. RFC 3339, UTC. Null until status is ended.",
            "examples": [
              "2026-08-25T09:15:11Z"
            ]
          },
          "environment": {
            "description": "`live` or `test` — inherited from the credential that placed it.",
            "examples": [
              "live"
            ],
            "type": "string"
          },
          "evaluations": {
            "anyOf": [
              {
                "additionalProperties": {
                  "properties": {
                    "rationale": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Why the judge reached that verdict, in one line. Null when the model gave no reason.",
                      "examples": [
                        "The customer said \"yes, I still want it\" when asked to confirm."
                      ]
                    },
                    "verdict": {
                      "description": "Open set — handle an unrecognised value rather than throwing. Today: `success`, `failure`, `unknown`.",
                      "type": "string",
                      "x-known-values": [
                        "success",
                        "failure",
                        "unknown"
                      ]
                    }
                  },
                  "required": [
                    "verdict",
                    "rationale"
                  ],
                  "type": "object"
                },
                "propertyNames": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "The post-call judge, keyed by your evaluation criteria. Null when it never ran."
          },
          "hasRecording": {
            "description": "Whether `GET /v1/calls/{id}/recording` will serve audio.",
            "examples": [
              true
            ],
            "type": "boolean"
          },
          "hasTranscript": {
            "description": "Whether `GET /v1/calls/{id}/transcript` will serve anything.",
            "examples": [
              true
            ],
            "type": "boolean"
          },
          "id": {
            "description": "The call's unique id.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "initiator": {
            "description": "What caused this call to happen.",
            "properties": {
              "id": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Which API key or user, when we know. Null for an inbound call, which presents no credential of yours.",
                "examples": [
                  "key_8f14a2c9"
                ]
              },
              "type": {
                "description": "Who started it. Open set — handle an unrecognised value rather than throwing. Today: `dashboard`, `api_key`, `inbound`, `sip`.",
                "examples": [
                  "api_key"
                ],
                "type": "string",
                "x-known-values": [
                  "dashboard",
                  "api_key",
                  "inbound",
                  "sip"
                ]
              }
            },
            "required": [
              "type",
              "id"
            ],
            "type": "object"
          },
          "number": {
            "anyOf": [
              {
                "properties": {
                  "e164": {
                    "description": "The number in E.164 — dialled from on an outbound call, rung on an inbound one.",
                    "examples": [
                      "+918045678901"
                    ],
                    "type": "string"
                  },
                  "id": {
                    "description": "The number's id.",
                    "examples": [
                      "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43"
                    ],
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "e164"
                ],
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "The Tone number this call used — the one dialled from outbound, the one rung inbound."
          },
          "outputs": {
            "anyOf": [
              {
                "additionalProperties": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "number"
                    },
                    {
                      "type": "boolean"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "propertyNames": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Structured extraction, keyed by your agent’s declared output variables. A key holding null means \"asked, not established\" — distinct from the whole field being null.",
            "examples": [
              {
                "confirmed": true,
                "delivery_day": "Thursday"
              }
            ]
          },
          "peer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The other end in E.164: the callee outbound, the caller inbound.",
            "examples": [
              "+919876543210"
            ]
          },
          "quality": {
            "description": "Latency as the caller experienced it. Null on calls that never connected.",
            "properties": {
              "answerP50Ms": {
                "anyOf": [
                  {
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Median time the agent took to produce its first audio for a turn, measured server-side. Lower than `perceivedP50Ms`, which also carries the network and the caller's own pause.",
                "examples": [
                  480
                ]
              },
              "perceivedP50Ms": {
                "anyOf": [
                  {
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Median gap between the caller finishing and the agent starting to speak."
              },
              "turns": {
                "anyOf": [
                  {
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "How many times the two sides swapped speaking. A completed call with 0 or 1 turns usually means nobody engaged — an answering machine, or a caller who never spoke.",
                "examples": [
                  6
                ]
              }
            },
            "required": [
              "turns",
              "perceivedP50Ms",
              "answerP50Ms"
            ],
            "type": "object"
          },
          "ratePaisePerMinute": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The rate this call was billed at, snapshotted when it was created.",
            "examples": [
              600
            ]
          },
          "startedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the call connected. RFC 3339, UTC. Null while it is still queued, and on a call that never connected.",
            "examples": [
              "2026-08-25T09:14:26Z"
            ]
          },
          "status": {
            "description": "Lifecycle position. `disposition` is only meaningful once this is `ended`. Open set — handle an unrecognised value rather than throwing. Today: `queued`, `in_progress`, `ended`.",
            "examples": [
              "ended"
            ],
            "type": "string",
            "x-known-values": [
              "queued",
              "in_progress",
              "ended"
            ]
          },
          "summary": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Post-call summary. Null until extraction lands, seconds after the call ends.",
            "examples": [
              "Customer confirmed the order and asked for Thursday delivery."
            ]
          },
          "variables": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string"
                },
                "propertyNames": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "The input-variable map this call ran with.",
            "examples": [
              {
                "customer_name": "Priya",
                "order_id": "AC-4417"
              }
            ]
          },
          "verdict": {
            "description": "Strict-AND rollup of `evaluations`. `not_evaluated` is not a failure. Open set — handle an unrecognised value rather than throwing. Today: `success`, `failure`, `unknown`, `not_evaluated`.",
            "examples": [
              "success"
            ],
            "type": "string",
            "x-known-values": [
              "success",
              "failure",
              "unknown",
              "not_evaluated"
            ]
          }
        },
        "required": [
          "id",
          "createdAt",
          "direction",
          "channel",
          "environment",
          "peer",
          "agent",
          "number",
          "agentVersion",
          "campaignId",
          "status",
          "disposition",
          "endReason",
          "startedAt",
          "endedAt",
          "durationSeconds",
          "ratePaisePerMinute",
          "billedPaise",
          "compliance",
          "initiator",
          "quality",
          "variables",
          "hasRecording",
          "hasTranscript",
          "summary",
          "outputs",
          "evaluations",
          "verdict"
        ],
        "type": "object"
      },
      "CampaignOutcomesResponse": {
        "properties": {
          "agentOutcome": {
            "additionalProperties": {
              "additionalProperties": {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "propertyNames": {
                "type": "string"
              },
              "type": "object"
            },
            "description": "Output-variable name → value → how many connected calls ended with it. Values are clipped at 80 characters and the whole tally at 400 rows: this serves a funnel, not a table.",
            "propertyNames": {
              "type": "string"
            },
            "type": "object"
          },
          "disposition": {
            "additionalProperties": {
              "maximum": 9007199254740991,
              "minimum": -9007199254740991,
              "type": "integer"
            },
            "description": "Dialled recipients by call outcome. Open set — handle an unrecognised value rather than throwing. Today: `answered`, `no_answer`, `busy`, `failed`, `voicemail`, `unknown`.",
            "propertyNames": {
              "type": "string"
            },
            "type": "object",
            "x-known-values": [
              "answered",
              "no_answer",
              "busy",
              "failed",
              "voicemail",
              "unknown"
            ]
          },
          "excludedReason": {
            "additionalProperties": {
              "maximum": 9007199254740991,
              "minimum": -9007199254740991,
              "type": "integer"
            },
            "description": "Excluded recipients by reason. Open set — handle an unrecognised value rather than throwing. Today: `invalid_number`, `duplicate`, `dnc`, `frequency_cap`, `dnd_scrub`, `blocked_by_gate`.",
            "propertyNames": {
              "type": "string"
            },
            "type": "object",
            "x-known-values": [
              "invalid_number",
              "duplicate",
              "dnc",
              "frequency_cap",
              "dnd_scrub",
              "blocked_by_gate"
            ]
          },
          "status": {
            "additionalProperties": {
              "maximum": 9007199254740991,
              "minimum": -9007199254740991,
              "type": "integer"
            },
            "description": "Recipients by status. Open set — handle an unrecognised value rather than throwing. Today: `pending`, `dialing`, `done`, `excluded`, `failed`.",
            "examples": [
              "running"
            ],
            "propertyNames": {
              "type": "string"
            },
            "type": "object",
            "x-known-values": [
              "pending",
              "dialing",
              "done",
              "excluded",
              "failed"
            ]
          }
        },
        "required": [
          "status",
          "disposition",
          "excludedReason",
          "agentOutcome"
        ],
        "type": "object"
      },
      "CampaignRecipientResponse": {
        "properties": {
          "attemptCount": {
            "description": "How many times this recipient has been dialled, retries included.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "costPaise": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the last call billed. 0 for an unanswered call; null for no call at all."
          },
          "createdAt": {
            "description": "When this recipient was added to the campaign. RFC 3339, UTC.",
            "type": "string"
          },
          "disposition": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The last call’s outcome. Open set — handle an unrecognised value rather than throwing. Today: `answered`, `no_answer`, `busy`, `failed`, `voicemail`, `unknown`.",
            "x-known-values": [
              "answered",
              "no_answer",
              "busy",
              "failed",
              "voicemail",
              "unknown"
            ]
          },
          "e164": {
            "description": "The recipient number, in E.164.",
            "examples": [
              "+919876543210"
            ],
            "type": "string"
          },
          "excludedReason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this one will not be called. Null unless excluded. Open set — handle an unrecognised value rather than throwing. Today: `invalid_number`, `duplicate`, `dnc`, `frequency_cap`, `dnd_scrub`, `blocked_by_gate`.",
            "x-known-values": [
              "invalid_number",
              "duplicate",
              "dnc",
              "frequency_cap",
              "dnd_scrub",
              "blocked_by_gate"
            ]
          },
          "id": {
            "description": "The campaign recipient's unique id.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "lastCallId": {
            "anyOf": [
              {
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Joins to `GET /v1/calls/{id}` for the full CDR, transcript and recording."
          },
          "nextAttemptAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the retry ladder will try again. RFC 3339, UTC. Null when no retry is scheduled."
          },
          "outcome": {
            "anyOf": [
              {
                "additionalProperties": {},
                "propertyNames": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "The agent’s structured extraction, copied from the call’s `outputs`."
          },
          "status": {
            "description": "Where this recipient stands. `dialing` is a runner lease, not a resting state. Open set — handle an unrecognised value rather than throwing. Today: `pending`, `dialing`, `done`, `excluded`, `failed`.",
            "examples": [
              "running"
            ],
            "type": "string",
            "x-known-values": [
              "pending",
              "dialing",
              "done",
              "excluded",
              "failed"
            ]
          },
          "talkSeconds": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The last call’s talking time. Null when nothing has been dialled."
          },
          "variables": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string"
                },
                "propertyNames": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "The per-recipient values substituted into the agent’s prompt."
          }
        },
        "required": [
          "id",
          "e164",
          "status",
          "excludedReason",
          "attemptCount",
          "nextAttemptAt",
          "lastCallId",
          "disposition",
          "outcome",
          "variables",
          "talkSeconds",
          "costPaise",
          "createdAt"
        ],
        "type": "object"
      },
      "CampaignResponse": {
        "properties": {
          "agent": {
            "description": "The agent as it was at launch. `id` goes null if the agent is later deleted; `name` keeps saying what ran.",
            "properties": {
              "id": {
                "anyOf": [
                  {
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "The agent's id, or null if it has since been deleted.",
                "examples": [
                  "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                ]
              },
              "name": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "The agent's name at launch. Kept even after the agent is deleted, so the record still says what ran.",
                "examples": [
                  "Order confirmation"
                ]
              }
            },
            "required": [
              "id",
              "name"
            ],
            "type": "object"
          },
          "archivedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When it was filed out of the list. Archived campaigns are hidden from `GET /v1/campaigns` unless `archived=true`; the detail route always serves them.",
            "examples": [
              null
            ]
          },
          "autoPauseBelowPaise": {
            "description": "Pause below this wallet balance. 0 means the floor is off.",
            "examples": [
              50000
            ],
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "completedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the last recipient settled. RFC 3339, UTC. Null until the campaign finishes.",
            "examples": [
              null
            ]
          },
          "createdAt": {
            "description": "RFC 3339, UTC.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          },
          "environment": {
            "description": "`live` or `test` — inherited from the credential that created it.",
            "examples": [
              "live"
            ],
            "type": "string"
          },
          "id": {
            "description": "The campaign's unique id.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "launchedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the campaign was launched. RFC 3339, UTC. Null while it is still a draft.",
            "examples": [
              "2026-09-01T04:00:00Z"
            ]
          },
          "name": {
            "description": "Your label for the campaign.",
            "examples": [
              "COD confirmations — September"
            ],
            "type": "string"
          },
          "number": {
            "description": "The from-number as it was at launch. Same snapshot rule as `agent`.",
            "properties": {
              "e164": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "The number dialled from, in E.164. Kept after release, so the record still says which line called.",
                "examples": [
                  "+918045678901"
                ]
              },
              "id": {
                "anyOf": [
                  {
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "The number's id, or null if it has since been released.",
                "examples": [
                  "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                ]
              }
            },
            "required": [
              "id",
              "e164"
            ],
            "type": "object"
          },
          "pacing": {
            "description": "How fast this campaign dials.",
            "properties": {
              "callsPerMinute": {
                "description": "How fast the campaign dials, in calls per minute.",
                "examples": [
                  10
                ],
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "maxConcurrent": {
                "description": "Above your concurrency quota this does not queue — the overflow settles as failed. See `GET /v1/limits`.",
                "examples": [
                  4
                ],
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              }
            },
            "required": [
              "callsPerMinute",
              "maxConcurrent"
            ],
            "type": "object"
          },
          "pausedReason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why it stopped dialling. Null while healthy. Open set — handle an unrecognised value rather than throwing. Today: `operator`, `low_balance`, `target_unavailable`, `carrier_errors`.",
            "x-known-values": [
              "operator",
              "low_balance",
              "target_unavailable",
              "carrier_errors"
            ]
          },
          "preflight": {
            "anyOf": [
              {
                "properties": {
                  "callable": {
                    "description": "What is left to dial.",
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  "checks": {
                    "description": "One entry per pre-dial check, in the order the gate runs them.",
                    "items": {
                      "properties": {
                        "outcome": {
                          "description": "`block` stops the launch; `warn` is recorded and lets it proceed; `pass` is clean. Only the suppression list and the calling window can block.",
                          "enum": [
                            "pass",
                            "warn",
                            "block"
                          ],
                          "examples": [
                            "pass"
                          ],
                          "type": "string"
                        },
                        "reason": {
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Why this recipient was excluded, when the reason needs more than its code.",
                          "examples": [
                            "Outside the 09:00-21:00 IST window for promotional calls."
                          ]
                        },
                        "type": {
                          "description": "Which pre-dial check this row reports — the calling window, the suppression list, consent, wallet funding, and so on.",
                          "examples": [
                            "time_window"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "type",
                        "outcome",
                        "reason"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "computedAt": {
                    "description": "When this funnel was computed, RFC 3339 UTC. Launch recomputes rather than trusting a stale one.",
                    "examples": [
                      "2026-09-01T03:58:12Z"
                    ],
                    "type": "string"
                  },
                  "estimatedCostPaise": {
                    "description": "The cost range for dialling everyone callable. An estimate, not a quote: what a campaign actually costs depends on how long people talk.",
                    "properties": {
                      "high": {
                        "description": "Dearest plausible total, in paise — every callable recipient running to the cap, retries included.",
                        "examples": [
                          480000
                        ],
                        "maximum": 9007199254740991,
                        "minimum": -9007199254740991,
                        "type": "integer"
                      },
                      "low": {
                        "description": "Cheapest plausible total, in paise — every callable recipient answering for the minimum billable duration.",
                        "examples": [
                          120000
                        ],
                        "maximum": 9007199254740991,
                        "minimum": -9007199254740991,
                        "type": "integer"
                      }
                    },
                    "required": [
                      "low",
                      "high"
                    ],
                    "type": "object"
                  },
                  "excluded": {
                    "additionalProperties": {
                      "type": "number"
                    },
                    "description": "Exclusion counts, keyed by reason. Open set — handle an unrecognised value rather than throwing. Today: `invalid_number`, `duplicate`, `dnc`, `frequency_cap`, `dnd_scrub`, `blocked_by_gate`.",
                    "propertyNames": {
                      "type": "string"
                    },
                    "type": "object",
                    "x-known-values": [
                      "invalid_number",
                      "duplicate",
                      "dnc",
                      "frequency_cap",
                      "dnd_scrub",
                      "blocked_by_gate"
                    ]
                  },
                  "excludedE164s": {
                    "additionalProperties": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "description": "The excluded numbers themselves, grouped by reason. Present ONLY on the response to `POST /v1/campaigns/{id}/preflight` — a fresh run holds them in memory. A later `GET` serves the counts without them; they are never stored.",
                    "propertyNames": {
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "total": {
                    "description": "Rows uploaded, before any exclusion.",
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  "walletBalancePaise": {
                    "description": "Your wallet balance when the funnel was computed, in paise. Compare against `estimatedCostPaise.high` to see whether the campaign can finish without a top-up.",
                    "examples": [
                      500000
                    ],
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  }
                },
                "required": [
                  "computedAt",
                  "total",
                  "excluded",
                  "callable",
                  "checks",
                  "estimatedCostPaise",
                  "walletBalancePaise"
                ],
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "The cached pre-flight funnel, or null if it has not been computed yet. Launch recomputes rather than trusting it."
          },
          "progress": {
            "description": "Counters cached on the campaign row, written alongside the recipient rows they summarise. If they ever disagree with the recipients, the recipients are right.",
            "properties": {
              "connected": {
                "description": "Recipients who answered. Never exceeds `dialed`.",
                "examples": [
                  244
                ],
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "dialed": {
                "description": "Recipients dialled at least once. Retries do not double-count.",
                "examples": [
                  320
                ],
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "excluded": {
                "description": "Recipients the pre-dial gate removed — suppression list, missing consent, outside the calling window. Never dialled, never billed.",
                "examples": [
                  31
                ],
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "spentPaise": {
                "description": "What this campaign has cost so far, in paise.",
                "examples": [
                  146400
                ],
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "total": {
                "description": "Recipients uploaded, before exclusions.",
                "examples": [
                  500
                ],
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              }
            },
            "required": [
              "total",
              "dialed",
              "connected",
              "excluded",
              "spentPaise"
            ],
            "type": "object"
          },
          "purpose": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The sender classification this campaign ran under, snapshotted at launch. It decides which calling window applied, so it is evidence — not a live read of the agent.",
            "examples": [
              "transactional"
            ]
          },
          "retries": {
            "description": "How this campaign retries recipients it did not reach. The retry tail has to fit inside the calling window, or the campaign is refused at launch.",
            "properties": {
              "attempts": {
                "description": "How many times a recipient is redialled before giving up.",
                "examples": [
                  1
                ],
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "backoff": {
                "description": "Retry spacing. Open set — handle an unrecognised value rather than throwing. Today: `linear`, `exponential`.",
                "type": "string",
                "x-known-values": [
                  "linear",
                  "exponential"
                ]
              },
              "intervalMinutes": {
                "description": "Minutes before the first retry.",
                "examples": [
                  60
                ],
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "on": {
                "description": "Which dispositions are retried. Open set — handle an unrecognised value rather than throwing. Today: `answered`, `no_answer`, `busy`, `failed`, `voicemail`, `unknown`.",
                "examples": [
                  [
                    "no_answer",
                    "busy"
                  ]
                ],
                "items": {
                  "type": "string"
                },
                "type": "array",
                "x-known-values": [
                  "answered",
                  "no_answer",
                  "busy",
                  "failed",
                  "voicemail",
                  "unknown"
                ]
              }
            },
            "required": [
              "attempts",
              "intervalMinutes",
              "backoff",
              "on"
            ],
            "type": "object"
          },
          "schedule": {
            "description": "When this campaign is allowed to dial. Narrower than the legal window, never wider — the compliance gate still runs on every call.",
            "properties": {
              "endsAt": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Stop dialling at this instant even if recipients remain. RFC 3339, UTC.",
                "examples": [
                  "2026-09-07T14:00:00Z"
                ]
              },
              "startsAt": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Do not dial before this instant. RFC 3339, UTC.",
                "examples": [
                  "2026-09-01T04:00:00Z"
                ]
              },
              "weekdays": {
                "description": "7-bit mask, Monday = bit 0.",
                "examples": [
                  31
                ],
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "windowEndMinute": {
                "description": "Minutes from midnight IST.",
                "examples": [
                  1260
                ],
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "windowStartMinute": {
                "description": "Minutes from midnight IST. Dialling never happens outside the window.",
                "examples": [
                  540
                ],
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              }
            },
            "required": [
              "startsAt",
              "endsAt",
              "windowStartMinute",
              "windowEndMinute",
              "weekdays"
            ],
            "type": "object"
          },
          "status": {
            "description": "Lifecycle position. `paused` is resumable; `stopped` is terminal and abandons the remaining recipients. Open set — handle an unrecognised value rather than throwing. Today: `draft`, `scheduled`, `running`, `paused`, `completed`, `stopped`, `failed`.",
            "examples": [
              "running"
            ],
            "type": "string",
            "x-known-values": [
              "draft",
              "scheduled",
              "running",
              "paused",
              "completed",
              "stopped",
              "failed"
            ]
          },
          "updatedAt": {
            "description": "When the campaign was last changed. RFC 3339, UTC.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "environment",
          "createdAt",
          "updatedAt",
          "agent",
          "number",
          "purpose",
          "schedule",
          "pacing",
          "retries",
          "autoPauseBelowPaise",
          "progress",
          "preflight",
          "launchedAt",
          "completedAt",
          "pausedReason",
          "archivedAt"
        ],
        "type": "object"
      },
      "ChainVerificationResponse": {
        "properties": {
          "brokenReason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How the break manifests. Open set — handle an unrecognised value rather than throwing. Today: `content_hash_mismatch`, `record_hash_mismatch`, `link_broken`, `sequence_gap`.",
            "examples": [
              null
            ],
            "x-known-values": [
              "content_hash_mismatch",
              "record_hash_mismatch",
              "link_broken",
              "sequence_gap"
            ]
          },
          "checked": {
            "description": "How many records were verified in this call.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "complete": {
            "description": "True when the walk reached the requested end (or the chain head). False means more chain remains — continue with `from_seq = throughSeq + 1`.",
            "type": "boolean"
          },
          "firstBrokenSeq": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The first position whose seal or link failed to verify. Null when the slice is intact.",
            "examples": [
              null
            ]
          },
          "fromSeq": {
            "description": "First position verified, inclusive.",
            "examples": [
              "1"
            ],
            "type": "string"
          },
          "throughSeq": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Last position verified, inclusive. Null when the slice held no records.",
            "examples": [
              "5000"
            ]
          },
          "valid": {
            "description": "Every record in the verified slice re-hashed to its stored seal and linked to its predecessor.",
            "type": "boolean"
          },
          "verifiedAt": {
            "description": "When this verification ran, RFC 3339 UTC.",
            "examples": [
              "2026-08-31T09:14:22Z"
            ],
            "type": "string"
          }
        },
        "required": [
          "valid",
          "checked",
          "fromSeq",
          "throughSeq",
          "complete",
          "firstBrokenSeq",
          "brokenReason",
          "verifiedAt"
        ],
        "type": "object"
      },
      "CheckComplianceBatchDto": {
        "properties": {
          "e164s": {
            "description": "The numbers to pre-flight, 1-100. Each one runs the full gate and is metered as its own verdict. A campaign-sized list belongs in a campaign, which has a pre-flight built for that scale.",
            "examples": [
              [
                "+919876543210",
                "+919812345678"
              ]
            ],
            "items": {
              "pattern": "^\\+91\\d{10,11}$",
              "type": "string"
            },
            "maxItems": 100,
            "minItems": 1,
            "type": "array"
          },
          "purpose": {
            "description": "The sender classification this call falls under, which decides the legal calling window and whether consent is required. Omit to use your organisation's declared `defaultCallPurpose`. It may only ever narrow — you cannot declare a stricter default and then send a looser purpose per request. Applies to every number in the batch. Open set — handle an unrecognised value rather than throwing. Today: `promotional`, `service`, `transactional`, `collections`.",
            "enum": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ],
            "examples": [
              "promotional"
            ],
            "type": "string",
            "x-known-values": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ]
          }
        },
        "required": [
          "e164s"
        ],
        "type": "object"
      },
      "CheckComplianceDto": {
        "properties": {
          "e164": {
            "description": "The number you intend to dial, in E.164.",
            "examples": [
              "+919876543210"
            ],
            "pattern": "^\\+91\\d{10,11}$",
            "type": "string"
          },
          "purpose": {
            "description": "The sender classification this call falls under, which decides the legal calling window and whether consent is required. Omit to use your organisation's declared `defaultCallPurpose`. It may only ever narrow — you cannot declare a stricter default and then send a looser purpose per request. Open set — handle an unrecognised value rather than throwing. Today: `promotional`, `service`, `transactional`, `collections`.",
            "enum": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ],
            "examples": [
              "promotional"
            ],
            "type": "string",
            "x-known-values": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ]
          }
        },
        "required": [
          "e164"
        ],
        "type": "object"
      },
      "ClearRecipientsResultResponse": {
        "properties": {
          "removed": {
            "description": "How many recipients were removed.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          }
        },
        "required": [
          "removed"
        ],
        "type": "object"
      },
      "ComplianceCheckResponse": {
        "properties": {
          "callId": {
            "anyOf": [
              {
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null for a standalone check.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ]
          },
          "checkType": {
            "description": "Which rule ran. Open set — handle an unrecognised value rather than throwing. Today: `dnc`, `carrier_dnd`, `consent`, `dlt`, `a2p`, `time_window`, `enforcement_change`, `profile_change`, `call_outcome`, `suppression_change`.",
            "type": "string",
            "x-known-values": [
              "dnc",
              "carrier_dnd",
              "consent",
              "dlt",
              "a2p",
              "time_window",
              "enforcement_change",
              "profile_change",
              "call_outcome",
              "suppression_change"
            ]
          },
          "createdAt": {
            "description": "When this check ran, RFC 3339 UTC. A check row is a snapshot: it says what was true at dial time even if the underlying consent or suppression entry changes later.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          },
          "detail": {
            "additionalProperties": {},
            "description": "Rule-specific evidence, as recorded at the time.",
            "propertyNames": {
              "type": "string"
            },
            "type": "object"
          },
          "e164": {
            "description": "The number this check was about, in E.164.",
            "examples": [
              "+919876543210"
            ],
            "type": "string"
          },
          "enforced": {
            "description": "Whether enforcement was ON when this ran. A recorded block with `false` did not stop anything.",
            "type": "boolean"
          },
          "id": {
            "description": "The audit row’s id — cite it when reporting an outcome.",
            "examples": [
              "8814"
            ],
            "type": "string"
          },
          "outcome": {
            "description": "Only `block` refuses a call. A `warn` is advisory and is recorded, not enforced — carrier DND data is warn-only by design. An `error` means the check itself failed to run: recorded so a broken check is a visible fact, and treated as a block when the check is mandatory. Open set — handle an unrecognised value rather than throwing. Today: `pass`, `warn`, `block`, `error`.",
            "type": "string",
            "x-known-values": [
              "pass",
              "warn",
              "block",
              "error"
            ]
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the check came out this way, when the outcome alone does not say it.",
            "examples": [
              "Asked to be removed during a call on 2026-08-20."
            ]
          },
          "source": {
            "description": "Where the answer came from. Open set — handle an unrecognised value rather than throwing. Today: `internal`, `carrier`, `operator`.",
            "type": "string",
            "x-known-values": [
              "internal",
              "carrier",
              "operator"
            ]
          }
        },
        "required": [
          "id",
          "callId",
          "checkType",
          "outcome",
          "source",
          "e164",
          "reason",
          "enforced",
          "detail",
          "createdAt"
        ],
        "type": "object"
      },
      "ComplianceVerdictResponse": {
        "properties": {
          "allowed": {
            "description": "The answer. A refusal is still `200` — branch on this, not on the status.",
            "type": "boolean"
          },
          "blockedBy": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which check refused. Null when allowed.",
            "examples": [
              null
            ]
          },
          "checks": {
            "description": "Every audit row written while deciding — the evidence, not a summary of it.",
            "items": {
              "properties": {
                "callId": {
                  "anyOf": [
                    {
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Null for a standalone check.",
                  "examples": [
                    "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                  ]
                },
                "checkType": {
                  "description": "Which rule ran. Open set — handle an unrecognised value rather than throwing. Today: `dnc`, `carrier_dnd`, `consent`, `dlt`, `a2p`, `time_window`, `enforcement_change`, `profile_change`, `call_outcome`, `suppression_change`.",
                  "type": "string",
                  "x-known-values": [
                    "dnc",
                    "carrier_dnd",
                    "consent",
                    "dlt",
                    "a2p",
                    "time_window",
                    "enforcement_change",
                    "profile_change",
                    "call_outcome",
                    "suppression_change"
                  ]
                },
                "createdAt": {
                  "description": "When this check ran, RFC 3339 UTC. A check row is a snapshot: it says what was true at dial time even if the underlying consent or suppression entry changes later.",
                  "examples": [
                    "2026-08-25T09:14:22Z"
                  ],
                  "type": "string"
                },
                "detail": {
                  "additionalProperties": {},
                  "description": "Rule-specific evidence, as recorded at the time.",
                  "propertyNames": {
                    "type": "string"
                  },
                  "type": "object"
                },
                "e164": {
                  "description": "The number this check was about, in E.164.",
                  "examples": [
                    "+919876543210"
                  ],
                  "type": "string"
                },
                "enforced": {
                  "description": "Whether enforcement was ON when this ran. A recorded block with `false` did not stop anything.",
                  "type": "boolean"
                },
                "id": {
                  "description": "The audit row’s id — cite it when reporting an outcome.",
                  "examples": [
                    "8814"
                  ],
                  "type": "string"
                },
                "outcome": {
                  "description": "Only `block` refuses a call. A `warn` is advisory and is recorded, not enforced — carrier DND data is warn-only by design. An `error` means the check itself failed to run: recorded so a broken check is a visible fact, and treated as a block when the check is mandatory. Open set — handle an unrecognised value rather than throwing. Today: `pass`, `warn`, `block`, `error`.",
                  "type": "string",
                  "x-known-values": [
                    "pass",
                    "warn",
                    "block",
                    "error"
                  ]
                },
                "reason": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Why the check came out this way, when the outcome alone does not say it.",
                  "examples": [
                    "Asked to be removed during a call on 2026-08-20."
                  ]
                },
                "source": {
                  "description": "Where the answer came from. Open set — handle an unrecognised value rather than throwing. Today: `internal`, `carrier`, `operator`.",
                  "type": "string",
                  "x-known-values": [
                    "internal",
                    "carrier",
                    "operator"
                  ]
                }
              },
              "required": [
                "id",
                "callId",
                "checkType",
                "outcome",
                "source",
                "e164",
                "reason",
                "enforced",
                "detail",
                "createdAt"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "e164": {
            "description": "The number the verdict is about, in E.164.",
            "examples": [
              "+919876543210"
            ],
            "type": "string"
          },
          "purpose": {
            "description": "The classification the gate evaluated — declared on the request, or your organization’s default. Recorded so the verdict is self-describing months later. Open set — handle an unrecognised value rather than throwing. Today: `promotional`, `service`, `transactional`, `collections`.",
            "type": "string",
            "x-known-values": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ]
          }
        },
        "required": [
          "e164",
          "purpose",
          "allowed",
          "blockedBy",
          "checks"
        ],
        "type": "object"
      },
      "ConsentBulkDto": {
        "properties": {
          "records": {
            "description": "The consents to import, 1-1000. Rows are accepted individually — the response lists exactly which were rejected and why, so you can fix and resubmit only those.",
            "items": {
              "additionalProperties": false,
              "properties": {
                "capturedAt": {
                  "description": "🔴 When the RECIPIENT consented — not when you called this endpoint. Defaults to now, which is correct only for a live capture: importing a back catalogue without this dates every record to the day of the import and makes the 7-day transactional clock meaningless.",
                  "examples": [
                    "2026-08-20T11:02:00Z"
                  ],
                  "type": "string"
                },
                "e164": {
                  "description": "The number that consented, in E.164.",
                  "examples": [
                    "+919876543210"
                  ],
                  "pattern": "^\\+91\\d{10,11}$",
                  "type": "string"
                },
                "evidenceRef": {
                  "description": "Where the proof lives — a form submission id, a recording URL, a DCA reference. Tone stores the pointer, never the artefact.",
                  "examples": [
                    "form-sub-88213"
                  ],
                  "maxLength": 500,
                  "type": "string"
                },
                "expiresAt": {
                  "description": "When the consent lapses. Optional for `explicit` consent, where policy fills it — capped at seven days for a transactional purpose, otherwise until revoked. REQUIRED for `inferred` consent, which lasts exactly as long as the relationship, and only you know when that ends; omitting it there is a 422.",
                  "examples": [
                    "2026-08-27T11:02:00Z"
                  ],
                  "type": "string"
                },
                "kind": {
                  "description": "How the consent arose. `explicit` is a positive act by the recipient; `inferred` rests on an existing relationship and MUST carry its own `expiresAt`. Open set — handle an unrecognised value rather than throwing. Today: `explicit`, `inferred`.",
                  "enum": [
                    "explicit",
                    "inferred"
                  ],
                  "examples": [
                    "explicit"
                  ],
                  "type": "string",
                  "x-known-values": [
                    "explicit",
                    "inferred"
                  ]
                },
                "purpose": {
                  "description": "What they consented to be contacted about. Consent is purpose-scoped: a record for one purpose does not satisfy the gate for another. Open set — handle an unrecognised value rather than throwing. Today: `promotional`, `service`, `transactional`, `collections`.",
                  "enum": [
                    "promotional",
                    "service",
                    "transactional",
                    "collections"
                  ],
                  "examples": [
                    "promotional"
                  ],
                  "type": "string",
                  "x-known-values": [
                    "promotional",
                    "service",
                    "transactional",
                    "collections"
                  ]
                },
                "scope": {
                  "description": "What the recipient actually agreed to, in their words or yours.",
                  "examples": [
                    "Order updates and delivery reminders for orders placed on acme.example."
                  ],
                  "maxLength": 1000,
                  "type": "string"
                },
                "source": {
                  "description": "Which channel captured it. Recorded verbatim and returned in the evidence pack. Open set — handle an unrecognised value rather than throwing. Today: `api`, `web_form`, `ivr`, `dtmf`, `otp`, `dca`, `import`.",
                  "enum": [
                    "api",
                    "web_form",
                    "ivr",
                    "dtmf",
                    "otp",
                    "dca",
                    "import"
                  ],
                  "examples": [
                    "web_form"
                  ],
                  "type": "string",
                  "x-known-values": [
                    "api",
                    "web_form",
                    "ivr",
                    "dtmf",
                    "otp",
                    "dca",
                    "import"
                  ]
                }
              },
              "required": [
                "e164",
                "purpose",
                "kind",
                "source"
              ],
              "type": "object"
            },
            "maxItems": 1000,
            "minItems": 1,
            "type": "array"
          }
        },
        "required": [
          "records"
        ],
        "type": "object"
      },
      "ConsentBulkResultResponse": {
        "properties": {
          "imported": {
            "description": "How many records were written. All accepted rows land in one transaction.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "rejected": {
            "description": "The refused rows. Fix these and resubmit only them — the accepted rows are already saved.",
            "items": {
              "properties": {
                "code": {
                  "description": "Machine-readable refusal code — `conflict` for a number inside its opt-out lockout, `unprocessable` for a policy violation.",
                  "examples": [
                    "conflict"
                  ],
                  "type": "string"
                },
                "e164": {
                  "description": "The number on the refused record.",
                  "examples": [
                    "+919876543210"
                  ],
                  "type": "string"
                },
                "index": {
                  "description": "Position of the refused record in your `records` array, zero-based.",
                  "maximum": 9007199254740991,
                  "minimum": -9007199254740991,
                  "type": "integer"
                },
                "message": {
                  "description": "Why the record was refused, in words.",
                  "examples": [
                    "This number opted out and is inside the 90-day re-consent lockout."
                  ],
                  "type": "string"
                }
              },
              "required": [
                "index",
                "e164",
                "code",
                "message"
              ],
              "type": "object"
            },
            "type": "array"
          }
        },
        "required": [
          "imported",
          "rejected"
        ],
        "type": "object"
      },
      "ConsentRecordResponse": {
        "properties": {
          "active": {
            "description": "Whether this record satisfies the gate right now.",
            "type": "boolean"
          },
          "capturedAt": {
            "description": "When the RECIPIENT consented, not when you told us.",
            "examples": [
              "2026-08-20T11:02:00Z"
            ],
            "type": "string"
          },
          "createdAt": {
            "description": "When this consent was recorded with Tone, RFC 3339 UTC. Distinct from `capturedAt`, which is when the recipient actually consented.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          },
          "e164": {
            "description": "The number that consented, in E.164.",
            "examples": [
              "+919876543210"
            ],
            "type": "string"
          },
          "evidenceRef": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where the proof lives — form id, recording URL, DCA reference.",
            "examples": [
              "form-sub-88213"
            ]
          },
          "expiresAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the consent lapses. RFC 3339, UTC. Null means it stands until revoked.",
            "examples": [
              "2026-11-23T09:14:22Z"
            ]
          },
          "id": {
            "description": "The consent record’s id. Pass it to `POST /v1/consent/{id}/revoke` to revoke this one record.",
            "examples": [
              "8814"
            ],
            "type": "string"
          },
          "kind": {
            "description": "Open set — handle an unrecognised value rather than throwing. Today: `explicit`, `inferred`.",
            "type": "string",
            "x-known-values": [
              "explicit",
              "inferred"
            ]
          },
          "purpose": {
            "description": "What they consented TO. Open set — handle an unrecognised value rather than throwing. Today: `promotional`, `service`, `transactional`, `collections`.",
            "type": "string",
            "x-known-values": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ]
          },
          "revokedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The ledger is append-only; revocation is a stamp, not a delete.",
            "examples": [
              null
            ]
          },
          "revokedReason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the consent was revoked, when a reason was given.",
            "examples": [
              null
            ]
          },
          "scope": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the recipient agreed to, as it was recorded.",
            "examples": [
              "Order updates and delivery reminders."
            ]
          },
          "source": {
            "description": "Weakest to strongest as evidence. Open set — handle an unrecognised value rather than throwing. Today: `api`, `web_form`, `ivr`, `dtmf`, `otp`, `dca`, `import`.",
            "type": "string",
            "x-known-values": [
              "api",
              "web_form",
              "ivr",
              "dtmf",
              "otp",
              "dca",
              "import"
            ]
          }
        },
        "required": [
          "id",
          "e164",
          "purpose",
          "kind",
          "source",
          "evidenceRef",
          "scope",
          "capturedAt",
          "expiresAt",
          "revokedAt",
          "revokedReason",
          "active",
          "createdAt"
        ],
        "type": "object"
      },
      "CreateAgentDto": {
        "properties": {
          "callSettings": {
            "additionalProperties": false,
            "description": "How the call RUNS rather than what it says: opening line, background ambience, what to do when the caller goes quiet, voicemail handling, the maximum call length and the farewell. A COMPLETE object; omitting the key leaves stored settings untouched. Custom lines are translated into the agent spoken languages automatically on save.",
            "properties": {
              "background": {
                "additionalProperties": false,
                "default": {},
                "description": "Ambient background audio for the call.",
                "examples": [
                  {
                    "sound": "none",
                    "volume": 0.3
                  }
                ],
                "properties": {
                  "sound": {
                    "default": "none",
                    "description": "An ambience bed played under the whole call, which makes a bot sound less like it is in a vacuum. Tone's own loops, not the voice vendor's. Open set — handle an unrecognised value rather than throwing. Today: `none`, `office`, `call_center`, `city_traffic`.",
                    "enum": [
                      "none",
                      "office",
                      "call_center",
                      "city_traffic"
                    ],
                    "examples": [
                      "none"
                    ],
                    "type": "string",
                    "x-known-values": [
                      "none",
                      "office",
                      "call_center",
                      "city_traffic"
                    ]
                  },
                  "volume": {
                    "default": 0.3,
                    "description": "How loud the bed sits under the speech, 0 to 1. Past about 0.4 it starts competing with the agent on a phone earpiece.",
                    "examples": [
                      0.3
                    ],
                    "maximum": 1,
                    "minimum": 0,
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "hangupLine": {
                "additionalProperties": false,
                "default": {},
                "description": "What the agent says as it ends the call on its own — after the nudge ladder runs out, or when it decides the task is done.",
                "examples": [
                  {
                    "text": "Thanks for your time. Goodbye."
                  }
                ],
                "properties": {
                  "i18n": {
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Read-only. Tone's translations of `text` into the agent's other languages, keyed by language code. Accepted and IGNORED on write so you can PATCH an object straight back from a GET; translations are always recomputed server-side, so a client can never inject one.",
                    "examples": [
                      {
                        "hi-IN": "नमस्ते, मैं Acme से बात कर रहा हूँ।"
                      }
                    ],
                    "propertyNames": {
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "text": {
                    "anyOf": [
                      {
                        "maxLength": 300,
                        "pattern": "^[^\\p{C}]+$",
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The line, in the agent's first language — Tone translates it into the others. Send `null` or an empty string to restore Tone's built-in line for this slot: that is the only way to spell \"go back to the default\", and it is why clearing the field does not make the agent say nothing."
                  }
                },
                "type": "object"
              },
              "maxCallSeconds": {
                "anyOf": [
                  {
                    "maximum": 7200,
                    "minimum": 60,
                    "type": "integer"
                  },
                  {
                    "type": "null"
                  }
                ],
                "default": null,
                "description": "A hard ceiling on call length, in seconds, after which Tone hangs up. `null` means no agent-level cap. This can only ever LOWER the platform ceiling, never raise it. Worth setting on any agent that bills per minute.",
                "examples": [
                  600
                ]
              },
              "nudges": {
                "additionalProperties": false,
                "default": {},
                "description": "What the agent does when the caller goes quiet.",
                "examples": [
                  {
                    "enabled": true,
                    "hangupAfter": true,
                    "steps": [
                      {
                        "afterSeconds": 15,
                        "line": {
                          "text": null
                        }
                      }
                    ]
                  }
                ],
                "properties": {
                  "enabled": {
                    "default": true,
                    "description": "Whether the agent prompts a silent caller at all. Turning this off leaves the call in silence until the caller speaks or the cap is reached.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "hangupAfter": {
                    "default": true,
                    "description": "Whether to end the call once the last rung goes unanswered. Requires `enabled` — hanging up after nothing would mean never, which is not what the name promises, so the pairing is enforced.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "steps": {
                    "description": "The ladder, in order, up to 5 rungs. Each rung's wait is measured from the previous one. At least one rung is required while `enabled` is true, because nudges on with no rungs is a switch that says the feature is on and never fires.",
                    "examples": [
                      [
                        {
                          "afterSeconds": 15,
                          "line": {
                            "text": null
                          }
                        }
                      ]
                    ],
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "afterSeconds": {
                          "description": "🔴 Seconds of CONTINUED silence since the previous rung — a gap, not an offset from the start of the call. Two rungs of 15 fire at 15s and 30s of quiet. Minimum 3s, so a ladder cannot machine-gun the caller.",
                          "examples": [
                            15
                          ],
                          "maximum": 300,
                          "minimum": 3,
                          "type": "integer"
                        },
                        "line": {
                          "additionalProperties": false,
                          "default": {},
                          "description": "What the agent says on this rung. Leave `text` null to use Tone's built-in localized nudge.",
                          "examples": [
                            {
                              "text": "Are you still there?"
                            }
                          ],
                          "properties": {
                            "i18n": {
                              "additionalProperties": {
                                "type": "string"
                              },
                              "description": "Read-only. Tone's translations of `text` into the agent's other languages, keyed by language code. Accepted and IGNORED on write so you can PATCH an object straight back from a GET; translations are always recomputed server-side, so a client can never inject one.",
                              "examples": [
                                {
                                  "hi-IN": "नमस्ते, मैं Acme से बात कर रहा हूँ।"
                                }
                              ],
                              "propertyNames": {
                                "type": "string"
                              },
                              "type": "object"
                            },
                            "text": {
                              "anyOf": [
                                {
                                  "maxLength": 300,
                                  "pattern": "^[^\\p{C}]+$",
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "The line, in the agent's first language — Tone translates it into the others. Send `null` or an empty string to restore Tone's built-in line for this slot: that is the only way to spell \"go back to the default\", and it is why clearing the field does not make the agent say nothing."
                            }
                          },
                          "type": "object"
                        }
                      },
                      "required": [
                        "afterSeconds"
                      ],
                      "type": "object"
                    },
                    "maxItems": 5,
                    "type": "array"
                  }
                },
                "type": "object"
              },
              "openingLine": {
                "additionalProperties": false,
                "default": {},
                "description": "What the agent says first, after Tone's fixed AI-and-recording disclosure. Unlike the other lines here it is substituted with the call's variables, so `{{customer_name}}` works. Leave `text` null and an outbound agent falls back to \"How can I help you today?\", which is the wrong opening for a call the customer did not place — set it.",
                "examples": [
                  {
                    "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                  }
                ],
                "properties": {
                  "i18n": {
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Read-only. Tone's translations of `text` into the agent's other languages, keyed by language code. Accepted and IGNORED on write so you can PATCH an object straight back from a GET; translations are always recomputed server-side, so a client can never inject one.",
                    "examples": [
                      {
                        "hi-IN": "नमस्ते, मैं Acme से बात कर रहा हूँ।"
                      }
                    ],
                    "propertyNames": {
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "text": {
                    "anyOf": [
                      {
                        "maxLength": 300,
                        "pattern": "^[^\\p{C}]+$",
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The line, in the agent's first language — Tone translates it into the others. Send `null` or an empty string to restore Tone's built-in line for this slot: that is the only way to spell \"go back to the default\", and it is why clearing the field does not make the agent say nothing."
                  }
                },
                "type": "object"
              },
              "voicemail": {
                "additionalProperties": false,
                "default": {},
                "description": "What happens when an answering machine picks up.",
                "examples": [
                  {
                    "enabled": true,
                    "windowSeconds": 30
                  }
                ],
                "properties": {
                  "enabled": {
                    "default": true,
                    "description": "Whether to leave `message` when an answering machine picks up. 🔴 Detection itself runs either way — an undetected mailbox is billed as an answered call and counted as a successful contact, so turning this off means \"hang up without speaking\", never \"do not check\".",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "message": {
                    "additionalProperties": false,
                    "default": {},
                    "description": "What to leave on the machine. Left only when `enabled` is true; the call ends either way.",
                    "examples": [
                      {
                        "text": "Hi, this is Acme calling about your order. We’ll try again later."
                      }
                    ],
                    "properties": {
                      "i18n": {
                        "additionalProperties": {
                          "type": "string"
                        },
                        "description": "Read-only. Tone's translations of `text` into the agent's other languages, keyed by language code. Accepted and IGNORED on write so you can PATCH an object straight back from a GET; translations are always recomputed server-side, so a client can never inject one.",
                        "examples": [
                          {
                            "hi-IN": "नमस्ते, मैं Acme से बात कर रहा हूँ।"
                          }
                        ],
                        "propertyNames": {
                          "type": "string"
                        },
                        "type": "object"
                      },
                      "text": {
                        "anyOf": [
                          {
                            "maxLength": 300,
                            "pattern": "^[^\\p{C}]+$",
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "The line, in the agent's first language — Tone translates it into the others. Send `null` or an empty string to restore Tone's built-in line for this slot: that is the only way to spell \"go back to the default\", and it is why clearing the field does not make the agent say nothing."
                      }
                    },
                    "type": "object"
                  },
                  "windowSeconds": {
                    "default": 30,
                    "description": "How long after the call connects detection stays armed. Past this window a long monologue is a talkative caller, not a machine, so the check stands down.",
                    "examples": [
                      30
                    ],
                    "maximum": 120,
                    "minimum": 5,
                    "type": "integer"
                  }
                },
                "type": "object"
              }
            },
            "type": "object"
          },
          "evaluationCriteria": {
            "description": "Questions a post-call judge answers about each call, returned as `evaluations` with a verdict and a rationale per criterion. A COMPLETE list, replacing what is stored.",
            "items": {
              "additionalProperties": false,
              "properties": {
                "id": {
                  "description": "🔴 The storage key for this criterion's verdicts, and IMMUTABLE once calls have been graded against it. Renaming it orphans every historical verdict — rename `name` instead, which exists for exactly that.",
                  "examples": [
                    "confirmed_order"
                  ],
                  "pattern": "^[a-z][a-z0-9_]{0,39}$",
                  "type": "string"
                },
                "name": {
                  "description": "The human label for this criterion, shown wherever verdicts are reported. Safe to rename at any time.",
                  "examples": [
                    "Confirmed the order"
                  ],
                  "maxLength": 80,
                  "minLength": 1,
                  "type": "string"
                },
                "prompt": {
                  "description": "The question the post-call judge answers about the transcript, handed to it verbatim. Write it so that \"yes\" is unambiguous.",
                  "examples": [
                    "Did the customer explicitly confirm they still want the order?"
                  ],
                  "maxLength": 1000,
                  "minLength": 1,
                  "type": "string"
                }
              },
              "required": [
                "id",
                "name",
                "prompt"
              ],
              "type": "object"
            },
            "maxItems": 10,
            "type": "array"
          },
          "inputVariables": {
            "description": "Placeholders the prompt can reference and a call can fill, each with a default used when a call supplies nothing. A COMPLETE list, replacing what is stored; an empty array clears it.",
            "items": {
              "additionalProperties": false,
              "properties": {
                "default": {
                  "default": "",
                  "description": "What to substitute when a call supplies no value. 🔴 Give every variable a literal fallback such as \"unknown\" — an empty default renders the prompt with a blank where a fact should be, and a model handed a blank invents one.",
                  "examples": [
                    "there"
                  ],
                  "maxLength": 500,
                  "type": "string"
                },
                "description": {
                  "description": "What this variable holds. For your own reference and the dashboard editor — it is not sent to the model.",
                  "examples": [
                    "The customer’s first name, as it appears on the order."
                  ],
                  "maxLength": 200,
                  "type": "string"
                },
                "name": {
                  "description": "The placeholder name, lowercase snake_case. Reference it in the system prompt or a spoken line as `{{name}}`, and supply its value per call.",
                  "examples": [
                    "customer_name"
                  ],
                  "pattern": "^[a-z][a-z0-9_]{0,39}$",
                  "type": "string"
                }
              },
              "required": [
                "name"
              ],
              "type": "object"
            },
            "maxItems": 25,
            "type": "array"
          },
          "knowledgeBaseIds": {
            "description": "Which knowledge bases this agent may answer from — the COMPLETE desired set, not a delta. Omitting the key leaves attachments untouched; sending an empty array detaches every base. A published version pins the SET OF IDS, not their contents, so re-indexing a base changes what past versions answer with.",
            "examples": [
              [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ]
            ],
            "items": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            },
            "maxItems": 50,
            "type": "array"
          },
          "llmModel": {
            "description": "Which language model the agent thinks on. The legal values come from GET /v1/catalog/voice and change without a deploy — treat this as an open set.",
            "examples": [
              "gemini-2.5-flash"
            ],
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "name": {
            "description": "Your name for the agent. Shown in the dashboard and on every call it runs.",
            "examples": [
              "Order confirmation"
            ],
            "maxLength": 48,
            "minLength": 1,
            "pattern": "^[^\\p{C}]+$",
            "type": "string"
          },
          "outputVariables": {
            "description": "Fields to extract from the transcript after each call, returned as `outputs` on the call record. Each field description IS the extraction instruction, so write it as you would tell a person what to look for. A COMPLETE list, replacing what is stored.",
            "items": {
              "additionalProperties": false,
              "properties": {
                "description": {
                  "description": "The extraction instruction, handed verbatim to the model that reads the transcript after the call. Required, because a bare field name extracts garbage — say what counts as an answer and what to do when the call never covered it.",
                  "examples": [
                    "Which day the customer agreed to take delivery. Leave empty if they did not commit to one."
                  ],
                  "maxLength": 500,
                  "minLength": 1,
                  "type": "string"
                },
                "enumValues": {
                  "description": "The allowed answers, 2-20 of them. Required when `type` is `enum` and rejected otherwise — the pairing is enforced, because values on a non-enum type would silently do nothing.",
                  "examples": [
                    [
                      "monday",
                      "tuesday",
                      "wednesday"
                    ]
                  ],
                  "items": {
                    "maxLength": 64,
                    "minLength": 1,
                    "type": "string"
                  },
                  "maxItems": 20,
                  "minItems": 2,
                  "type": "array"
                },
                "name": {
                  "description": "The key this value is stored under on the finished call, lowercase snake_case. Read it back from `outputs` on `GET /v1/calls/{id}`.",
                  "examples": [
                    "delivery_day"
                  ],
                  "pattern": "^[a-z][a-z0-9_]{0,39}$",
                  "type": "string"
                },
                "type": {
                  "description": "What kind of value to extract. `enum` clamps the answer to `enumValues`, which is what makes an outcome countable rather than free text. Open set — handle an unrecognised value rather than throwing. Today: `string`, `number`, `boolean`, `enum`.",
                  "enum": [
                    "string",
                    "number",
                    "boolean",
                    "enum"
                  ],
                  "examples": [
                    "enum"
                  ],
                  "type": "string",
                  "x-known-values": [
                    "string",
                    "number",
                    "boolean",
                    "enum"
                  ]
                }
              },
              "required": [
                "name",
                "type",
                "description"
              ],
              "type": "object"
            },
            "maxItems": 25,
            "type": "array"
          },
          "purpose": {
            "description": "🔴 The regulatory sender classification for every call this agent makes. Not cosmetic: it decides which calling window applies and whether consent is required. `promotional` and `collections` have hard time windows; `service` and `transactional` have none. Defaults to the strictest, `promotional`, and there is deliberately no per-call override. Open set — handle an unrecognised value rather than throwing. Today: `promotional`, `service`, `transactional`, `collections`.",
            "enum": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ],
            "examples": [
              "transactional"
            ],
            "type": "string",
            "x-known-values": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ]
          },
          "systemPrompt": {
            "description": "What the agent is trying to do, in your own words. Reference an input variable with double braces, for example {{{{customer_name}}}}. Keep it task-shaped: the platform already supplies conversational behaviour such as interruption handling and language matching.",
            "examples": [
              "You call customers to confirm a cash-on-delivery order. Confirm the order, ask which day suits them for delivery, then thank them and end the call. Be brief and polite."
            ],
            "maxLength": 20000,
            "minLength": 1,
            "type": "string"
          },
          "tools": {
            "description": "HTTP tools the agent may call mid-conversation, up to 10. Credentials are referenced from your stored secrets, never written inline. A COMPLETE list, replacing what is stored.",
            "items": {
              "additionalProperties": false,
              "properties": {
                "connectionId": {
                  "description": "Read-only provenance. Which integration connection installed this tool — used to answer \"which agents use this connection\" exactly, where matching on `preset` cannot (two connections to the same vendor are indistinguishable). Never reaches the running call.",
                  "examples": [
                    "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d"
                  ],
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "type": "string"
                },
                "description": {
                  "description": "🔴 WHEN the agent should call this tool — the single most important field on it. A vague line is the biggest cause of a tool misfiring, so at least 20 characters are required. Describe the trigger condition, not the implementation.",
                  "examples": [
                    "Call this once the customer has agreed to a specific delivery date and time window."
                  ],
                  "maxLength": 1000,
                  "minLength": 20,
                  "type": "string"
                },
                "http": {
                  "additionalProperties": false,
                  "description": "The request Tone makes when the agent calls this tool.",
                  "properties": {
                    "auth": {
                      "additionalProperties": false,
                      "description": "How Tone authenticates to your endpoint. Every credential is referenced by stored-secret id rather than typed in here, which is what keeps it out of every read of the agent.",
                      "properties": {
                        "header": {
                          "description": "Which header carries an `api_key` credential. Defaults to `x-api-key`. Applies only to `api_key`, and only when the credential goes in a header.",
                          "examples": [
                            "x-api-key"
                          ],
                          "pattern": "^[a-zA-Z0-9-]{1,64}$",
                          "type": "string"
                        },
                        "in": {
                          "description": "Where the credential goes. Defaults to `header`. 🔴 A `body` credential on a GET or DELETE is refused — those send no body, so it would be dropped and the endpoint would answer 401, which reads exactly like a revoked key.",
                          "enum": [
                            "header",
                            "query",
                            "body"
                          ],
                          "examples": [
                            "header"
                          ],
                          "type": "string"
                        },
                        "name": {
                          "description": "The query key or dotted body path the credential lands in. Required when `in` is not `header`.",
                          "examples": [
                            "api_key"
                          ],
                          "maxLength": 120,
                          "pattern": "^[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)*$",
                          "type": "string"
                        },
                        "secondary": {
                          "additionalProperties": false,
                          "description": "A second credential, for APIs that authenticate with a PAIR such as an access key plus a secret key. It carries no `type` because a pair is never two schemes — it is only ever \"put this value in this place\".",
                          "properties": {
                            "in": {
                              "description": "Where the second credential goes. Defaults to `header`, and every placement rule the primary has applies here too.",
                              "enum": [
                                "header",
                                "query",
                                "body"
                              ],
                              "examples": [
                                "header"
                              ],
                              "type": "string"
                            },
                            "name": {
                              "description": "The header name, query key or dotted body path for the second credential. Must not collide with the primary's slot — one would silently overwrite the other.",
                              "examples": [
                                "x-acme-secret"
                              ],
                              "maxLength": 120,
                              "pattern": "^[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)*$",
                              "type": "string"
                            },
                            "secretId": {
                              "description": "The second stored secret. Must differ from the primary — the same id twice sends one value under two names, and the rejection that follows says nothing about which half was wrong.",
                              "examples": [
                                "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                              ],
                              "format": "uuid",
                              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                              "type": "string"
                            }
                          },
                          "required": [
                            "secretId",
                            "name"
                          ],
                          "type": "object"
                        },
                        "secretId": {
                          "description": "The stored secret holding the credential value. 🔴 A REFERENCE, never the credential itself — the value is decrypted only when a call runs, so it never rides a dashboard read of the agent. Create one in the dashboard under Secrets.",
                          "examples": [
                            "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b"
                          ],
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                          "type": "string"
                        },
                        "type": {
                          "description": "The scheme. `bearer` and `basic` are header schemes by definition and cannot be placed elsewhere; only `api_key` may move.",
                          "enum": [
                            "bearer",
                            "api_key",
                            "basic"
                          ],
                          "examples": [
                            "bearer"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "type",
                        "secretId"
                      ],
                      "type": "object"
                    },
                    "bodyFormat": {
                      "description": "How the body is encoded. `json` by default; `form` sends `application/x-www-form-urlencoded`, which is FLAT — a dotted parameter path cannot be encoded into it and is refused.",
                      "enum": [
                        "json",
                        "form"
                      ],
                      "examples": [
                        "json"
                      ],
                      "type": "string"
                    },
                    "bodyRoot": {
                      "description": "Whether the request body is a JSON object (default) or an array. 🔴 With `array`, every parameter path must start with an index such as `0.email` — a named key set on an array is dropped silently when the body is serialised, and your API then reports a missing required field.",
                      "enum": [
                        "object",
                        "array"
                      ],
                      "examples": [
                        "object"
                      ],
                      "type": "string"
                    },
                    "headers": {
                      "additionalProperties": {
                        "maxLength": 1024,
                        "type": "string"
                      },
                      "description": "Static headers sent with every call, up to 16. 🔴 Credentials do not go here — `authorization` is refused outright, as are platform-owned headers and anything `x-tone-*`. Use `auth`, which keeps the secret out of every agent read.",
                      "examples": [
                        {
                          "x-acme-source": "tone"
                        }
                      ],
                      "propertyNames": {
                        "pattern": "^[a-zA-Z0-9-]{1,64}$",
                        "type": "string"
                      },
                      "type": "object"
                    },
                    "method": {
                      "description": "The HTTP method. GET and DELETE send no body, so parameters default to the query string.",
                      "enum": [
                        "GET",
                        "POST",
                        "PUT",
                        "PATCH",
                        "DELETE"
                      ],
                      "examples": [
                        "POST"
                      ],
                      "type": "string"
                    },
                    "timeoutMs": {
                      "description": "How long to wait for your endpoint before giving up, in milliseconds (1000-30000). Remember the caller is waiting in silence — keep it short enough that the agent can say something before it becomes an awkward pause.",
                      "examples": [
                        5000
                      ],
                      "maximum": 30000,
                      "minimum": 1000,
                      "type": "integer"
                    },
                    "url": {
                      "description": "The endpoint Tone calls. Checked at save time — a URL pointing at private address space, loopback or a cloud metadata endpoint is refused here rather than discovered mid-call, and the check re-runs against the resolved address at execution. Must be `https` if the tool sends credentials.",
                      "examples": [
                        "https://api.acme.example/v1/deliveries"
                      ],
                      "maxLength": 2048,
                      "minLength": 1,
                      "type": "string"
                    }
                  },
                  "required": [
                    "url",
                    "method"
                  ],
                  "type": "object"
                },
                "mock": {
                  "additionalProperties": false,
                  "description": "Return a fixed response instead of calling the endpoint, so the conversation can be tested before the integration is live.",
                  "properties": {
                    "enabled": {
                      "description": "While true, Tone returns `response` instead of calling your endpoint. Use it to rehearse the conversation before the API exists.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "response": {
                      "description": "The canned reply handed to the model in place of a real response. Shape it like the real thing — the model reads it the same way.",
                      "examples": [
                        "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                      ],
                      "maxLength": 6000,
                      "type": "string"
                    }
                  },
                  "required": [
                    "enabled",
                    "response"
                  ],
                  "type": "object"
                },
                "name": {
                  "description": "What the model calls this tool, lowercase snake_case. Must be unique on the agent and cannot shadow a built-in name such as `end_call` or `query_knowledge`.",
                  "examples": [
                    "book_delivery_slot"
                  ],
                  "pattern": "^[a-z][a-z0-9_]{1,39}$",
                  "type": "string"
                },
                "parameters": {
                  "description": "What the agent collects before calling, up to 16. Names must be unique within the tool.",
                  "examples": [
                    [
                      {
                        "description": "The agreed date as YYYY-MM-DD.",
                        "name": "delivery_date",
                        "required": true,
                        "type": "string"
                      }
                    ]
                  ],
                  "items": {
                    "additionalProperties": false,
                    "properties": {
                      "description": {
                        "description": "What this parameter holds, in the model's terms. Required unless the parameter is pinned with `value` — a parameter the model fills with no description collects garbage.",
                        "examples": [
                          "The delivery date the customer agreed to, as YYYY-MM-DD."
                        ],
                        "maxLength": 500,
                        "type": "string"
                      },
                      "enum": {
                        "description": "Clamp the model's answer to this list, 2-24 values. String parameters only, and mutually exclusive with `value`.",
                        "examples": [
                          [
                            "morning",
                            "afternoon"
                          ]
                        ],
                        "items": {
                          "maxLength": 64,
                          "minLength": 1,
                          "type": "string"
                        },
                        "maxItems": 24,
                        "minItems": 2,
                        "type": "array"
                      },
                      "in": {
                        "description": "Where the value goes on the wire. Defaults to the method's natural place — query for GET and DELETE, body for the rest. Use `path` to substitute a `{placeholder}` in the URL.",
                        "enum": [
                          "query",
                          "body",
                          "path"
                        ],
                        "examples": [
                          "body"
                        ],
                        "type": "string"
                      },
                      "name": {
                        "description": "The parameter name the model fills in, lowercase snake_case. Also the wire name unless `path` overrides it.",
                        "examples": [
                          "delivery_date"
                        ],
                        "pattern": "^[a-z][a-z0-9_]{0,39}$",
                        "type": "string"
                      },
                      "path": {
                        "description": "The wire name, when it differs from `name`: a query key, a path placeholder, or a dotted location inside the body such as `attendee.email`. Dots nest only inside a JSON body — on a query key they would be sent literally, so that combination is rejected.",
                        "examples": [
                          "attendee.email"
                        ],
                        "maxLength": 120,
                        "pattern": "^[a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+)*$",
                        "type": "string"
                      },
                      "required": {
                        "description": "Whether the model must supply this before the tool can run.",
                        "examples": [
                          true
                        ],
                        "type": "boolean"
                      },
                      "type": {
                        "description": "What kind of value the model must produce.",
                        "enum": [
                          "string",
                          "number",
                          "integer",
                          "boolean"
                        ],
                        "examples": [
                          "string"
                        ],
                        "type": "string"
                      },
                      "value": {
                        "description": "Pin the parameter to a fixed value, injected at call time and INVISIBLE to the model. This is how a tenant id or an account key reaches your API without the model being able to see or change it.",
                        "examples": [
                          "acme-prod"
                        ],
                        "maxLength": 500,
                        "type": "string"
                      }
                    },
                    "required": [
                      "name",
                      "type"
                    ],
                    "type": "object"
                  },
                  "maxItems": 16,
                  "type": "array"
                },
                "preset": {
                  "description": "Read-only provenance. Names the integration preset that installed this tool, if any. Round-trips unchanged so renaming a preset-installed tool does not strip it.",
                  "examples": [
                    "cal.com/book"
                  ],
                  "maxLength": 64,
                  "type": "string"
                },
                "speech": {
                  "additionalProperties": {
                    "maxLength": 200,
                    "minLength": 1,
                    "type": "string"
                  },
                  "description": "What the agent says out loud while it waits for your endpoint, keyed by language code (`hi-IN`, `en-IN`). Without it the caller hears silence for the length of `timeoutMs`, which on a phone call reads as a dropped line. Up to 16 languages.",
                  "examples": [
                    {
                      "en-IN": "Let me check that for you.",
                      "hi-IN": "मैं अभी देखता हूँ।"
                    }
                  ],
                  "propertyNames": {
                    "pattern": "^[a-z]{2,3}-[A-Z]{2}$",
                    "type": "string"
                  },
                  "type": "object"
                }
              },
              "required": [
                "name",
                "description",
                "http"
              ],
              "type": "object"
            },
            "maxItems": 10,
            "type": "array"
          },
          "voice": {
            "additionalProperties": false,
            "description": "The speech stack: which model transcribes, which speaks, in which voice, and which languages the agent handles. 🔴 The (ttsModel, ttsVoice) pair is a constraint, not two independent choices — a voice belongs to one model version and the wrong pairing is rejected at write time rather than becoming a failure mid-call. Read the valid combinations from GET /v1/catalog/voice.",
            "properties": {
              "languages": {
                "description": "Every language this agent is allowed to speak, most-preferred first. Also the clamp on auto-detection: the transcriber understands about twice as many languages as the speaking model can speak, so a detection outside this list falls back to the first entry instead of producing a reply the voice cannot say. An empty list means \"no opinion\" — adopt whatever is detected.",
                "examples": [
                  [
                    "hi-IN",
                    "en-IN"
                  ]
                ],
                "items": {
                  "maxLength": 64,
                  "minLength": 1,
                  "type": "string"
                },
                "maxItems": 32,
                "type": "array"
              },
              "sttLanguage": {
                "description": "The language to expect from the caller, or `auto` to detect it per utterance. Auto-detection is clamped to `languages`, so a detection outside that list falls back to the first entry rather than opening a socket the speaking model would reject.",
                "examples": [
                  "auto"
                ],
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              },
              "sttMode": {
                "description": "How the transcriber treats the caller's language. `transcribe` writes what was said in the language it was said in; `translate` renders it into English. Values come from the catalog.",
                "examples": [
                  "transcribe"
                ],
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              },
              "sttModel": {
                "description": "Which model transcribes the caller. Read the legal values from `GET /v1/catalog/voice` — they change without a deploy.",
                "examples": [
                  "saaras:v3"
                ],
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              },
              "ttsModel": {
                "description": "Which model speaks. 🔴 Half of a constraint: a voice belongs to one model version, so changing this can invalidate the `ttsVoice` already on the agent — send both together when you switch.",
                "examples": [
                  "bulbul:v3"
                ],
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              },
              "ttsOptions": {
                "additionalProperties": {
                  "type": "number"
                },
                "description": "Model-specific voice tuning, as a map of option name to number. Which options exist depends on the speaking model — v3 dropped `pitch` and `loudness` and added `temperature`. `GET /v1/catalog/voice` lists each model's options with their ranges; an option the chosen model does not take is rejected.",
                "examples": [
                  {
                    "pace": 1
                  }
                ],
                "propertyNames": {
                  "maxLength": 32,
                  "type": "string"
                },
                "type": "object"
              },
              "ttsVoice": {
                "description": "Which voice speaks. 🔴 Valid only for its own `ttsModel` — `simran` is a v3 voice and is rejected on v2, `anushka` is the reverse. The pair is checked at write time so it cannot fail mid-call.",
                "examples": [
                  "simran"
                ],
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              }
            },
            "type": "object"
          }
        },
        "required": [
          "name",
          "systemPrompt"
        ],
        "type": "object"
      },
      "CreateCallDto": {
        "properties": {
          "agentId": {
            "description": "The agent that runs the call. **Required** when the number routes to a Tone agent (`routingMode: \"tone_agent\"`) and **forbidden** when it routes to your own stack — the number decides which, and either mistake is a `422`. Optional in the schema only because the schema cannot see the number.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ],
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "numberId": {
            "description": "The number to call FROM. Must be `active`; a `suspended` number refuses in both directions.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ],
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "toE164": {
            "description": "The recipient, in E.164 — a leading `+`, country code, no spaces or punctuation. In test mode, the magic numbers `+915555000001`-`+915555000006` produce fixed outcomes.",
            "examples": [
              "+919876543210"
            ],
            "pattern": "^\\+91\\d{10,11}$",
            "type": "string"
          },
          "variables": {
            "additionalProperties": {
              "anyOf": [
                {
                  "maxLength": 500,
                  "type": "string"
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                }
              ]
            },
            "description": "Values for the agent's declared input variables on this call, overriding its defaults. Stored on the call record and returned by reads. Persona data only — nothing here reaches the compliance gate.",
            "propertyNames": {
              "pattern": "^[a-z][a-z0-9_]{0,39}$",
              "type": "string"
            },
            "type": "object"
          }
        },
        "required": [
          "numberId",
          "toE164"
        ],
        "type": "object"
      },
      "CreateCampaignDto": {
        "properties": {
          "agentId": {
            "description": "The agent every call in this campaign runs. **Cannot be changed after creation** — duplicate the campaign to use a different agent. Its `purpose` is snapshotted at launch and drives the compliance gate for the whole run.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ],
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "autoPauseBelowPaise": {
            "description": "Wallet floor in paise. When the balance falls below it the campaign pauses itself with pausedReason low_balance and emits campaign.paused, instead of dialling until calls start failing mid-conversation. Resume it after topping up.",
            "examples": [
              50000
            ],
            "maximum": 9007199254740991,
            "minimum": 0,
            "type": "integer"
          },
          "callsPerMinute": {
            "description": "How fast to dial, 1-60. The ceiling is the carrier's own campaign throttle, and bursts from a single caller ID are the pattern TCCCPR's spam rubric watches for — if you need more throughput, use more numbers rather than a higher rate.",
            "examples": [
              10
            ],
            "maximum": 60,
            "minimum": 1,
            "type": "integer"
          },
          "endsAt": {
            "description": "Stop dialling at this instant even if recipients remain. Must be later than `startsAt`.",
            "examples": [
              "2026-09-07T14:00:00Z"
            ],
            "type": "string"
          },
          "maxConcurrent": {
            "description": "How many calls may be in flight at once, 1-20. 🔴 This does **not** queue above your organisation's concurrency quota — recipients dialled over it are refused and settle as `failed`. Check `GET /v1/limits` and keep this at or below what it reports.",
            "examples": [
              4
            ],
            "maximum": 20,
            "minimum": 1,
            "type": "integer"
          },
          "name": {
            "description": "Your label for the campaign. Shown in the dashboard and on every call it places.",
            "examples": [
              "COD confirmations — September"
            ],
            "maxLength": 120,
            "minLength": 1,
            "type": "string"
          },
          "numberId": {
            "description": "The number to dial from. Must route to a Tone agent — a campaign on a BYO number is refused at launch rather than failing per call.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ],
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "retryAttempts": {
            "description": "How many times to redial a recipient whose outcome is in `retryOn`. 0-3; 0 disables retries.",
            "examples": [
              1
            ],
            "maximum": 3,
            "minimum": 0,
            "type": "integer"
          },
          "retryBackoff": {
            "description": "How the wait grows between successive retries. Open set — handle an unrecognised value rather than throwing. Today: `linear`, `exponential`.",
            "enum": [
              "linear",
              "exponential"
            ],
            "examples": [
              "fixed"
            ],
            "type": "string",
            "x-known-values": [
              "linear",
              "exponential"
            ]
          },
          "retryIntervalMinutes": {
            "description": "Minutes to wait before the first retry, 5-1440.",
            "examples": [
              60
            ],
            "maximum": 1440,
            "minimum": 5,
            "type": "integer"
          },
          "retryOn": {
            "description": "Which outcomes earn a retry. 🔴 `answered` is deliberately not accepted — redialling someone who already spoke to the agent is what turns a campaign into a complaint, and under TCCCPR five complaints in ten days bars every number your organisation owns.",
            "examples": [
              [
                "no_answer",
                "busy"
              ]
            ],
            "items": {
              "enum": [
                "no_answer",
                "busy",
                "failed",
                "voicemail"
              ],
              "type": "string"
            },
            "maxItems": 4,
            "type": "array"
          },
          "startsAt": {
            "description": "Do not dial before this instant. Omit to start as soon as the campaign is launched.",
            "examples": [
              "2026-09-01T04:00:00Z"
            ],
            "type": "string"
          },
          "weekdays": {
            "description": "Which weekdays may dial, as a 7-bit mask with **Monday = bit 0** (`0b0011111` = 31 = Mon-Fri, 127 = every day). `0` is refused: a campaign with no enabled weekday can never dial, and accepting it would leave it `running` and silently idle.",
            "examples": [
              31
            ],
            "maximum": 127,
            "minimum": 1,
            "type": "integer"
          },
          "windowEndMinute": {
            "description": "Latest minute of the day this campaign may dial, as minutes past midnight IST (1260 = 21:00). 1440 is accepted so a window can run to midnight. Must be later than `windowStartMinute`, and the **retry tail has to fit inside it too** — a schedule whose retries would land outside the window is refused at launch.",
            "examples": [
              1260
            ],
            "maximum": 1440,
            "minimum": 0,
            "type": "integer"
          },
          "windowStartMinute": {
            "description": "Earliest minute of the day this campaign may dial, as **minutes past midnight IST** (540 = 09:00). Narrower than the legal band, never wider: the compliance gate still applies and will block a call this window would have allowed.",
            "examples": [
              540
            ],
            "maximum": 1439,
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "name",
          "agentId",
          "numberId"
        ],
        "type": "object"
      },
      "CreateContactSubmissionDto": {
        "properties": {
          "building": {
            "default": [],
            "description": "What you are building, in your own words. Free-form tags.",
            "examples": [
              [
                "Order confirmations"
              ]
            ],
            "items": {
              "maxLength": 100,
              "type": "string"
            },
            "maxItems": 20,
            "type": "array"
          },
          "companyName": {
            "description": "Your company name.",
            "examples": [
              "Acme Retail"
            ],
            "maxLength": 200,
            "minLength": 1,
            "type": "string"
          },
          "companySize": {
            "description": "Roughly how many people work there. Open set — handle an unrecognised value rather than throwing. Today: `1-10`, `11-50`, `51-200`, `201-1000`, `1000+`.",
            "enum": [
              "1-10",
              "11-50",
              "51-200",
              "201-1000",
              "1000+"
            ],
            "examples": [
              "11-50"
            ],
            "type": "string",
            "x-known-values": [
              "1-10",
              "11-50",
              "51-200",
              "201-1000",
              "1000+"
            ]
          },
          "companyWebsite": {
            "anyOf": [
              {
                "format": "uri",
                "maxLength": 500,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your company website, if you have one.",
            "examples": [
              "https://acme.example"
            ]
          },
          "details": {
            "anyOf": [
              {
                "maxLength": 5000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Anything else worth knowing before we reply.",
            "examples": [
              "We place about 5,000 COD confirmation calls a week."
            ]
          },
          "email": {
            "description": "A work email we can reply to.",
            "examples": [
              "priya@example.com"
            ],
            "format": "email",
            "maxLength": 255,
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
            "type": "string"
          },
          "firstName": {
            "description": "Your first name.",
            "examples": [
              "Priya"
            ],
            "maxLength": 100,
            "minLength": 1,
            "type": "string"
          },
          "lastName": {
            "description": "Your last name.",
            "examples": [
              "Sharma"
            ],
            "maxLength": 100,
            "minLength": 1,
            "type": "string"
          },
          "lookingFor": {
            "default": [],
            "description": "What you want from Tone. Free-form tags.",
            "examples": [
              [
                "Outbound calling",
                "TRAI compliance"
              ]
            ],
            "items": {
              "maxLength": 100,
              "type": "string"
            },
            "maxItems": 20,
            "type": "array"
          },
          "phone": {
            "description": "A phone number we can reach you on.",
            "examples": [
              "+919876543210"
            ],
            "maxLength": 30,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "firstName",
          "lastName",
          "email",
          "phone",
          "companyName",
          "companySize"
        ],
        "type": "object"
      },
      "CreateKnowledgeBaseDto": {
        "properties": {
          "description": {
            "description": "What this base covers. For your own reference; the agent does not read it.",
            "examples": [
              "Delivery timelines, COD rules and the returns window."
            ],
            "maxLength": 280,
            "type": "string"
          },
          "name": {
            "description": "Your name for the knowledge base.",
            "examples": [
              "Shipping and returns policy"
            ],
            "maxLength": 64,
            "minLength": 1,
            "pattern": "^[^\\p{C}]+$",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "CreateUploadUrlDto": {
        "properties": {
          "contentLength": {
            "description": "Exact size in bytes of the file you are about to PUT. Required because it is signed into the URL — a presigned PUT that does not pin the length is an unbounded write. A mismatch fails the upload.",
            "examples": [
              248311
            ],
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991,
            "type": "integer"
          },
          "contentType": {
            "description": "The MIME type you are about to upload.",
            "examples": [
              "application/pdf"
            ],
            "maxLength": 200,
            "minLength": 1,
            "type": "string"
          },
          "filename": {
            "description": "The file name, with no path separators. Shown in the document list.",
            "examples": [
              "returns-policy.pdf"
            ],
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[^\\p{C}/\\\\]+$",
            "type": "string"
          },
          "kind": {
            "description": "What kind of document this is. Web pages are not uploaded — import those with POST /v1/knowledge-bases/{{id}}/documents/url instead. Open set — handle an unrecognised value rather than throwing. Today: `pdf`, `docx`, `txt`, `csv`, `md`.",
            "enum": [
              "pdf",
              "docx",
              "txt",
              "csv",
              "md"
            ],
            "examples": [
              "file"
            ],
            "type": "string",
            "x-known-values": [
              "pdf",
              "docx",
              "txt",
              "csv",
              "md"
            ]
          }
        },
        "required": [
          "filename",
          "contentType",
          "contentLength",
          "kind"
        ],
        "type": "object"
      },
      "CreateWebhookEndpointDto": {
        "properties": {
          "description": {
            "description": "Your label for this endpoint. Shown in the delivery log.",
            "examples": [
              "Production CRM sync"
            ],
            "maxLength": 120,
            "type": "string"
          },
          "enabled": {
            "description": "Whether deliveries are sent. Disable to stop delivery without losing the endpoint, its secret or its history.",
            "examples": [
              true
            ],
            "type": "boolean"
          },
          "events": {
            "default": [
              "call.completed"
            ],
            "description": "Which events to send to this endpoint. Subscribe only to what you consume — every delivery is retried up to 14 times over roughly a day, and 20 consecutive failures across all deliveries disables the endpoint. Open set — handle an unrecognised value rather than throwing. Today: `call.initiated`, `call.answered`, `call.completed`, `call.failed`, `campaign.completed`, `campaign.paused`, `compliance.check.blocked`, `wallet.balance.low`, `number.suspended`, `number.reactivated`, `knowledge.build.completed`, `knowledge.build.failed`.",
            "examples": [
              [
                "call.completed",
                "call.failed"
              ]
            ],
            "items": {
              "enum": [
                "call.initiated",
                "call.answered",
                "call.completed",
                "call.failed",
                "campaign.completed",
                "campaign.paused",
                "compliance.check.blocked",
                "wallet.balance.low",
                "number.suspended",
                "number.reactivated",
                "knowledge.build.completed",
                "knowledge.build.failed"
              ],
              "type": "string"
            },
            "minItems": 1,
            "type": "array",
            "x-known-values": [
              "call.initiated",
              "call.answered",
              "call.completed",
              "call.failed",
              "campaign.completed",
              "campaign.paused",
              "compliance.check.blocked",
              "wallet.balance.low",
              "number.suspended",
              "number.reactivated",
              "knowledge.build.completed",
              "knowledge.build.failed"
            ]
          },
          "url": {
            "description": "Where to POST deliveries. Must be a public https:// URL — private and link-local addresses are refused at save time rather than discovered at delivery time. Answer 2xx within 10 seconds; anything slower is retried and will manufacture duplicates.",
            "examples": [
              "https://hooks.example.com/tone"
            ],
            "format": "uri",
            "maxLength": 2048,
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "type": "object"
      },
      "CreatedWebhookEndpointResponse": {
        "properties": {
          "consecutiveFailures": {
            "description": "Resets to 0 on the first success.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "createdAt": {
            "description": "RFC 3339, UTC.",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your label for this endpoint.",
            "examples": [
              "Production — order service"
            ]
          },
          "disabledReason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why we switched it off, when we did — never silent, and the owners are emailed. Sustained failures disable an endpoint after the retry ladder is exhausted.",
            "examples": [
              null
            ]
          },
          "enabled": {
            "description": "Whether deliveries are being sent. Set false by you, or automatically after 20 consecutive delivery failures.",
            "type": "boolean"
          },
          "events": {
            "description": "Which events this endpoint receives. Open set — handle an unrecognised value rather than throwing. Today: `call.initiated`, `call.answered`, `call.completed`, `call.failed`, `campaign.completed`, `campaign.paused`, `compliance.check.blocked`, `wallet.balance.low`, `number.suspended`, `number.reactivated`, `knowledge.build.completed`, `knowledge.build.failed`.",
            "examples": [
              [
                "call.completed",
                "campaign.finished"
              ]
            ],
            "items": {
              "type": "string"
            },
            "type": "array",
            "x-known-values": [
              "call.initiated",
              "call.answered",
              "call.completed",
              "call.failed",
              "campaign.completed",
              "campaign.paused",
              "compliance.check.blocked",
              "wallet.balance.low",
              "number.suspended",
              "number.reactivated",
              "knowledge.build.completed",
              "knowledge.build.failed"
            ]
          },
          "id": {
            "description": "The created webhook endpoint's unique id.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "secret": {
            "description": "The `whsec_` signing secret. Shown here and never again in this form — store it now. It stays readable at admin scope from the endpoint’s own secret route.",
            "examples": [
              "whsec_3f1a7f6e2b4c4d1e9a8b5c6d7e8f9a0b"
            ],
            "type": "string"
          },
          "url": {
            "description": "Where deliveries are POSTed. Vetted at save time — a private-range URL is refused by the form, not discovered at delivery.",
            "examples": [
              "https://hooks.acme.example/tone"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "url",
          "description",
          "events",
          "enabled",
          "disabledReason",
          "consecutiveFailures",
          "createdAt",
          "secret"
        ],
        "type": "object"
      },
      "DncEntryResponse": {
        "properties": {
          "createdAt": {
            "description": "When this number was suppressed, RFC 3339 UTC.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          },
          "e164": {
            "description": "The suppressed number, in E.164.",
            "examples": [
              "+919876543210"
            ],
            "type": "string"
          },
          "expiresAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null is permanent. A date is the end of the 90-day opt-out lockout.",
            "examples": [
              "2026-11-23T09:14:22Z"
            ]
          },
          "id": {
            "description": "The suppression entry’s id. Pass it to `POST /v1/dnc/{id}/remove` to lift the suppression — a dashboard-session action that requires a written reason.",
            "examples": [
              "8814"
            ],
            "type": "string"
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this number was suppressed.",
            "examples": [
              "Asked to be removed during a call on 2026-08-20."
            ]
          },
          "removedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Non-null means the suppression was LIFTED — the entry no longer blocks, and survives only as the record of the removal.",
            "examples": [
              null
            ]
          },
          "removedReason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The written justification the operator gave when lifting it.",
            "examples": [
              null
            ]
          },
          "source": {
            "description": "How it got on the list. Open set — handle an unrecognised value rather than throwing. Today: `manual`, `csv`, `api`, `caller_request`, `complaint`, `carrier_rejection`.",
            "type": "string",
            "x-known-values": [
              "manual",
              "csv",
              "api",
              "caller_request",
              "complaint",
              "carrier_rejection"
            ]
          },
          "sourceCallId": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The call that produced this suppression, when it was captured in-call (DTMF, verbal opt-out) or from a carrier rejection.",
            "examples": [
              null
            ]
          }
        },
        "required": [
          "id",
          "e164",
          "source",
          "reason",
          "expiresAt",
          "sourceCallId",
          "removedAt",
          "removedReason",
          "createdAt"
        ],
        "type": "object"
      },
      "EmailAvailabilityDto": {
        "properties": {
          "email": {
            "description": "The address to check. Answers whether it can be signed up, without revealing anything about an existing account beyond availability.",
            "examples": [
              "priya@example.com"
            ],
            "format": "email",
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
            "type": "string"
          }
        },
        "required": [
          "email"
        ],
        "type": "object"
      },
      "Error": {
        "description": "Every error response has this shape. Branch on `error.code`, never on `error.message`.",
        "properties": {
          "error": {
            "description": "The failure. Present INSTEAD OF `data`, never alongside it, so the presence of this key is how you tell a failure from a success.",
            "properties": {
              "code": {
                "description": "Stable machine-readable reason, part of the public contract. OPEN SET: codes are added over time, so fall back on `type` and the HTTP status for one you do not know. Never removed or renamed.",
                "type": "string",
                "x-known-values": [
                  "bad_request",
                  "blocked_dlt_invalid",
                  "blocked_dnd",
                  "blocked_opt_out",
                  "compliance_incomplete",
                  "concurrent_call_limit_reached",
                  "conflict",
                  "document_too_large",
                  "email_exists",
                  "email_not_verified",
                  "environment_mismatch",
                  "forbidden",
                  "idempotency_key_in_use",
                  "idempotency_key_reused_with_different_params",
                  "insufficient_funds",
                  "insufficient_scope",
                  "internal_error",
                  "invalid_credentials",
                  "invalid_signature",
                  "invalid_token",
                  "knowledge_base_not_ready",
                  "mfa_required",
                  "not_found",
                  "number_unavailable",
                  "provider_misconfigured",
                  "provider_quota_exhausted",
                  "provider_unavailable",
                  "rate_limited",
                  "token_expired",
                  "unauthenticated",
                  "unprocessable_entity",
                  "validation_error"
                ]
              },
              "details": {
                "description": "Structured context when there is any (e.g. which fields failed)."
              },
              "doc_url": {
                "description": "Documentation anchor for this specific code.",
                "format": "uri",
                "type": "string"
              },
              "message": {
                "description": "Human-readable. Reworded freely; do not parse.",
                "type": "string"
              },
              "request_id": {
                "description": "Quote this when contacting support.",
                "type": "string"
              },
              "type": {
                "description": "Coarse category. OPEN SET — handle an unrecognised value rather than throwing.",
                "type": "string",
                "x-known-values": [
                  "authentication",
                  "authorization",
                  "compliance",
                  "conflict",
                  "invalid_request",
                  "not_found",
                  "payment_required",
                  "rate_limit",
                  "server_error"
                ]
              }
            },
            "required": [
              "type",
              "code",
              "message",
              "doc_url",
              "request_id"
            ],
            "type": "object"
          }
        },
        "required": [
          "error"
        ],
        "type": "object"
      },
      "EventDetailResponse": {
        "properties": {
          "createdAt": {
            "description": "RFC 3339, UTC. Retained 30 days.",
            "type": "string"
          },
          "delivery": {
            "description": "This event’s delivery to one endpoint.",
            "properties": {
              "attempts": {
                "description": "How many times it has been tried, retries included.",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "deliveredAt": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When your endpoint accepted it, RFC 3339 UTC. Null while pending or failed.",
                "examples": [
                  "2026-08-25T09:14:03Z"
                ]
              },
              "endpointId": {
                "description": "Which of your webhook endpoints this delivery was for. An event delivered to two endpoints is listed twice, once per endpoint, because each has its own outcome.",
                "examples": [
                  "2b7c1d90-4e5f-4a6b-8c9d-0e1f2a3b4c5d"
                ],
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "type": "string"
              },
              "lastStatus": {
                "anyOf": [
                  {
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "The HTTP status your endpoint last answered with. Null if it never responded."
              },
              "status": {
                "description": "Where this delivery stands. Open set — handle an unrecognised value rather than throwing. Today: `pending`, `delivered`, `failed`.",
                "type": "string",
                "x-known-values": [
                  "pending",
                  "delivered",
                  "failed"
                ]
              }
            },
            "required": [
              "endpointId",
              "status",
              "attempts",
              "lastStatus",
              "deliveredAt"
            ],
            "type": "object"
          },
          "id": {
            "description": "Also the `x-tone-event-id` header your endpoint received.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "payload": {
            "anyOf": [
              {
                "properties": {
                  "created_at": {
                    "description": "Snake_case here and nowhere else: this is the webhook wire body verbatim. RFC 3339, UTC.",
                    "type": "string"
                  },
                  "data": {
                    "additionalProperties": {},
                    "description": "Keyed by subject — `{ call }`, `{ campaign }`, `{ number }`, … Each is that resource’s own representation, unchanged.",
                    "propertyNames": {
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "id": {
                    "description": "The event id, the same value as `id` above and as the `x-tone-event-id` header.",
                    "examples": [
                      "evt_01J9Z2K3M4N5P6Q7R8S9T0"
                    ],
                    "type": "string"
                  },
                  "links": {
                    "description": "API routes for the heavy parts. No transcript rides inline — it is multi-KB and a bad neighbour on a webhook handler.",
                    "properties": {
                      "recording": {
                        "description": "Where to fetch the recording. Present only when the call was recorded.",
                        "examples": [
                          "/v1/calls/9f1c2d84-5b6a-4c3d-8e2f-1a0b9c8d7e6f/recording"
                        ],
                        "type": "string"
                      },
                      "self": {
                        "description": "The subject's own API route.",
                        "examples": [
                          "/v1/calls/9f1c2d84-5b6a-4c3d-8e2f-1a0b9c8d7e6f"
                        ],
                        "type": "string"
                      },
                      "transcript": {
                        "description": "Where to fetch the transcript. Present on call events only.",
                        "examples": [
                          "/v1/calls/9f1c2d84-5b6a-4c3d-8e2f-1a0b9c8d7e6f/transcript"
                        ],
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "The event type, the same value as `type` above.",
                    "examples": [
                      "call.completed"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "The event body. Null when the subject has since been deleted."
          },
          "subjectId": {
            "description": "The subject’s id — fetchable from its own resource route.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ],
            "type": "string"
          },
          "subjectType": {
            "description": "What kind of thing it happened to. Open set — handle an unrecognised value rather than throwing. Today: `call`, `campaign`, `compliance_check`, `document`, `knowledge_base`, `number`, `organization`, `verification`, `wallet`.",
            "type": "string",
            "x-known-values": [
              "call",
              "campaign",
              "compliance_check",
              "document",
              "knowledge_base",
              "number",
              "organization",
              "verification",
              "wallet"
            ]
          },
          "type": {
            "description": "What happened. Open set — handle an unrecognised value rather than throwing. Today: `call.initiated`, `call.answered`, `call.completed`, `call.failed`, `campaign.completed`, `campaign.paused`, `compliance.check.blocked`, `wallet.balance.low`, `number.suspended`, `number.reactivated`, `knowledge.build.completed`, `knowledge.build.failed`.",
            "type": "string",
            "x-known-values": [
              "call.initiated",
              "call.answered",
              "call.completed",
              "call.failed",
              "campaign.completed",
              "campaign.paused",
              "compliance.check.blocked",
              "wallet.balance.low",
              "number.suspended",
              "number.reactivated",
              "knowledge.build.completed",
              "knowledge.build.failed"
            ]
          }
        },
        "required": [
          "id",
          "type",
          "subjectType",
          "subjectId",
          "createdAt",
          "delivery",
          "payload"
        ],
        "type": "object"
      },
      "EventSummaryResponse": {
        "properties": {
          "createdAt": {
            "description": "RFC 3339, UTC. Retained 30 days.",
            "type": "string"
          },
          "delivery": {
            "description": "This event’s delivery to one endpoint.",
            "properties": {
              "attempts": {
                "description": "How many times it has been tried, retries included.",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "deliveredAt": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When your endpoint accepted it, RFC 3339 UTC. Null while pending or failed.",
                "examples": [
                  "2026-08-25T09:14:03Z"
                ]
              },
              "endpointId": {
                "description": "Which of your webhook endpoints this delivery was for. An event delivered to two endpoints is listed twice, once per endpoint, because each has its own outcome.",
                "examples": [
                  "2b7c1d90-4e5f-4a6b-8c9d-0e1f2a3b4c5d"
                ],
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "type": "string"
              },
              "lastStatus": {
                "anyOf": [
                  {
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "The HTTP status your endpoint last answered with. Null if it never responded."
              },
              "status": {
                "description": "Where this delivery stands. Open set — handle an unrecognised value rather than throwing. Today: `pending`, `delivered`, `failed`.",
                "type": "string",
                "x-known-values": [
                  "pending",
                  "delivered",
                  "failed"
                ]
              }
            },
            "required": [
              "endpointId",
              "status",
              "attempts",
              "lastStatus",
              "deliveredAt"
            ],
            "type": "object"
          },
          "id": {
            "description": "Also the `x-tone-event-id` header your endpoint received.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "subjectId": {
            "description": "The subject’s id — fetchable from its own resource route.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ],
            "type": "string"
          },
          "subjectType": {
            "description": "What kind of thing it happened to. Open set — handle an unrecognised value rather than throwing. Today: `call`, `campaign`, `compliance_check`, `document`, `knowledge_base`, `number`, `organization`, `verification`, `wallet`.",
            "type": "string",
            "x-known-values": [
              "call",
              "campaign",
              "compliance_check",
              "document",
              "knowledge_base",
              "number",
              "organization",
              "verification",
              "wallet"
            ]
          },
          "type": {
            "description": "What happened. Open set — handle an unrecognised value rather than throwing. Today: `call.initiated`, `call.answered`, `call.completed`, `call.failed`, `campaign.completed`, `campaign.paused`, `compliance.check.blocked`, `wallet.balance.low`, `number.suspended`, `number.reactivated`, `knowledge.build.completed`, `knowledge.build.failed`.",
            "type": "string",
            "x-known-values": [
              "call.initiated",
              "call.answered",
              "call.completed",
              "call.failed",
              "campaign.completed",
              "campaign.paused",
              "compliance.check.blocked",
              "wallet.balance.low",
              "number.suspended",
              "number.reactivated",
              "knowledge.build.completed",
              "knowledge.build.failed"
            ]
          }
        },
        "required": [
          "id",
          "type",
          "subjectType",
          "subjectId",
          "createdAt",
          "delivery"
        ],
        "type": "object"
      },
      "EvidencePackResponse": {
        "properties": {
          "checks": {
            "description": "Every gate decision, in the order it ran.",
            "items": {
              "properties": {
                "callId": {
                  "anyOf": [
                    {
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Null for a standalone check.",
                  "examples": [
                    "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                  ]
                },
                "checkType": {
                  "description": "Which rule ran. Open set — handle an unrecognised value rather than throwing. Today: `dnc`, `carrier_dnd`, `consent`, `dlt`, `a2p`, `time_window`, `enforcement_change`, `profile_change`, `call_outcome`, `suppression_change`.",
                  "type": "string",
                  "x-known-values": [
                    "dnc",
                    "carrier_dnd",
                    "consent",
                    "dlt",
                    "a2p",
                    "time_window",
                    "enforcement_change",
                    "profile_change",
                    "call_outcome",
                    "suppression_change"
                  ]
                },
                "createdAt": {
                  "description": "When this check ran, RFC 3339 UTC. A check row is a snapshot: it says what was true at dial time even if the underlying consent or suppression entry changes later.",
                  "examples": [
                    "2026-08-25T09:14:22Z"
                  ],
                  "type": "string"
                },
                "detail": {
                  "additionalProperties": {},
                  "description": "Rule-specific evidence, as recorded at the time.",
                  "propertyNames": {
                    "type": "string"
                  },
                  "type": "object"
                },
                "e164": {
                  "description": "The number this check was about, in E.164.",
                  "examples": [
                    "+919876543210"
                  ],
                  "type": "string"
                },
                "enforced": {
                  "description": "Whether enforcement was ON when this ran. A recorded block with `false` did not stop anything.",
                  "type": "boolean"
                },
                "id": {
                  "description": "The audit row’s id — cite it when reporting an outcome.",
                  "examples": [
                    "8814"
                  ],
                  "type": "string"
                },
                "outcome": {
                  "description": "Only `block` refuses a call. A `warn` is advisory and is recorded, not enforced — carrier DND data is warn-only by design. An `error` means the check itself failed to run: recorded so a broken check is a visible fact, and treated as a block when the check is mandatory. Open set — handle an unrecognised value rather than throwing. Today: `pass`, `warn`, `block`, `error`.",
                  "type": "string",
                  "x-known-values": [
                    "pass",
                    "warn",
                    "block",
                    "error"
                  ]
                },
                "reason": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Why the check came out this way, when the outcome alone does not say it.",
                  "examples": [
                    "Asked to be removed during a call on 2026-08-20."
                  ]
                },
                "source": {
                  "description": "Where the answer came from. Open set — handle an unrecognised value rather than throwing. Today: `internal`, `carrier`, `operator`.",
                  "type": "string",
                  "x-known-values": [
                    "internal",
                    "carrier",
                    "operator"
                  ]
                }
              },
              "required": [
                "id",
                "callId",
                "checkType",
                "outcome",
                "source",
                "e164",
                "reason",
                "enforced",
                "detail",
                "createdAt"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "consents": {
            "description": "The full consent history, revocations included — the ledger is append-only.",
            "items": {
              "properties": {
                "active": {
                  "description": "Whether this record satisfies the gate right now.",
                  "type": "boolean"
                },
                "capturedAt": {
                  "description": "When the RECIPIENT consented, not when you told us.",
                  "examples": [
                    "2026-08-20T11:02:00Z"
                  ],
                  "type": "string"
                },
                "createdAt": {
                  "description": "When this consent was recorded with Tone, RFC 3339 UTC. Distinct from `capturedAt`, which is when the recipient actually consented.",
                  "examples": [
                    "2026-08-25T09:14:22Z"
                  ],
                  "type": "string"
                },
                "e164": {
                  "description": "The number that consented, in E.164.",
                  "examples": [
                    "+919876543210"
                  ],
                  "type": "string"
                },
                "evidenceRef": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Where the proof lives — form id, recording URL, DCA reference.",
                  "examples": [
                    "form-sub-88213"
                  ]
                },
                "expiresAt": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "When the consent lapses. RFC 3339, UTC. Null means it stands until revoked.",
                  "examples": [
                    "2026-11-23T09:14:22Z"
                  ]
                },
                "id": {
                  "description": "The consent record’s id. Pass it to `POST /v1/consent/{id}/revoke` to revoke this one record.",
                  "examples": [
                    "8814"
                  ],
                  "type": "string"
                },
                "kind": {
                  "description": "Open set — handle an unrecognised value rather than throwing. Today: `explicit`, `inferred`.",
                  "type": "string",
                  "x-known-values": [
                    "explicit",
                    "inferred"
                  ]
                },
                "purpose": {
                  "description": "What they consented TO. Open set — handle an unrecognised value rather than throwing. Today: `promotional`, `service`, `transactional`, `collections`.",
                  "type": "string",
                  "x-known-values": [
                    "promotional",
                    "service",
                    "transactional",
                    "collections"
                  ]
                },
                "revokedAt": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "The ledger is append-only; revocation is a stamp, not a delete.",
                  "examples": [
                    null
                  ]
                },
                "revokedReason": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Why the consent was revoked, when a reason was given.",
                  "examples": [
                    null
                  ]
                },
                "scope": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "What the recipient agreed to, as it was recorded.",
                  "examples": [
                    "Order updates and delivery reminders."
                  ]
                },
                "source": {
                  "description": "Weakest to strongest as evidence. Open set — handle an unrecognised value rather than throwing. Today: `api`, `web_form`, `ivr`, `dtmf`, `otp`, `dca`, `import`.",
                  "type": "string",
                  "x-known-values": [
                    "api",
                    "web_form",
                    "ivr",
                    "dtmf",
                    "otp",
                    "dca",
                    "import"
                  ]
                }
              },
              "required": [
                "id",
                "e164",
                "purpose",
                "kind",
                "source",
                "evidenceRef",
                "scope",
                "capturedAt",
                "expiresAt",
                "revokedAt",
                "revokedReason",
                "active",
                "createdAt"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "e164": {
            "description": "The number this evidence pack is about, in E.164.",
            "examples": [
              "+919876543210"
            ],
            "type": "string"
          },
          "generatedAt": {
            "description": "When this pack was assembled. RFC 3339, UTC.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          },
          "outcomes": {
            "description": "Outcomes reported back for this number.",
            "items": {
              "properties": {
                "callId": {
                  "anyOf": [
                    {
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Null for a standalone check.",
                  "examples": [
                    "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                  ]
                },
                "checkType": {
                  "description": "Which rule ran. Open set — handle an unrecognised value rather than throwing. Today: `dnc`, `carrier_dnd`, `consent`, `dlt`, `a2p`, `time_window`, `enforcement_change`, `profile_change`, `call_outcome`, `suppression_change`.",
                  "type": "string",
                  "x-known-values": [
                    "dnc",
                    "carrier_dnd",
                    "consent",
                    "dlt",
                    "a2p",
                    "time_window",
                    "enforcement_change",
                    "profile_change",
                    "call_outcome",
                    "suppression_change"
                  ]
                },
                "createdAt": {
                  "description": "When this check ran, RFC 3339 UTC. A check row is a snapshot: it says what was true at dial time even if the underlying consent or suppression entry changes later.",
                  "examples": [
                    "2026-08-25T09:14:22Z"
                  ],
                  "type": "string"
                },
                "detail": {
                  "additionalProperties": {},
                  "description": "Rule-specific evidence, as recorded at the time.",
                  "propertyNames": {
                    "type": "string"
                  },
                  "type": "object"
                },
                "e164": {
                  "description": "The number this check was about, in E.164.",
                  "examples": [
                    "+919876543210"
                  ],
                  "type": "string"
                },
                "enforced": {
                  "description": "Whether enforcement was ON when this ran. A recorded block with `false` did not stop anything.",
                  "type": "boolean"
                },
                "id": {
                  "description": "The audit row’s id — cite it when reporting an outcome.",
                  "examples": [
                    "8814"
                  ],
                  "type": "string"
                },
                "outcome": {
                  "description": "Only `block` refuses a call. A `warn` is advisory and is recorded, not enforced — carrier DND data is warn-only by design. An `error` means the check itself failed to run: recorded so a broken check is a visible fact, and treated as a block when the check is mandatory. Open set — handle an unrecognised value rather than throwing. Today: `pass`, `warn`, `block`, `error`.",
                  "type": "string",
                  "x-known-values": [
                    "pass",
                    "warn",
                    "block",
                    "error"
                  ]
                },
                "reason": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Why the check came out this way, when the outcome alone does not say it.",
                  "examples": [
                    "Asked to be removed during a call on 2026-08-20."
                  ]
                },
                "source": {
                  "description": "Where the answer came from. Open set — handle an unrecognised value rather than throwing. Today: `internal`, `carrier`, `operator`.",
                  "type": "string",
                  "x-known-values": [
                    "internal",
                    "carrier",
                    "operator"
                  ]
                }
              },
              "required": [
                "id",
                "callId",
                "checkType",
                "outcome",
                "source",
                "e164",
                "reason",
                "enforced",
                "detail",
                "createdAt"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "suppression": {
            "anyOf": [
              {
                "properties": {
                  "createdAt": {
                    "description": "When this number was suppressed, RFC 3339 UTC.",
                    "examples": [
                      "2026-08-25T09:14:22Z"
                    ],
                    "type": "string"
                  },
                  "e164": {
                    "description": "The suppressed number, in E.164.",
                    "examples": [
                      "+919876543210"
                    ],
                    "type": "string"
                  },
                  "expiresAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Null is permanent. A date is the end of the 90-day opt-out lockout.",
                    "examples": [
                      "2026-11-23T09:14:22Z"
                    ]
                  },
                  "id": {
                    "description": "The suppression entry’s id. Pass it to `POST /v1/dnc/{id}/remove` to lift the suppression — a dashboard-session action that requires a written reason.",
                    "examples": [
                      "8814"
                    ],
                    "type": "string"
                  },
                  "reason": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Why this number was suppressed.",
                    "examples": [
                      "Asked to be removed during a call on 2026-08-20."
                    ]
                  },
                  "removedAt": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Non-null means the suppression was LIFTED — the entry no longer blocks, and survives only as the record of the removal.",
                    "examples": [
                      null
                    ]
                  },
                  "removedReason": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The written justification the operator gave when lifting it.",
                    "examples": [
                      null
                    ]
                  },
                  "source": {
                    "description": "How it got on the list. Open set — handle an unrecognised value rather than throwing. Today: `manual`, `csv`, `api`, `caller_request`, `complaint`, `carrier_rejection`.",
                    "type": "string",
                    "x-known-values": [
                      "manual",
                      "csv",
                      "api",
                      "caller_request",
                      "complaint",
                      "carrier_rejection"
                    ]
                  },
                  "sourceCallId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The call that produced this suppression, when it was captured in-call (DTMF, verbal opt-out) or from a carrier rejection.",
                    "examples": [
                      null
                    ]
                  }
                },
                "required": [
                  "id",
                  "e164",
                  "source",
                  "reason",
                  "expiresAt",
                  "sourceCallId",
                  "removedAt",
                  "removedReason",
                  "createdAt"
                ],
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "The suppression entry, if this number carries one."
          },
          "truncated": {
            "description": "True when more evidence existed in the window than the cap returns. Narrow the window.",
            "type": "boolean"
          },
          "window": {
            "description": "The time range this pack covers. Null bounds mean everything on record.",
            "properties": {
              "from": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Start of the range, RFC 3339 UTC. Null means from the beginning of the record.",
                "examples": [
                  "2026-08-01T00:00:00Z"
                ]
              },
              "to": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "End of the range, RFC 3339 UTC. Null means up to now.",
                "examples": [
                  "2026-08-25T00:00:00Z"
                ]
              }
            },
            "required": [
              "from",
              "to"
            ],
            "type": "object"
          }
        },
        "required": [
          "e164",
          "generatedAt",
          "window",
          "checks",
          "outcomes",
          "consents",
          "suppression",
          "truncated"
        ],
        "type": "object"
      },
      "EvidenceRecordResponse": {
        "properties": {
          "callId": {
            "anyOf": [
              {
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The call this record seals. Null for a blocked dial, which never created a call.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ]
          },
          "campaignId": {
            "anyOf": [
              {
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The campaign, when the attempt belonged to one.",
            "examples": [
              null
            ]
          },
          "chainSeq": {
            "description": "Position in your organisation’s evidence chain, from 1. Also the list cursor.",
            "examples": [
              "4211"
            ],
            "type": "string"
          },
          "content": {
            "additionalProperties": {},
            "description": "The evidence document itself — call identity, the legal basis to call (DNC result, consent record, scrub token, carrier signal), how the call was placed (DLT PE ID, A2P declaration, calling window, number status at dial time, AI disclosure), and the outcome. This is exactly the document `contentHash` covers.",
            "propertyNames": {
              "type": "string"
            },
            "type": "object"
          },
          "contentHash": {
            "description": "sha256 (hex) of the canonical serialisation of `content`. Recompute it to prove the document was not altered.",
            "examples": [
              "a3f1…"
            ],
            "type": "string"
          },
          "e164": {
            "description": "The number the attempt was about, in E.164.",
            "examples": [
              "+919876543210"
            ],
            "type": "string"
          },
          "id": {
            "description": "The sealed record’s id.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ],
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "kind": {
            "description": "What kind of attempt this seals. Open set — handle an unrecognised value rather than throwing. Today: `completed_call`, `blocked_dial`.",
            "type": "string",
            "x-known-values": [
              "completed_call",
              "blocked_dial"
            ]
          },
          "prevHash": {
            "description": "The previous record’s `recordHash` — 64 zeros for the first record. What makes deletion and reordering detectable, not just edits.",
            "examples": [
              "0000…"
            ],
            "type": "string"
          },
          "recordHash": {
            "description": "sha256 (hex) of `contentHash + prevHash` — the seal.",
            "examples": [
              "b7e2…"
            ],
            "type": "string"
          },
          "sealedAt": {
            "description": "When the record was sealed, RFC 3339 UTC. Also inside `content`, covered by the hash.",
            "examples": [
              "2026-08-31T09:14:22Z"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "callId",
          "campaignId",
          "e164",
          "kind",
          "content",
          "contentHash",
          "prevHash",
          "recordHash",
          "chainSeq",
          "sealedAt"
        ],
        "type": "object"
      },
      "KnowledgeAgentsResponse": {
        "properties": {
          "agentIds": {
            "description": "Every agent currently attached to this knowledge base.",
            "items": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "agentIds"
        ],
        "type": "object"
      },
      "KnowledgeBaseResponse": {
        "properties": {
          "agentCount": {
            "description": "How many agents currently reference this base. Listed by `GET /v1/knowledge-bases/{id}/agents`.",
            "examples": [
              2
            ],
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "chunkCount": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "How many retrievable passages the last successful build produced. Null before the first build succeeds.",
            "examples": [
              187
            ]
          },
          "compiledTokens": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Size of the compiled snapshot. Null until a build has succeeded."
          },
          "createdAt": {
            "description": "RFC 3339, UTC.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          },
          "deliveryMode": {
            "description": "How this base reaches the agent on a call: `inline` — the whole text rides in the system prompt, no per-turn retrieval and no added latency; `search` — too large to send in full, so passages are retrieved per question; `pending` — nothing built yet. Open set — handle an unrecognised value rather than throwing. Today: `inline`, `search`, `pending`.",
            "type": "string",
            "x-known-values": [
              "inline",
              "search",
              "pending"
            ]
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What this base covers. For your reference; the agent does not read it.",
            "examples": [
              "Delivery timelines, COD rules and the returns window."
            ]
          },
          "docCount": {
            "description": "How many documents the base holds.",
            "examples": [
              4
            ],
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Populated only when `status` is `error`. A failed build behind a still-serving one deliberately reports null — the agent is not broken.",
            "examples": [
              null
            ]
          },
          "id": {
            "description": "The knowledge base's unique id.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "name": {
            "description": "Your name for the knowledge base.",
            "examples": [
              "Shipping and returns policy"
            ],
            "type": "string"
          },
          "status": {
            "description": "Derived lifecycle. `ready` means an agent can answer from this base right now; a base serving its last good build while a newer one failed is still `ready`, because the agent genuinely is answering fine. Open set — handle an unrecognised value rather than throwing. Today: `empty`, `processing`, `ready`, `error`.",
            "type": "string",
            "x-known-values": [
              "empty",
              "processing",
              "ready",
              "error"
            ]
          },
          "totalBytes": {
            "description": "Combined size of those documents, in bytes.",
            "examples": [
              248311
            ],
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "updatedAt": {
            "description": "When the knowledge base was last changed. RFC 3339, UTC.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "status",
          "deliveryMode",
          "docCount",
          "totalBytes",
          "agentCount",
          "compiledTokens",
          "chunkCount",
          "error",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "KnowledgeDocumentResponse": {
        "properties": {
          "byteSize": {
            "description": "The document size in bytes, as measured on our side after upload.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "charCount": {
            "description": "Characters extracted. 0 until the document has been parsed.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "createdAt": {
            "description": "When the document was added. RFC 3339, UTC.",
            "type": "string"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why parsing failed. Null unless `status` is failed.",
            "examples": [
              null
            ]
          },
          "filename": {
            "description": "The document file name.",
            "examples": [
              "returns-policy.pdf"
            ],
            "type": "string"
          },
          "id": {
            "description": "The knowledge document's unique id.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "kind": {
            "description": "What kind of source this is. Open set — handle an unrecognised value rather than throwing. Today: `pdf`, `docx`, `txt`, `csv`, `md`, `url`.",
            "type": "string",
            "x-known-values": [
              "pdf",
              "docx",
              "txt",
              "csv",
              "md",
              "url"
            ]
          },
          "mimeType": {
            "description": "The document content type.",
            "examples": [
              "application/pdf"
            ],
            "type": "string"
          },
          "status": {
            "description": "Where this document is in ingestion. Open set — handle an unrecognised value rather than throwing. Today: `awaiting_upload`, `queued`, `processing`, `ready`, `failed`.",
            "type": "string",
            "x-known-values": [
              "awaiting_upload",
              "queued",
              "processing",
              "ready",
              "failed"
            ]
          },
          "updatedAt": {
            "description": "When the document last changed — including a re-parse. RFC 3339, UTC.",
            "type": "string"
          }
        },
        "required": [
          "id",
          "filename",
          "kind",
          "mimeType",
          "byteSize",
          "status",
          "error",
          "charCount",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "KnowledgeSearchResponse": {
        "properties": {
          "answer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the agent would say. Null when answering is off or failed.",
            "examples": [
              "You can return unopened items within 30 days for a full refund."
            ]
          },
          "answerScope": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the answer was drawn from: the whole base inline, or the retrieved passages. Open set — handle an unrecognised value rather than throwing. Today: `inline`, `passages`.",
            "x-known-values": [
              "inline",
              "passages"
            ]
          },
          "answerStatus": {
            "description": "Open set — handle an unrecognised value rather than throwing. Today: `ok`, `disabled`, `failed`, `no_context`.",
            "type": "string",
            "x-known-values": [
              "ok",
              "disabled",
              "failed",
              "no_context"
            ]
          },
          "degraded": {
            "description": "True when embeddings were unavailable and this fell back to text search alone — the results are real, just weaker.",
            "type": "boolean"
          },
          "results": {
            "description": "The passages retrieval returned, best first — the same passages a live turn would get for this query.",
            "items": {
              "properties": {
                "documentId": {
                  "description": "Which document the passage came from.",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "type": "string"
                },
                "headingPath": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Where the passage sits in the document’s heading structure.",
                  "examples": [
                    "Returns > Timeframe"
                  ]
                },
                "matchedText": {
                  "description": "Found by keyword match. Both can be true.",
                  "type": "boolean"
                },
                "matchedVector": {
                  "description": "Found by embedding similarity.",
                  "type": "boolean"
                },
                "score": {
                  "description": "Relevance, higher is better. Comparable within one response, not across responses.",
                  "type": "number"
                },
                "text": {
                  "description": "The passage itself, exactly as the agent would receive it.",
                  "examples": [
                    "Unopened items may be returned within 30 days of delivery for a full refund."
                  ],
                  "type": "string"
                }
              },
              "required": [
                "documentId",
                "headingPath",
                "text",
                "score",
                "matchedVector",
                "matchedText"
              ],
              "type": "object"
            },
            "type": "array"
          }
        },
        "required": [
          "results",
          "degraded",
          "answer",
          "answerStatus",
          "answerScope"
        ],
        "type": "object"
      },
      "LimitsResponse": {
        "properties": {
          "concurrency": {
            "description": "How many calls may run at once. Two separate pools that do not borrow from each other. Exceeding one is a 429 concurrent_call_limit_reached, which is NOT solved by slowing down — you have to wait for calls to end.",
            "properties": {
              "agentCalls": {
                "description": "Calls running a Tone agent.",
                "properties": {
                  "inUse": {
                    "description": "Calls in flight right now. Rows older than 2h are not counted — a call the carrier never resolved must not eat quota.",
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  "limit": {
                    "description": "Your ceiling for this pool. Raised per-org by support.",
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  }
                },
                "required": [
                  "inUse",
                  "limit"
                ],
                "type": "object"
              },
              "byoCalls": {
                "description": "Calls bridged to your own media stack.",
                "properties": {
                  "inUse": {
                    "description": "Calls in flight right now. Rows older than 2h are not counted — a call the carrier never resolved must not eat quota.",
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  "limit": {
                    "description": "Your ceiling for this pool. Raised per-org by support.",
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  }
                },
                "required": [
                  "inUse",
                  "limit"
                ],
                "type": "object"
              }
            },
            "required": [
              "agentCalls",
              "byoCalls"
            ],
            "type": "object"
          },
          "environment": {
            "description": "Which environment these numbers describe — taken from the key you asked with. Live and test have separate budgets.",
            "enum": [
              "live",
              "test"
            ],
            "type": "string"
          },
          "requests": {
            "description": "Your request budget. Exceeding it is a 429 rate_limited with a Retry-After — slow down and retry.",
            "properties": {
              "limitPerMinute": {
                "description": "How many requests this organisation may make per minute in this environment.",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              "remaining": {
                "description": "Tokens left in the current window. The same figure the `RateLimit` response header carries.",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              }
            },
            "required": [
              "limitPerMinute",
              "remaining"
            ],
            "type": "object"
          }
        },
        "required": [
          "environment",
          "requests",
          "concurrency"
        ],
        "type": "object"
      },
      "NumberOfferResponse": {
        "properties": {
          "capabilities": {
            "description": "What the carrier says this number can carry.",
            "properties": {
              "sms": {
                "description": "Whether the carrier reports SMS capability. Reported for completeness — Tone does not send SMS.",
                "examples": [
                  false
                ],
                "type": "boolean"
              },
              "voice": {
                "description": "Whether this number can carry calls. Every number Tone sells can.",
                "examples": [
                  true
                ],
                "type": "boolean"
              }
            },
            "type": "object"
          },
          "e164": {
            "description": "The offered number, in E.164. Pass this to POST /v1/numbers/purchase.",
            "examples": [
              "+918045678901"
            ],
            "type": "string"
          },
          "numberType": {
            "description": "What kind of number this is. Open set.",
            "examples": [
              "landline"
            ],
            "type": "string"
          },
          "region": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Telecom circle the number belongs to.",
            "examples": [
              "KA"
            ]
          },
          "rentalPaise": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Monthly rental if you buy it, in paise. Charged again on each anniversary; non-payment suspends the number rather than releasing it."
          },
          "setupPaise": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "One-off provisioning charge if you buy it, in paise. Quoted from the carrier at search time; the server re-quotes on purchase."
          },
          "totalPaise": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Setup plus the first month — what buying this number costs today."
          }
        },
        "required": [
          "e164",
          "numberType",
          "region",
          "capabilities",
          "setupPaise",
          "rentalPaise",
          "totalPaise"
        ],
        "type": "object"
      },
      "NumberRegionResponse": {
        "properties": {
          "code": {
            "description": "The circle code to pass as the region search filter.",
            "examples": [
              "KA"
            ],
            "type": "string"
          },
          "label": {
            "description": "The circle name, for display.",
            "examples": [
              "Karnataka"
            ],
            "type": "string"
          }
        },
        "required": [
          "code",
          "label"
        ],
        "type": "object"
      },
      "NumberResponse": {
        "properties": {
          "agentId": {
            "anyOf": [
              {
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The agent that answers calls TO this number. Null on BYO numbers.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ]
          },
          "capabilities": {
            "description": "What the carrier says this number can carry.",
            "properties": {
              "sms": {
                "description": "Whether the carrier reports SMS capability. Reported for completeness — Tone does not send SMS.",
                "examples": [
                  false
                ],
                "type": "boolean"
              },
              "voice": {
                "description": "Whether this number can carry calls. Every number Tone sells can.",
                "examples": [
                  true
                ],
                "type": "boolean"
              }
            },
            "type": "object"
          },
          "createdAt": {
            "description": "When you bought this number, RFC 3339 UTC. Also the rental anniversary the monthly charge falls on.",
            "examples": [
              "2026-08-25T09:14:22Z"
            ],
            "type": "string"
          },
          "currency": {
            "description": "Currency for the amounts on this number. INR today.",
            "examples": [
              "INR"
            ],
            "type": "string"
          },
          "e164": {
            "description": "E.164, with the country code and a leading `+`.",
            "examples": [
              "+918045678901"
            ],
            "type": "string"
          },
          "environment": {
            "description": "`live` or `test`.",
            "examples": [
              "live"
            ],
            "type": "string"
          },
          "id": {
            "description": "The number's id. Use it on every route that addresses this number.",
            "examples": [
              "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43"
            ],
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "inbound": {
            "description": "Whether a call TO this number can actually be answered right now. `ready` — yes. `no_agent` — routed but nobody assigned. `no_endpoint` — a BYO number with no media endpoint. `unrouted` — no carrier flow, so nothing will ever arrive.",
            "enum": [
              "ready",
              "no_agent",
              "no_endpoint",
              "unrouted"
            ],
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your own name for it.",
            "examples": [
              "Support line — Bengaluru"
            ]
          },
          "mediaEndpoint": {
            "anyOf": [
              {
                "description": "Where a BYO number hands its media. Null on `tone_agent` numbers.",
                "properties": {
                  "authSecretId": {
                    "description": "Reference into your secret store. The credential itself is never returned here — it is decrypted only on the signed path that opens a call.",
                    "examples": [
                      "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b"
                    ],
                    "type": "string"
                  },
                  "customParameters": {
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Your own key/value pairs, echoed back on the media socket's `start` frame. Use them to correlate a call with your side without a lookup.",
                    "examples": [
                      {
                        "tenant": "acme"
                      }
                    ],
                    "propertyNames": {
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "format": {
                    "description": "Audio encoding on the media socket. `linear16` is 16-bit PCM at `sampleRate`; `mulaw8k` is 8kHz G.711 mu-law, for stacks written against Twilio Media Streams.",
                    "enum": [
                      "linear16",
                      "mulaw8k"
                    ],
                    "examples": [
                      "linear16"
                    ],
                    "type": "string"
                  },
                  "sampleRate": {
                    "anyOf": [
                      {
                        "const": 8000,
                        "type": "number"
                      },
                      {
                        "const": 16000,
                        "type": "number"
                      }
                    ],
                    "description": "Sample rate in Hz for `linear16`. Ignored for `mulaw8k`, which is 8000 by definition.",
                    "examples": [
                      16000
                    ]
                  },
                  "type": {
                    "description": "`static` sends every call to the same `url`. `webhook` asks your endpoint per call which socket to use, which is how you shard across sessions.",
                    "enum": [
                      "static",
                      "webhook"
                    ],
                    "examples": [
                      "static"
                    ],
                    "type": "string"
                  },
                  "url": {
                    "description": "Your WebSocket endpoint for `static`, or the HTTPS endpoint Tone asks for one for `webhook`. Must be publicly resolvable — private address space is refused at write time and again at connect time.",
                    "examples": [
                      "wss://media.acme.example/tone"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "url"
                ],
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where call audio goes when this number routes to your own stack. Null unless routingMode is byo_ws. The endpoint credential is referenced by id, never returned here."
          },
          "nextRentalAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the next month’s rental falls due. Null for sandbox numbers.",
            "examples": [
              "2026-09-01T06:30:00Z"
            ]
          },
          "numberType": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What kind of number this is. Open set — handle an unrecognised value rather than throwing. Today: `landline`, `mobile`, `tollfree`.",
            "examples": [
              "landline"
            ],
            "x-known-values": [
              "landline",
              "mobile",
              "tollfree"
            ]
          },
          "provider": {
            "description": "Which carrier operates it. Open set — handle an unrecognised value rather than throwing. Today: `exotel`, `vobiz`, `sandbox`.",
            "type": "string",
            "x-known-values": [
              "exotel",
              "vobiz",
              "sandbox"
            ]
          },
          "purchasedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the number was bought. RFC 3339, UTC.",
            "examples": [
              "2026-08-01T06:30:00Z"
            ]
          },
          "recordCalls": {
            "description": "Per-number recording switch. It can only turn recording OFF — it never enables it where the platform has it disabled.",
            "examples": [
              true
            ],
            "type": "boolean"
          },
          "region": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Telecom circle code, e.g. `KA`.",
            "examples": [
              "KA"
            ]
          },
          "releasedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the number was released back to the carrier. RFC 3339, UTC. Releasing is permanent — the number goes back into general inventory.",
            "examples": [
              null
            ]
          },
          "rentalPaise": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Monthly rental, in paise.",
            "examples": [
              50000
            ]
          },
          "routed": {
            "description": "Whether a carrier flow is attached, as far as our records go. For \"can this take a call?\", read `inbound` instead.",
            "examples": [
              true
            ],
            "type": "boolean"
          },
          "routingMode": {
            "description": "Who answers the media: a Tone agent, your own WebSocket endpoint, or your SIP platform. Open set — handle an unrecognised value rather than throwing. Today: `tone_agent`, `byo_ws`, `byo_sip`.",
            "type": "string",
            "x-known-values": [
              "tone_agent",
              "byo_ws",
              "byo_sip"
            ]
          },
          "series": {
            "description": "Numbering series. Open set — handle an unrecognised value rather than throwing. Today: `regular`, `140`, `160`.",
            "type": "string",
            "x-known-values": [
              "regular",
              "140",
              "160"
            ]
          },
          "setupPaise": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "One-off provisioning charge for this number, in paise.",
            "examples": [
              50000
            ]
          },
          "sipTrunk": {
            "anyOf": [
              {
                "description": "The SIP pair for a `byo_sip` number. Never the termination password — that is shown exactly once, at provisioning.",
                "properties": {
                  "credentialId": {
                    "description": "The carrier's id for the trunk credential, for support requests.",
                    "examples": [
                      "cred_5a1b"
                    ],
                    "type": "string"
                  },
                  "inboundTrunkId": {
                    "description": "The carrier's id for the inbound trunk.",
                    "examples": [
                      "tin_2c7d"
                    ],
                    "type": "string"
                  },
                  "originationSipUri": {
                    "description": "Where the carrier sends INBOUND calls — the URI on your SIP platform. Calls to this number arrive here.",
                    "examples": [
                      "sip:acme@sip.livekit.cloud"
                    ],
                    "type": "string"
                  },
                  "originationUriId": {
                    "description": "The carrier's id for the origination URI, for support requests.",
                    "examples": [
                      "ouri_9f2c"
                    ],
                    "type": "string"
                  },
                  "outboundTrunkId": {
                    "description": "The carrier's id for the outbound trunk.",
                    "examples": [
                      "tout_8e3f"
                    ],
                    "type": "string"
                  },
                  "provider": {
                    "description": "Which carrier operates this trunk.",
                    "examples": [
                      "vobiz"
                    ],
                    "type": "string"
                  },
                  "terminationDomain": {
                    "description": "Where YOU send outbound calls — point your platform's outbound trunk at this host.",
                    "examples": [
                      "acme.sip.vobiz.example"
                    ],
                    "type": "string"
                  },
                  "terminationRealm": {
                    "description": "The SIP realm, when the carrier requires one distinct from the domain.",
                    "examples": [
                      "vobiz.example"
                    ],
                    "type": "string"
                  },
                  "terminationUsername": {
                    "description": "The SIP username for outbound. 🔴 Its password is returned exactly once, at provisioning, and never again — store it then or re-provision.",
                    "examples": [
                      "acme-out"
                    ],
                    "type": "string"
                  },
                  "transport": {
                    "description": "SIP signalling transport. `tls` unless your platform cannot do it.",
                    "enum": [
                      "tls",
                      "tcp",
                      "udp"
                    ],
                    "examples": [
                      "tls"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "provider",
                  "originationSipUri",
                  "transport",
                  "originationUriId",
                  "credentialId",
                  "inboundTrunkId",
                  "outboundTrunkId",
                  "terminationDomain",
                  "terminationUsername"
                ],
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "The provisioned SIP trunk pair, when this number routes to your own SIP platform. The termination password is shown once at provisioning and never again."
          },
          "status": {
            "description": "Lifecycle. `suspended` still HOLDS the number — unpaid rent is not a release — and it returns to `active` automatically once the wallet covers what is owed. Open set — handle an unrecognised value rather than throwing. Today: `pending`, `active`, `released`, `failed`, `suspended`.",
            "type": "string",
            "x-known-values": [
              "pending",
              "active",
              "released",
              "failed",
              "suspended"
            ]
          }
        },
        "required": [
          "id",
          "e164",
          "label",
          "status",
          "environment",
          "series",
          "provider",
          "numberType",
          "region",
          "capabilities",
          "agentId",
          "routingMode",
          "mediaEndpoint",
          "nextRentalAt",
          "recordCalls",
          "sipTrunk",
          "setupPaise",
          "rentalPaise",
          "currency",
          "routed",
          "inbound",
          "purchasedAt",
          "releasedAt",
          "createdAt"
        ],
        "type": "object"
      },
      "OptOutDto": {
        "properties": {
          "e164": {
            "description": "The number that opted out, in E.164.",
            "examples": [
              "+919876543210"
            ],
            "pattern": "^\\+91\\d{10,11}$",
            "type": "string"
          },
          "reason": {
            "description": "Free text kept with both the revocation and the suppression entry.",
            "examples": [
              "Said \"do not call me again\" during the call."
            ],
            "maxLength": 500,
            "type": "string"
          }
        },
        "required": [
          "e164"
        ],
        "type": "object"
      },
      "OptOutResultResponse": {
        "properties": {
          "revoked": {
            "description": "Active consents revoked. The 90-day suppression is written in the same transaction, whatever this number is.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          }
        },
        "required": [
          "revoked"
        ],
        "type": "object"
      },
      "ProvisionSipDto": {
        "properties": {
          "sipUri": {
            "description": "Your voice platform SIP ingress, for example sip:agent@sip.example.com;transport=tls. The host must be publicly reachable.",
            "examples": [
              "sip:agent@sip.example.com;transport=tls"
            ],
            "maxLength": 300,
            "pattern": "^sips?:[^\\s@]+@[^\\s]+$",
            "type": "string"
          },
          "transport": {
            "default": "tls",
            "description": "Transport for the trunk. Leave it on tls unless your platform cannot terminate it.",
            "enum": [
              "tls",
              "tcp",
              "udp"
            ],
            "examples": [
              "tls"
            ],
            "type": "string"
          }
        },
        "required": [
          "sipUri"
        ],
        "type": "object"
      },
      "ProvisionedSipResponse": {
        "properties": {
          "number": {
            "description": "The number the trunk was provisioned for, as it now stands.",
            "properties": {
              "agentId": {
                "anyOf": [
                  {
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "The agent that answers calls TO this number. Null on BYO numbers.",
                "examples": [
                  "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                ]
              },
              "capabilities": {
                "description": "What the carrier says this number can carry.",
                "properties": {
                  "sms": {
                    "description": "Whether the carrier reports SMS capability. Reported for completeness — Tone does not send SMS.",
                    "examples": [
                      false
                    ],
                    "type": "boolean"
                  },
                  "voice": {
                    "description": "Whether this number can carry calls. Every number Tone sells can.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  }
                },
                "type": "object"
              },
              "createdAt": {
                "description": "When you bought this number, RFC 3339 UTC. Also the rental anniversary the monthly charge falls on.",
                "examples": [
                  "2026-08-25T09:14:22Z"
                ],
                "type": "string"
              },
              "currency": {
                "description": "Currency for the amounts on this number. INR today.",
                "examples": [
                  "INR"
                ],
                "type": "string"
              },
              "e164": {
                "description": "E.164, with the country code and a leading `+`.",
                "examples": [
                  "+918045678901"
                ],
                "type": "string"
              },
              "environment": {
                "description": "`live` or `test`.",
                "examples": [
                  "live"
                ],
                "type": "string"
              },
              "id": {
                "description": "The number's id. Use it on every route that addresses this number.",
                "examples": [
                  "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43"
                ],
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "type": "string"
              },
              "inbound": {
                "description": "Whether a call TO this number can actually be answered right now. `ready` — yes. `no_agent` — routed but nobody assigned. `no_endpoint` — a BYO number with no media endpoint. `unrouted` — no carrier flow, so nothing will ever arrive.",
                "enum": [
                  "ready",
                  "no_agent",
                  "no_endpoint",
                  "unrouted"
                ],
                "type": "string"
              },
              "label": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Your own name for it.",
                "examples": [
                  "Support line — Bengaluru"
                ]
              },
              "mediaEndpoint": {
                "anyOf": [
                  {
                    "description": "Where a BYO number hands its media. Null on `tone_agent` numbers.",
                    "properties": {
                      "authSecretId": {
                        "description": "Reference into your secret store. The credential itself is never returned here — it is decrypted only on the signed path that opens a call.",
                        "examples": [
                          "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b"
                        ],
                        "type": "string"
                      },
                      "customParameters": {
                        "additionalProperties": {
                          "type": "string"
                        },
                        "description": "Your own key/value pairs, echoed back on the media socket's `start` frame. Use them to correlate a call with your side without a lookup.",
                        "examples": [
                          {
                            "tenant": "acme"
                          }
                        ],
                        "propertyNames": {
                          "type": "string"
                        },
                        "type": "object"
                      },
                      "format": {
                        "description": "Audio encoding on the media socket. `linear16` is 16-bit PCM at `sampleRate`; `mulaw8k` is 8kHz G.711 mu-law, for stacks written against Twilio Media Streams.",
                        "enum": [
                          "linear16",
                          "mulaw8k"
                        ],
                        "examples": [
                          "linear16"
                        ],
                        "type": "string"
                      },
                      "sampleRate": {
                        "anyOf": [
                          {
                            "const": 8000,
                            "type": "number"
                          },
                          {
                            "const": 16000,
                            "type": "number"
                          }
                        ],
                        "description": "Sample rate in Hz for `linear16`. Ignored for `mulaw8k`, which is 8000 by definition.",
                        "examples": [
                          16000
                        ]
                      },
                      "type": {
                        "description": "`static` sends every call to the same `url`. `webhook` asks your endpoint per call which socket to use, which is how you shard across sessions.",
                        "enum": [
                          "static",
                          "webhook"
                        ],
                        "examples": [
                          "static"
                        ],
                        "type": "string"
                      },
                      "url": {
                        "description": "Your WebSocket endpoint for `static`, or the HTTPS endpoint Tone asks for one for `webhook`. Must be publicly resolvable — private address space is refused at write time and again at connect time.",
                        "examples": [
                          "wss://media.acme.example/tone"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "type",
                      "url"
                    ],
                    "type": "object"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Where call audio goes when this number routes to your own stack. Null unless routingMode is byo_ws. The endpoint credential is referenced by id, never returned here."
              },
              "nextRentalAt": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When the next month’s rental falls due. Null for sandbox numbers.",
                "examples": [
                  "2026-09-01T06:30:00Z"
                ]
              },
              "numberType": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "What kind of number this is. Open set — handle an unrecognised value rather than throwing. Today: `landline`, `mobile`, `tollfree`.",
                "examples": [
                  "landline"
                ],
                "x-known-values": [
                  "landline",
                  "mobile",
                  "tollfree"
                ]
              },
              "provider": {
                "description": "Which carrier operates it. Open set — handle an unrecognised value rather than throwing. Today: `exotel`, `vobiz`, `sandbox`.",
                "type": "string",
                "x-known-values": [
                  "exotel",
                  "vobiz",
                  "sandbox"
                ]
              },
              "purchasedAt": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When the number was bought. RFC 3339, UTC.",
                "examples": [
                  "2026-08-01T06:30:00Z"
                ]
              },
              "recordCalls": {
                "description": "Per-number recording switch. It can only turn recording OFF — it never enables it where the platform has it disabled.",
                "examples": [
                  true
                ],
                "type": "boolean"
              },
              "region": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Telecom circle code, e.g. `KA`.",
                "examples": [
                  "KA"
                ]
              },
              "releasedAt": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "When the number was released back to the carrier. RFC 3339, UTC. Releasing is permanent — the number goes back into general inventory.",
                "examples": [
                  null
                ]
              },
              "rentalPaise": {
                "anyOf": [
                  {
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Monthly rental, in paise.",
                "examples": [
                  50000
                ]
              },
              "routed": {
                "description": "Whether a carrier flow is attached, as far as our records go. For \"can this take a call?\", read `inbound` instead.",
                "examples": [
                  true
                ],
                "type": "boolean"
              },
              "routingMode": {
                "description": "Who answers the media: a Tone agent, your own WebSocket endpoint, or your SIP platform. Open set — handle an unrecognised value rather than throwing. Today: `tone_agent`, `byo_ws`, `byo_sip`.",
                "type": "string",
                "x-known-values": [
                  "tone_agent",
                  "byo_ws",
                  "byo_sip"
                ]
              },
              "series": {
                "description": "Numbering series. Open set — handle an unrecognised value rather than throwing. Today: `regular`, `140`, `160`.",
                "type": "string",
                "x-known-values": [
                  "regular",
                  "140",
                  "160"
                ]
              },
              "setupPaise": {
                "anyOf": [
                  {
                    "maximum": 9007199254740991,
                    "minimum": -9007199254740991,
                    "type": "integer"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "One-off provisioning charge for this number, in paise.",
                "examples": [
                  50000
                ]
              },
              "sipTrunk": {
                "anyOf": [
                  {
                    "description": "The SIP pair for a `byo_sip` number. Never the termination password — that is shown exactly once, at provisioning.",
                    "properties": {
                      "credentialId": {
                        "description": "The carrier's id for the trunk credential, for support requests.",
                        "examples": [
                          "cred_5a1b"
                        ],
                        "type": "string"
                      },
                      "inboundTrunkId": {
                        "description": "The carrier's id for the inbound trunk.",
                        "examples": [
                          "tin_2c7d"
                        ],
                        "type": "string"
                      },
                      "originationSipUri": {
                        "description": "Where the carrier sends INBOUND calls — the URI on your SIP platform. Calls to this number arrive here.",
                        "examples": [
                          "sip:acme@sip.livekit.cloud"
                        ],
                        "type": "string"
                      },
                      "originationUriId": {
                        "description": "The carrier's id for the origination URI, for support requests.",
                        "examples": [
                          "ouri_9f2c"
                        ],
                        "type": "string"
                      },
                      "outboundTrunkId": {
                        "description": "The carrier's id for the outbound trunk.",
                        "examples": [
                          "tout_8e3f"
                        ],
                        "type": "string"
                      },
                      "provider": {
                        "description": "Which carrier operates this trunk.",
                        "examples": [
                          "vobiz"
                        ],
                        "type": "string"
                      },
                      "terminationDomain": {
                        "description": "Where YOU send outbound calls — point your platform's outbound trunk at this host.",
                        "examples": [
                          "acme.sip.vobiz.example"
                        ],
                        "type": "string"
                      },
                      "terminationRealm": {
                        "description": "The SIP realm, when the carrier requires one distinct from the domain.",
                        "examples": [
                          "vobiz.example"
                        ],
                        "type": "string"
                      },
                      "terminationUsername": {
                        "description": "The SIP username for outbound. 🔴 Its password is returned exactly once, at provisioning, and never again — store it then or re-provision.",
                        "examples": [
                          "acme-out"
                        ],
                        "type": "string"
                      },
                      "transport": {
                        "description": "SIP signalling transport. `tls` unless your platform cannot do it.",
                        "enum": [
                          "tls",
                          "tcp",
                          "udp"
                        ],
                        "examples": [
                          "tls"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "provider",
                      "originationSipUri",
                      "transport",
                      "originationUriId",
                      "credentialId",
                      "inboundTrunkId",
                      "outboundTrunkId",
                      "terminationDomain",
                      "terminationUsername"
                    ],
                    "type": "object"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "The provisioned SIP trunk pair, when this number routes to your own SIP platform. The termination password is shown once at provisioning and never again."
              },
              "status": {
                "description": "Lifecycle. `suspended` still HOLDS the number — unpaid rent is not a release — and it returns to `active` automatically once the wallet covers what is owed. Open set — handle an unrecognised value rather than throwing. Today: `pending`, `active`, `released`, `failed`, `suspended`.",
                "type": "string",
                "x-known-values": [
                  "pending",
                  "active",
                  "released",
                  "failed",
                  "suspended"
                ]
              }
            },
            "required": [
              "id",
              "e164",
              "label",
              "status",
              "environment",
              "series",
              "provider",
              "numberType",
              "region",
              "capabilities",
              "agentId",
              "routingMode",
              "mediaEndpoint",
              "nextRentalAt",
              "recordCalls",
              "sipTrunk",
              "setupPaise",
              "rentalPaise",
              "currency",
              "routed",
              "inbound",
              "purchasedAt",
              "releasedAt",
              "createdAt"
            ],
            "type": "object"
          },
          "termination": {
            "description": "The credentials your voice platform authenticates with. The password appears in this response only — it is not stored in a readable form and cannot be fetched again.",
            "properties": {
              "domain": {
                "description": "The SIP domain to send traffic to.",
                "examples": [
                  "acme.sip.vobiz.example"
                ],
                "type": "string"
              },
              "password": {
                "description": "Shown exactly once — at provisioning. Store it now.",
                "examples": [
                  "K7x2QpL9vR4nT1cW"
                ],
                "type": "string"
              },
              "realm": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Authentication realm, when your platform needs it stated explicitly.",
                "examples": [
                  "vobiz.example"
                ]
              },
              "username": {
                "description": "The SIP username for this trunk.",
                "examples": [
                  "acme-out"
                ],
                "type": "string"
              }
            },
            "required": [
              "domain",
              "username",
              "password",
              "realm"
            ],
            "type": "object"
          }
        },
        "required": [
          "number",
          "termination"
        ],
        "type": "object"
      },
      "PurchaseEligibilityResponse": {
        "properties": {
          "balancePaise": {
            "description": "Current wallet balance. Compare it against an offer’s `totalPaise`.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "verified": {
            "description": "KYC and DLT registration are complete.",
            "type": "boolean"
          }
        },
        "required": [
          "verified",
          "balancePaise"
        ],
        "type": "object"
      },
      "PurchaseNumberDto": {
        "properties": {
          "agentId": {
            "description": "Bind the number to this agent on purchase, so inbound calls are answered immediately. You can set or change it later with PATCH /v1/numbers/{{id}}.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ],
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "e164": {
            "description": "The number to buy, in E.164. Must have come from a prior GET /v1/numbers/available result — carrier inventory is genuinely first-come, so a number can be taken between your search and your purchase, which is a 409 number_unavailable.",
            "examples": [
              "+918045678901"
            ],
            "pattern": "^\\+91\\d{10,11}$",
            "type": "string"
          },
          "label": {
            "description": "Your name for the number. Shown wherever the number appears; no effect on routing.",
            "examples": [
              "Support line — Bengaluru"
            ],
            "maxLength": 48,
            "minLength": 1,
            "pattern": "^[^\\p{C}]+$",
            "type": "string"
          }
        },
        "required": [
          "e164"
        ],
        "type": "object"
      },
      "RecordConsentDto": {
        "properties": {
          "capturedAt": {
            "description": "🔴 When the RECIPIENT consented — not when you called this endpoint. Defaults to now, which is correct only for a live capture: importing a back catalogue without this dates every record to the day of the import and makes the 7-day transactional clock meaningless.",
            "examples": [
              "2026-08-20T11:02:00Z"
            ],
            "type": "string"
          },
          "e164": {
            "description": "The number that consented, in E.164.",
            "examples": [
              "+919876543210"
            ],
            "pattern": "^\\+91\\d{10,11}$",
            "type": "string"
          },
          "evidenceRef": {
            "description": "Where the proof lives — a form submission id, a recording URL, a DCA reference. Tone stores the pointer, never the artefact.",
            "examples": [
              "form-sub-88213"
            ],
            "maxLength": 500,
            "type": "string"
          },
          "expiresAt": {
            "description": "When the consent lapses. Optional for `explicit` consent, where policy fills it — capped at seven days for a transactional purpose, otherwise until revoked. REQUIRED for `inferred` consent, which lasts exactly as long as the relationship, and only you know when that ends; omitting it there is a 422.",
            "examples": [
              "2026-08-27T11:02:00Z"
            ],
            "type": "string"
          },
          "kind": {
            "description": "How the consent arose. `explicit` is a positive act by the recipient; `inferred` rests on an existing relationship and MUST carry its own `expiresAt`. Open set — handle an unrecognised value rather than throwing. Today: `explicit`, `inferred`.",
            "enum": [
              "explicit",
              "inferred"
            ],
            "examples": [
              "explicit"
            ],
            "type": "string",
            "x-known-values": [
              "explicit",
              "inferred"
            ]
          },
          "purpose": {
            "description": "What they consented to be contacted about. Consent is purpose-scoped: a record for one purpose does not satisfy the gate for another. Open set — handle an unrecognised value rather than throwing. Today: `promotional`, `service`, `transactional`, `collections`.",
            "enum": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ],
            "examples": [
              "promotional"
            ],
            "type": "string",
            "x-known-values": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ]
          },
          "scope": {
            "description": "What the recipient actually agreed to, in their words or yours.",
            "examples": [
              "Order updates and delivery reminders for orders placed on acme.example."
            ],
            "maxLength": 1000,
            "type": "string"
          },
          "source": {
            "description": "Which channel captured it. Recorded verbatim and returned in the evidence pack. Open set — handle an unrecognised value rather than throwing. Today: `api`, `web_form`, `ivr`, `dtmf`, `otp`, `dca`, `import`.",
            "enum": [
              "api",
              "web_form",
              "ivr",
              "dtmf",
              "otp",
              "dca",
              "import"
            ],
            "examples": [
              "web_form"
            ],
            "type": "string",
            "x-known-values": [
              "api",
              "web_form",
              "ivr",
              "dtmf",
              "otp",
              "dca",
              "import"
            ]
          }
        },
        "required": [
          "e164",
          "purpose",
          "kind",
          "source"
        ],
        "type": "object"
      },
      "RevokeConsentDto": {
        "properties": {
          "reason": {
            "description": "Why the consent is being revoked. Kept on the record — revocation is a stamp, never a delete.",
            "examples": [
              "Recipient asked to be removed by email."
            ],
            "maxLength": 500,
            "type": "string"
          }
        },
        "type": "object"
      },
      "RollbackAgentDto": {
        "properties": {
          "version": {
            "description": "Which published version to restore. Rolling back MINTS A NEW VERSION carrying that content rather than moving a pointer, so the history stays append-only and the rollback itself is visible in it.",
            "examples": [
              3
            ],
            "maximum": 9007199254740991,
            "minimum": 1,
            "type": "integer"
          }
        },
        "required": [
          "version"
        ],
        "type": "object"
      },
      "RolledSecretResponse": {
        "properties": {
          "previousValidUntil": {
            "description": "When the old secret stops being sent alongside it — 24 hours out. RFC 3339, UTC.",
            "type": "string"
          },
          "secret": {
            "description": "The new secret. Start accepting it now.",
            "examples": [
              "whsec_8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f"
            ],
            "type": "string"
          }
        },
        "required": [
          "secret",
          "previousValidUntil"
        ],
        "type": "object"
      },
      "SearchKnowledgeDto": {
        "properties": {
          "answer": {
            "default": true,
            "description": "Also generate the answer a caller would hear. Defaults on; the passage list underneath is the debugging view. Turning it off skips the generation call entirely.",
            "examples": [
              true
            ],
            "type": "boolean"
          },
          "limit": {
            "default": 3,
            "description": "How many passages to return, 1-10.",
            "examples": [
              3
            ],
            "maximum": 10,
            "minimum": 1,
            "type": "integer"
          },
          "query": {
            "description": "What to search for, phrased as a caller would ask it. This runs the same retrieval a live turn runs, so the passages here are the passages the agent would get.",
            "examples": [
              "How long do I have to return an item?"
            ],
            "maxLength": 500,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "query"
        ],
        "type": "object"
      },
      "SetRoutingDto": {
        "properties": {
          "enabled": {
            "description": "Whether this number should accept inbound calls. Turning it off makes the number refuse inbound while keeping the number, its rental and its agent binding intact.",
            "examples": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "enabled"
        ],
        "type": "object"
      },
      "SigningSecretResponse": {
        "properties": {
          "note": {
            "description": "Which secret this is and what signs with it. Human-readable, not a code.",
            "examples": [
              "Signs every delivery to this endpoint as x-tone-signature."
            ],
            "type": "string"
          },
          "secret": {
            "description": "The signing secret, shown once. Verify x-tone-signature against it before trusting any delivery.",
            "examples": [
              "whsec_3f1a7f6e2b4c4d1e9a8b5c6d7e8f9a0b"
            ],
            "type": "string"
          }
        },
        "required": [
          "secret",
          "note"
        ],
        "type": "object"
      },
      "TransactionResponse": {
        "properties": {
          "amountPaise": {
            "description": "Signed: positive credited the wallet, negative spent from it.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "balanceAfterPaise": {
            "description": "The balance immediately after this entry — a statement’s closing column, which is what makes a disputed charge checkable. Derived server-side, never stored: the ledger is append-only, and deriving it client-side from the balance plus a page of rows goes wrong the moment a call bills between the two requests.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "createdAt": {
            "description": "RFC 3339, UTC.",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What this entry was for, in words.",
            "examples": [
              "Call to +919876543210 (45s)"
            ]
          },
          "entryType": {
            "description": "What moved the money. Open set — handle an unrecognised value rather than throwing. Today: `topup`, `topup_reversal`, `number_purchase`, `number_purchase_reversal`, `number_rental`, `call_usage`, `compliance_usage`, `adjustment`, `promo_credit`, `promo_credit_expiry`, `promo_credit_revocation`.",
            "type": "string",
            "x-known-values": [
              "topup",
              "topup_reversal",
              "number_purchase",
              "number_purchase_reversal",
              "number_rental",
              "call_usage",
              "compliance_usage",
              "adjustment",
              "promo_credit",
              "promo_credit_expiry",
              "promo_credit_revocation"
            ]
          },
          "id": {
            "description": "A decimal string, not a number — the underlying id is a bigint. Also the pagination cursor.",
            "examples": [
              "1043827"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "amountPaise",
          "entryType",
          "description",
          "balanceAfterPaise",
          "createdAt"
        ],
        "type": "object"
      },
      "UpdateAgentDto": {
        "properties": {
          "callSettings": {
            "additionalProperties": false,
            "description": "How the call RUNS rather than what it says: opening line, background ambience, what to do when the caller goes quiet, voicemail handling, the maximum call length and the farewell. A COMPLETE object; omitting the key leaves stored settings untouched. Custom lines are translated into the agent spoken languages automatically on save.",
            "properties": {
              "background": {
                "additionalProperties": false,
                "default": {},
                "description": "Ambient background audio for the call.",
                "examples": [
                  {
                    "sound": "none",
                    "volume": 0.3
                  }
                ],
                "properties": {
                  "sound": {
                    "default": "none",
                    "description": "An ambience bed played under the whole call, which makes a bot sound less like it is in a vacuum. Tone's own loops, not the voice vendor's. Open set — handle an unrecognised value rather than throwing. Today: `none`, `office`, `call_center`, `city_traffic`.",
                    "enum": [
                      "none",
                      "office",
                      "call_center",
                      "city_traffic"
                    ],
                    "examples": [
                      "none"
                    ],
                    "type": "string",
                    "x-known-values": [
                      "none",
                      "office",
                      "call_center",
                      "city_traffic"
                    ]
                  },
                  "volume": {
                    "default": 0.3,
                    "description": "How loud the bed sits under the speech, 0 to 1. Past about 0.4 it starts competing with the agent on a phone earpiece.",
                    "examples": [
                      0.3
                    ],
                    "maximum": 1,
                    "minimum": 0,
                    "type": "number"
                  }
                },
                "type": "object"
              },
              "hangupLine": {
                "additionalProperties": false,
                "default": {},
                "description": "What the agent says as it ends the call on its own — after the nudge ladder runs out, or when it decides the task is done.",
                "examples": [
                  {
                    "text": "Thanks for your time. Goodbye."
                  }
                ],
                "properties": {
                  "i18n": {
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Read-only. Tone's translations of `text` into the agent's other languages, keyed by language code. Accepted and IGNORED on write so you can PATCH an object straight back from a GET; translations are always recomputed server-side, so a client can never inject one.",
                    "examples": [
                      {
                        "hi-IN": "नमस्ते, मैं Acme से बात कर रहा हूँ।"
                      }
                    ],
                    "propertyNames": {
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "text": {
                    "anyOf": [
                      {
                        "maxLength": 300,
                        "pattern": "^[^\\p{C}]+$",
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The line, in the agent's first language — Tone translates it into the others. Send `null` or an empty string to restore Tone's built-in line for this slot: that is the only way to spell \"go back to the default\", and it is why clearing the field does not make the agent say nothing."
                  }
                },
                "type": "object"
              },
              "maxCallSeconds": {
                "anyOf": [
                  {
                    "maximum": 7200,
                    "minimum": 60,
                    "type": "integer"
                  },
                  {
                    "type": "null"
                  }
                ],
                "default": null,
                "description": "A hard ceiling on call length, in seconds, after which Tone hangs up. `null` means no agent-level cap. This can only ever LOWER the platform ceiling, never raise it. Worth setting on any agent that bills per minute.",
                "examples": [
                  600
                ]
              },
              "nudges": {
                "additionalProperties": false,
                "default": {},
                "description": "What the agent does when the caller goes quiet.",
                "examples": [
                  {
                    "enabled": true,
                    "hangupAfter": true,
                    "steps": [
                      {
                        "afterSeconds": 15,
                        "line": {
                          "text": null
                        }
                      }
                    ]
                  }
                ],
                "properties": {
                  "enabled": {
                    "default": true,
                    "description": "Whether the agent prompts a silent caller at all. Turning this off leaves the call in silence until the caller speaks or the cap is reached.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "hangupAfter": {
                    "default": true,
                    "description": "Whether to end the call once the last rung goes unanswered. Requires `enabled` — hanging up after nothing would mean never, which is not what the name promises, so the pairing is enforced.",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "steps": {
                    "description": "The ladder, in order, up to 5 rungs. Each rung's wait is measured from the previous one. At least one rung is required while `enabled` is true, because nudges on with no rungs is a switch that says the feature is on and never fires.",
                    "examples": [
                      [
                        {
                          "afterSeconds": 15,
                          "line": {
                            "text": null
                          }
                        }
                      ]
                    ],
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "afterSeconds": {
                          "description": "🔴 Seconds of CONTINUED silence since the previous rung — a gap, not an offset from the start of the call. Two rungs of 15 fire at 15s and 30s of quiet. Minimum 3s, so a ladder cannot machine-gun the caller.",
                          "examples": [
                            15
                          ],
                          "maximum": 300,
                          "minimum": 3,
                          "type": "integer"
                        },
                        "line": {
                          "additionalProperties": false,
                          "default": {},
                          "description": "What the agent says on this rung. Leave `text` null to use Tone's built-in localized nudge.",
                          "examples": [
                            {
                              "text": "Are you still there?"
                            }
                          ],
                          "properties": {
                            "i18n": {
                              "additionalProperties": {
                                "type": "string"
                              },
                              "description": "Read-only. Tone's translations of `text` into the agent's other languages, keyed by language code. Accepted and IGNORED on write so you can PATCH an object straight back from a GET; translations are always recomputed server-side, so a client can never inject one.",
                              "examples": [
                                {
                                  "hi-IN": "नमस्ते, मैं Acme से बात कर रहा हूँ।"
                                }
                              ],
                              "propertyNames": {
                                "type": "string"
                              },
                              "type": "object"
                            },
                            "text": {
                              "anyOf": [
                                {
                                  "maxLength": 300,
                                  "pattern": "^[^\\p{C}]+$",
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "The line, in the agent's first language — Tone translates it into the others. Send `null` or an empty string to restore Tone's built-in line for this slot: that is the only way to spell \"go back to the default\", and it is why clearing the field does not make the agent say nothing."
                            }
                          },
                          "type": "object"
                        }
                      },
                      "required": [
                        "afterSeconds"
                      ],
                      "type": "object"
                    },
                    "maxItems": 5,
                    "type": "array"
                  }
                },
                "type": "object"
              },
              "openingLine": {
                "additionalProperties": false,
                "default": {},
                "description": "What the agent says first, after Tone's fixed AI-and-recording disclosure. Unlike the other lines here it is substituted with the call's variables, so `{{customer_name}}` works. Leave `text` null and an outbound agent falls back to \"How can I help you today?\", which is the wrong opening for a call the customer did not place — set it.",
                "examples": [
                  {
                    "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                  }
                ],
                "properties": {
                  "i18n": {
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Read-only. Tone's translations of `text` into the agent's other languages, keyed by language code. Accepted and IGNORED on write so you can PATCH an object straight back from a GET; translations are always recomputed server-side, so a client can never inject one.",
                    "examples": [
                      {
                        "hi-IN": "नमस्ते, मैं Acme से बात कर रहा हूँ।"
                      }
                    ],
                    "propertyNames": {
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "text": {
                    "anyOf": [
                      {
                        "maxLength": 300,
                        "pattern": "^[^\\p{C}]+$",
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The line, in the agent's first language — Tone translates it into the others. Send `null` or an empty string to restore Tone's built-in line for this slot: that is the only way to spell \"go back to the default\", and it is why clearing the field does not make the agent say nothing."
                  }
                },
                "type": "object"
              },
              "voicemail": {
                "additionalProperties": false,
                "default": {},
                "description": "What happens when an answering machine picks up.",
                "examples": [
                  {
                    "enabled": true,
                    "windowSeconds": 30
                  }
                ],
                "properties": {
                  "enabled": {
                    "default": true,
                    "description": "Whether to leave `message` when an answering machine picks up. 🔴 Detection itself runs either way — an undetected mailbox is billed as an answered call and counted as a successful contact, so turning this off means \"hang up without speaking\", never \"do not check\".",
                    "examples": [
                      true
                    ],
                    "type": "boolean"
                  },
                  "message": {
                    "additionalProperties": false,
                    "default": {},
                    "description": "What to leave on the machine. Left only when `enabled` is true; the call ends either way.",
                    "examples": [
                      {
                        "text": "Hi, this is Acme calling about your order. We’ll try again later."
                      }
                    ],
                    "properties": {
                      "i18n": {
                        "additionalProperties": {
                          "type": "string"
                        },
                        "description": "Read-only. Tone's translations of `text` into the agent's other languages, keyed by language code. Accepted and IGNORED on write so you can PATCH an object straight back from a GET; translations are always recomputed server-side, so a client can never inject one.",
                        "examples": [
                          {
                            "hi-IN": "नमस्ते, मैं Acme से बात कर रहा हूँ।"
                          }
                        ],
                        "propertyNames": {
                          "type": "string"
                        },
                        "type": "object"
                      },
                      "text": {
                        "anyOf": [
                          {
                            "maxLength": 300,
                            "pattern": "^[^\\p{C}]+$",
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "The line, in the agent's first language — Tone translates it into the others. Send `null` or an empty string to restore Tone's built-in line for this slot: that is the only way to spell \"go back to the default\", and it is why clearing the field does not make the agent say nothing."
                      }
                    },
                    "type": "object"
                  },
                  "windowSeconds": {
                    "default": 30,
                    "description": "How long after the call connects detection stays armed. Past this window a long monologue is a talkative caller, not a machine, so the check stands down.",
                    "examples": [
                      30
                    ],
                    "maximum": 120,
                    "minimum": 5,
                    "type": "integer"
                  }
                },
                "type": "object"
              }
            },
            "type": "object"
          },
          "evaluationCriteria": {
            "description": "Questions a post-call judge answers about each call, returned as `evaluations` with a verdict and a rationale per criterion. A COMPLETE list, replacing what is stored.",
            "items": {
              "additionalProperties": false,
              "properties": {
                "id": {
                  "description": "🔴 The storage key for this criterion's verdicts, and IMMUTABLE once calls have been graded against it. Renaming it orphans every historical verdict — rename `name` instead, which exists for exactly that.",
                  "examples": [
                    "confirmed_order"
                  ],
                  "pattern": "^[a-z][a-z0-9_]{0,39}$",
                  "type": "string"
                },
                "name": {
                  "description": "The human label for this criterion, shown wherever verdicts are reported. Safe to rename at any time.",
                  "examples": [
                    "Confirmed the order"
                  ],
                  "maxLength": 80,
                  "minLength": 1,
                  "type": "string"
                },
                "prompt": {
                  "description": "The question the post-call judge answers about the transcript, handed to it verbatim. Write it so that \"yes\" is unambiguous.",
                  "examples": [
                    "Did the customer explicitly confirm they still want the order?"
                  ],
                  "maxLength": 1000,
                  "minLength": 1,
                  "type": "string"
                }
              },
              "required": [
                "id",
                "name",
                "prompt"
              ],
              "type": "object"
            },
            "maxItems": 10,
            "type": "array"
          },
          "inputVariables": {
            "description": "Placeholders the prompt can reference and a call can fill, each with a default used when a call supplies nothing. A COMPLETE list, replacing what is stored; an empty array clears it.",
            "items": {
              "additionalProperties": false,
              "properties": {
                "default": {
                  "default": "",
                  "description": "What to substitute when a call supplies no value. 🔴 Give every variable a literal fallback such as \"unknown\" — an empty default renders the prompt with a blank where a fact should be, and a model handed a blank invents one.",
                  "examples": [
                    "there"
                  ],
                  "maxLength": 500,
                  "type": "string"
                },
                "description": {
                  "description": "What this variable holds. For your own reference and the dashboard editor — it is not sent to the model.",
                  "examples": [
                    "The customer’s first name, as it appears on the order."
                  ],
                  "maxLength": 200,
                  "type": "string"
                },
                "name": {
                  "description": "The placeholder name, lowercase snake_case. Reference it in the system prompt or a spoken line as `{{name}}`, and supply its value per call.",
                  "examples": [
                    "customer_name"
                  ],
                  "pattern": "^[a-z][a-z0-9_]{0,39}$",
                  "type": "string"
                }
              },
              "required": [
                "name"
              ],
              "type": "object"
            },
            "maxItems": 25,
            "type": "array"
          },
          "knowledgeBaseIds": {
            "description": "Which knowledge bases this agent may answer from — the COMPLETE desired set, not a delta. Omitting the key leaves attachments untouched; sending an empty array detaches every base. A published version pins the SET OF IDS, not their contents, so re-indexing a base changes what past versions answer with.",
            "examples": [
              [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ]
            ],
            "items": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            },
            "maxItems": 50,
            "type": "array"
          },
          "llmModel": {
            "description": "Which language model the agent thinks on. The legal values come from GET /v1/catalog/voice and change without a deploy — treat this as an open set.",
            "examples": [
              "gemini-2.5-flash"
            ],
            "maxLength": 64,
            "minLength": 1,
            "type": "string"
          },
          "name": {
            "description": "Your name for the agent. Shown in the dashboard and on every call it runs.",
            "examples": [
              "Order confirmation"
            ],
            "maxLength": 48,
            "minLength": 1,
            "pattern": "^[^\\p{C}]+$",
            "type": "string"
          },
          "outputVariables": {
            "description": "Fields to extract from the transcript after each call, returned as `outputs` on the call record. Each field description IS the extraction instruction, so write it as you would tell a person what to look for. A COMPLETE list, replacing what is stored.",
            "items": {
              "additionalProperties": false,
              "properties": {
                "description": {
                  "description": "The extraction instruction, handed verbatim to the model that reads the transcript after the call. Required, because a bare field name extracts garbage — say what counts as an answer and what to do when the call never covered it.",
                  "examples": [
                    "Which day the customer agreed to take delivery. Leave empty if they did not commit to one."
                  ],
                  "maxLength": 500,
                  "minLength": 1,
                  "type": "string"
                },
                "enumValues": {
                  "description": "The allowed answers, 2-20 of them. Required when `type` is `enum` and rejected otherwise — the pairing is enforced, because values on a non-enum type would silently do nothing.",
                  "examples": [
                    [
                      "monday",
                      "tuesday",
                      "wednesday"
                    ]
                  ],
                  "items": {
                    "maxLength": 64,
                    "minLength": 1,
                    "type": "string"
                  },
                  "maxItems": 20,
                  "minItems": 2,
                  "type": "array"
                },
                "name": {
                  "description": "The key this value is stored under on the finished call, lowercase snake_case. Read it back from `outputs` on `GET /v1/calls/{id}`.",
                  "examples": [
                    "delivery_day"
                  ],
                  "pattern": "^[a-z][a-z0-9_]{0,39}$",
                  "type": "string"
                },
                "type": {
                  "description": "What kind of value to extract. `enum` clamps the answer to `enumValues`, which is what makes an outcome countable rather than free text. Open set — handle an unrecognised value rather than throwing. Today: `string`, `number`, `boolean`, `enum`.",
                  "enum": [
                    "string",
                    "number",
                    "boolean",
                    "enum"
                  ],
                  "examples": [
                    "enum"
                  ],
                  "type": "string",
                  "x-known-values": [
                    "string",
                    "number",
                    "boolean",
                    "enum"
                  ]
                }
              },
              "required": [
                "name",
                "type",
                "description"
              ],
              "type": "object"
            },
            "maxItems": 25,
            "type": "array"
          },
          "purpose": {
            "description": "🔴 The regulatory sender classification for every call this agent makes. Not cosmetic: it decides which calling window applies and whether consent is required. `promotional` and `collections` have hard time windows; `service` and `transactional` have none. Defaults to the strictest, `promotional`, and there is deliberately no per-call override. Open set — handle an unrecognised value rather than throwing. Today: `promotional`, `service`, `transactional`, `collections`.",
            "enum": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ],
            "examples": [
              "transactional"
            ],
            "type": "string",
            "x-known-values": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ]
          },
          "status": {
            "description": "Settable only on update — an agent is always created as a draft. A draft can be dialled outbound but will NOT answer inbound calls; publishing is what freezes the working copy into an immutable numbered version and points the agent at it. Open set — handle an unrecognised value rather than throwing. Today: `draft`, `live`.",
            "enum": [
              "draft",
              "live"
            ],
            "examples": [
              "live"
            ],
            "type": "string",
            "x-known-values": [
              "draft",
              "live"
            ]
          },
          "systemPrompt": {
            "description": "What the agent is trying to do, in your own words. Reference an input variable with double braces, for example {{{{customer_name}}}}. Keep it task-shaped: the platform already supplies conversational behaviour such as interruption handling and language matching.",
            "examples": [
              "You call customers to confirm a cash-on-delivery order. Confirm the order, ask which day suits them for delivery, then thank them and end the call. Be brief and polite."
            ],
            "maxLength": 20000,
            "minLength": 1,
            "type": "string"
          },
          "tools": {
            "description": "HTTP tools the agent may call mid-conversation, up to 10. Credentials are referenced from your stored secrets, never written inline. A COMPLETE list, replacing what is stored.",
            "items": {
              "additionalProperties": false,
              "properties": {
                "connectionId": {
                  "description": "Read-only provenance. Which integration connection installed this tool — used to answer \"which agents use this connection\" exactly, where matching on `preset` cannot (two connections to the same vendor are indistinguishable). Never reaches the running call.",
                  "examples": [
                    "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d"
                  ],
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "type": "string"
                },
                "description": {
                  "description": "🔴 WHEN the agent should call this tool — the single most important field on it. A vague line is the biggest cause of a tool misfiring, so at least 20 characters are required. Describe the trigger condition, not the implementation.",
                  "examples": [
                    "Call this once the customer has agreed to a specific delivery date and time window."
                  ],
                  "maxLength": 1000,
                  "minLength": 20,
                  "type": "string"
                },
                "http": {
                  "additionalProperties": false,
                  "description": "The request Tone makes when the agent calls this tool.",
                  "properties": {
                    "auth": {
                      "additionalProperties": false,
                      "description": "How Tone authenticates to your endpoint. Every credential is referenced by stored-secret id rather than typed in here, which is what keeps it out of every read of the agent.",
                      "properties": {
                        "header": {
                          "description": "Which header carries an `api_key` credential. Defaults to `x-api-key`. Applies only to `api_key`, and only when the credential goes in a header.",
                          "examples": [
                            "x-api-key"
                          ],
                          "pattern": "^[a-zA-Z0-9-]{1,64}$",
                          "type": "string"
                        },
                        "in": {
                          "description": "Where the credential goes. Defaults to `header`. 🔴 A `body` credential on a GET or DELETE is refused — those send no body, so it would be dropped and the endpoint would answer 401, which reads exactly like a revoked key.",
                          "enum": [
                            "header",
                            "query",
                            "body"
                          ],
                          "examples": [
                            "header"
                          ],
                          "type": "string"
                        },
                        "name": {
                          "description": "The query key or dotted body path the credential lands in. Required when `in` is not `header`.",
                          "examples": [
                            "api_key"
                          ],
                          "maxLength": 120,
                          "pattern": "^[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)*$",
                          "type": "string"
                        },
                        "secondary": {
                          "additionalProperties": false,
                          "description": "A second credential, for APIs that authenticate with a PAIR such as an access key plus a secret key. It carries no `type` because a pair is never two schemes — it is only ever \"put this value in this place\".",
                          "properties": {
                            "in": {
                              "description": "Where the second credential goes. Defaults to `header`, and every placement rule the primary has applies here too.",
                              "enum": [
                                "header",
                                "query",
                                "body"
                              ],
                              "examples": [
                                "header"
                              ],
                              "type": "string"
                            },
                            "name": {
                              "description": "The header name, query key or dotted body path for the second credential. Must not collide with the primary's slot — one would silently overwrite the other.",
                              "examples": [
                                "x-acme-secret"
                              ],
                              "maxLength": 120,
                              "pattern": "^[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)*$",
                              "type": "string"
                            },
                            "secretId": {
                              "description": "The second stored secret. Must differ from the primary — the same id twice sends one value under two names, and the rejection that follows says nothing about which half was wrong.",
                              "examples": [
                                "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                              ],
                              "format": "uuid",
                              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                              "type": "string"
                            }
                          },
                          "required": [
                            "secretId",
                            "name"
                          ],
                          "type": "object"
                        },
                        "secretId": {
                          "description": "The stored secret holding the credential value. 🔴 A REFERENCE, never the credential itself — the value is decrypted only when a call runs, so it never rides a dashboard read of the agent. Create one in the dashboard under Secrets.",
                          "examples": [
                            "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b"
                          ],
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                          "type": "string"
                        },
                        "type": {
                          "description": "The scheme. `bearer` and `basic` are header schemes by definition and cannot be placed elsewhere; only `api_key` may move.",
                          "enum": [
                            "bearer",
                            "api_key",
                            "basic"
                          ],
                          "examples": [
                            "bearer"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "type",
                        "secretId"
                      ],
                      "type": "object"
                    },
                    "bodyFormat": {
                      "description": "How the body is encoded. `json` by default; `form` sends `application/x-www-form-urlencoded`, which is FLAT — a dotted parameter path cannot be encoded into it and is refused.",
                      "enum": [
                        "json",
                        "form"
                      ],
                      "examples": [
                        "json"
                      ],
                      "type": "string"
                    },
                    "bodyRoot": {
                      "description": "Whether the request body is a JSON object (default) or an array. 🔴 With `array`, every parameter path must start with an index such as `0.email` — a named key set on an array is dropped silently when the body is serialised, and your API then reports a missing required field.",
                      "enum": [
                        "object",
                        "array"
                      ],
                      "examples": [
                        "object"
                      ],
                      "type": "string"
                    },
                    "headers": {
                      "additionalProperties": {
                        "maxLength": 1024,
                        "type": "string"
                      },
                      "description": "Static headers sent with every call, up to 16. 🔴 Credentials do not go here — `authorization` is refused outright, as are platform-owned headers and anything `x-tone-*`. Use `auth`, which keeps the secret out of every agent read.",
                      "examples": [
                        {
                          "x-acme-source": "tone"
                        }
                      ],
                      "propertyNames": {
                        "pattern": "^[a-zA-Z0-9-]{1,64}$",
                        "type": "string"
                      },
                      "type": "object"
                    },
                    "method": {
                      "description": "The HTTP method. GET and DELETE send no body, so parameters default to the query string.",
                      "enum": [
                        "GET",
                        "POST",
                        "PUT",
                        "PATCH",
                        "DELETE"
                      ],
                      "examples": [
                        "POST"
                      ],
                      "type": "string"
                    },
                    "timeoutMs": {
                      "description": "How long to wait for your endpoint before giving up, in milliseconds (1000-30000). Remember the caller is waiting in silence — keep it short enough that the agent can say something before it becomes an awkward pause.",
                      "examples": [
                        5000
                      ],
                      "maximum": 30000,
                      "minimum": 1000,
                      "type": "integer"
                    },
                    "url": {
                      "description": "The endpoint Tone calls. Checked at save time — a URL pointing at private address space, loopback or a cloud metadata endpoint is refused here rather than discovered mid-call, and the check re-runs against the resolved address at execution. Must be `https` if the tool sends credentials.",
                      "examples": [
                        "https://api.acme.example/v1/deliveries"
                      ],
                      "maxLength": 2048,
                      "minLength": 1,
                      "type": "string"
                    }
                  },
                  "required": [
                    "url",
                    "method"
                  ],
                  "type": "object"
                },
                "mock": {
                  "additionalProperties": false,
                  "description": "Return a fixed response instead of calling the endpoint, so the conversation can be tested before the integration is live.",
                  "properties": {
                    "enabled": {
                      "description": "While true, Tone returns `response` instead of calling your endpoint. Use it to rehearse the conversation before the API exists.",
                      "examples": [
                        true
                      ],
                      "type": "boolean"
                    },
                    "response": {
                      "description": "The canned reply handed to the model in place of a real response. Shape it like the real thing — the model reads it the same way.",
                      "examples": [
                        "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                      ],
                      "maxLength": 6000,
                      "type": "string"
                    }
                  },
                  "required": [
                    "enabled",
                    "response"
                  ],
                  "type": "object"
                },
                "name": {
                  "description": "What the model calls this tool, lowercase snake_case. Must be unique on the agent and cannot shadow a built-in name such as `end_call` or `query_knowledge`.",
                  "examples": [
                    "book_delivery_slot"
                  ],
                  "pattern": "^[a-z][a-z0-9_]{1,39}$",
                  "type": "string"
                },
                "parameters": {
                  "description": "What the agent collects before calling, up to 16. Names must be unique within the tool.",
                  "examples": [
                    [
                      {
                        "description": "The agreed date as YYYY-MM-DD.",
                        "name": "delivery_date",
                        "required": true,
                        "type": "string"
                      }
                    ]
                  ],
                  "items": {
                    "additionalProperties": false,
                    "properties": {
                      "description": {
                        "description": "What this parameter holds, in the model's terms. Required unless the parameter is pinned with `value` — a parameter the model fills with no description collects garbage.",
                        "examples": [
                          "The delivery date the customer agreed to, as YYYY-MM-DD."
                        ],
                        "maxLength": 500,
                        "type": "string"
                      },
                      "enum": {
                        "description": "Clamp the model's answer to this list, 2-24 values. String parameters only, and mutually exclusive with `value`.",
                        "examples": [
                          [
                            "morning",
                            "afternoon"
                          ]
                        ],
                        "items": {
                          "maxLength": 64,
                          "minLength": 1,
                          "type": "string"
                        },
                        "maxItems": 24,
                        "minItems": 2,
                        "type": "array"
                      },
                      "in": {
                        "description": "Where the value goes on the wire. Defaults to the method's natural place — query for GET and DELETE, body for the rest. Use `path` to substitute a `{placeholder}` in the URL.",
                        "enum": [
                          "query",
                          "body",
                          "path"
                        ],
                        "examples": [
                          "body"
                        ],
                        "type": "string"
                      },
                      "name": {
                        "description": "The parameter name the model fills in, lowercase snake_case. Also the wire name unless `path` overrides it.",
                        "examples": [
                          "delivery_date"
                        ],
                        "pattern": "^[a-z][a-z0-9_]{0,39}$",
                        "type": "string"
                      },
                      "path": {
                        "description": "The wire name, when it differs from `name`: a query key, a path placeholder, or a dotted location inside the body such as `attendee.email`. Dots nest only inside a JSON body — on a query key they would be sent literally, so that combination is rejected.",
                        "examples": [
                          "attendee.email"
                        ],
                        "maxLength": 120,
                        "pattern": "^[a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+)*$",
                        "type": "string"
                      },
                      "required": {
                        "description": "Whether the model must supply this before the tool can run.",
                        "examples": [
                          true
                        ],
                        "type": "boolean"
                      },
                      "type": {
                        "description": "What kind of value the model must produce.",
                        "enum": [
                          "string",
                          "number",
                          "integer",
                          "boolean"
                        ],
                        "examples": [
                          "string"
                        ],
                        "type": "string"
                      },
                      "value": {
                        "description": "Pin the parameter to a fixed value, injected at call time and INVISIBLE to the model. This is how a tenant id or an account key reaches your API without the model being able to see or change it.",
                        "examples": [
                          "acme-prod"
                        ],
                        "maxLength": 500,
                        "type": "string"
                      }
                    },
                    "required": [
                      "name",
                      "type"
                    ],
                    "type": "object"
                  },
                  "maxItems": 16,
                  "type": "array"
                },
                "preset": {
                  "description": "Read-only provenance. Names the integration preset that installed this tool, if any. Round-trips unchanged so renaming a preset-installed tool does not strip it.",
                  "examples": [
                    "cal.com/book"
                  ],
                  "maxLength": 64,
                  "type": "string"
                },
                "speech": {
                  "additionalProperties": {
                    "maxLength": 200,
                    "minLength": 1,
                    "type": "string"
                  },
                  "description": "What the agent says out loud while it waits for your endpoint, keyed by language code (`hi-IN`, `en-IN`). Without it the caller hears silence for the length of `timeoutMs`, which on a phone call reads as a dropped line. Up to 16 languages.",
                  "examples": [
                    {
                      "en-IN": "Let me check that for you.",
                      "hi-IN": "मैं अभी देखता हूँ।"
                    }
                  ],
                  "propertyNames": {
                    "pattern": "^[a-z]{2,3}-[A-Z]{2}$",
                    "type": "string"
                  },
                  "type": "object"
                }
              },
              "required": [
                "name",
                "description",
                "http"
              ],
              "type": "object"
            },
            "maxItems": 10,
            "type": "array"
          },
          "voice": {
            "additionalProperties": false,
            "description": "The speech stack: which model transcribes, which speaks, in which voice, and which languages the agent handles. 🔴 The (ttsModel, ttsVoice) pair is a constraint, not two independent choices — a voice belongs to one model version and the wrong pairing is rejected at write time rather than becoming a failure mid-call. Read the valid combinations from GET /v1/catalog/voice.",
            "properties": {
              "languages": {
                "description": "Every language this agent is allowed to speak, most-preferred first. Also the clamp on auto-detection: the transcriber understands about twice as many languages as the speaking model can speak, so a detection outside this list falls back to the first entry instead of producing a reply the voice cannot say. An empty list means \"no opinion\" — adopt whatever is detected.",
                "examples": [
                  [
                    "hi-IN",
                    "en-IN"
                  ]
                ],
                "items": {
                  "maxLength": 64,
                  "minLength": 1,
                  "type": "string"
                },
                "maxItems": 32,
                "type": "array"
              },
              "sttLanguage": {
                "description": "The language to expect from the caller, or `auto` to detect it per utterance. Auto-detection is clamped to `languages`, so a detection outside that list falls back to the first entry rather than opening a socket the speaking model would reject.",
                "examples": [
                  "auto"
                ],
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              },
              "sttMode": {
                "description": "How the transcriber treats the caller's language. `transcribe` writes what was said in the language it was said in; `translate` renders it into English. Values come from the catalog.",
                "examples": [
                  "transcribe"
                ],
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              },
              "sttModel": {
                "description": "Which model transcribes the caller. Read the legal values from `GET /v1/catalog/voice` — they change without a deploy.",
                "examples": [
                  "saaras:v3"
                ],
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              },
              "ttsModel": {
                "description": "Which model speaks. 🔴 Half of a constraint: a voice belongs to one model version, so changing this can invalidate the `ttsVoice` already on the agent — send both together when you switch.",
                "examples": [
                  "bulbul:v3"
                ],
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              },
              "ttsOptions": {
                "additionalProperties": {
                  "type": "number"
                },
                "description": "Model-specific voice tuning, as a map of option name to number. Which options exist depends on the speaking model — v3 dropped `pitch` and `loudness` and added `temperature`. `GET /v1/catalog/voice` lists each model's options with their ranges; an option the chosen model does not take is rejected.",
                "examples": [
                  {
                    "pace": 1
                  }
                ],
                "propertyNames": {
                  "maxLength": 32,
                  "type": "string"
                },
                "type": "object"
              },
              "ttsVoice": {
                "description": "Which voice speaks. 🔴 Valid only for its own `ttsModel` — `simran` is a v3 voice and is rejected on v2, `anushka` is the reverse. The pair is checked at write time so it cannot fail mid-call.",
                "examples": [
                  "simran"
                ],
                "maxLength": 64,
                "minLength": 1,
                "type": "string"
              }
            },
            "type": "object"
          }
        },
        "type": "object"
      },
      "UpdateCampaignDto": {
        "properties": {
          "autoPauseBelowPaise": {
            "description": "Wallet floor in paise. When the balance falls below it the campaign pauses itself with pausedReason low_balance and emits campaign.paused, instead of dialling until calls start failing mid-conversation. Resume it after topping up.",
            "examples": [
              50000
            ],
            "maximum": 9007199254740991,
            "minimum": 0,
            "type": "integer"
          },
          "callsPerMinute": {
            "description": "How fast to dial, 1-60. The ceiling is the carrier's own campaign throttle, and bursts from a single caller ID are the pattern TCCCPR's spam rubric watches for — if you need more throughput, use more numbers rather than a higher rate.",
            "examples": [
              10
            ],
            "maximum": 60,
            "minimum": 1,
            "type": "integer"
          },
          "endsAt": {
            "description": "Stop dialling at this instant even if recipients remain. Must be later than `startsAt`.",
            "examples": [
              "2026-09-07T14:00:00Z"
            ],
            "type": "string"
          },
          "maxConcurrent": {
            "description": "How many calls may be in flight at once, 1-20. 🔴 This does **not** queue above your organisation's concurrency quota — recipients dialled over it are refused and settle as `failed`. Check `GET /v1/limits` and keep this at or below what it reports.",
            "examples": [
              4
            ],
            "maximum": 20,
            "minimum": 1,
            "type": "integer"
          },
          "name": {
            "description": "Your label for the campaign. Shown in the dashboard and on every call it places.",
            "examples": [
              "COD confirmations — September"
            ],
            "maxLength": 120,
            "minLength": 1,
            "type": "string"
          },
          "numberId": {
            "description": "The number to dial from. Must route to a Tone agent — a campaign on a BYO number is refused at launch rather than failing per call.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ],
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "retryAttempts": {
            "description": "How many times to redial a recipient whose outcome is in `retryOn`. 0-3; 0 disables retries.",
            "examples": [
              1
            ],
            "maximum": 3,
            "minimum": 0,
            "type": "integer"
          },
          "retryBackoff": {
            "description": "How the wait grows between successive retries. Open set — handle an unrecognised value rather than throwing. Today: `linear`, `exponential`.",
            "enum": [
              "linear",
              "exponential"
            ],
            "examples": [
              "fixed"
            ],
            "type": "string",
            "x-known-values": [
              "linear",
              "exponential"
            ]
          },
          "retryIntervalMinutes": {
            "description": "Minutes to wait before the first retry, 5-1440.",
            "examples": [
              60
            ],
            "maximum": 1440,
            "minimum": 5,
            "type": "integer"
          },
          "retryOn": {
            "description": "Which outcomes earn a retry. 🔴 `answered` is deliberately not accepted — redialling someone who already spoke to the agent is what turns a campaign into a complaint, and under TCCCPR five complaints in ten days bars every number your organisation owns.",
            "examples": [
              [
                "no_answer",
                "busy"
              ]
            ],
            "items": {
              "enum": [
                "no_answer",
                "busy",
                "failed",
                "voicemail"
              ],
              "type": "string"
            },
            "maxItems": 4,
            "type": "array"
          },
          "startsAt": {
            "description": "Do not dial before this instant. Omit to start as soon as the campaign is launched.",
            "examples": [
              "2026-09-01T04:00:00Z"
            ],
            "type": "string"
          },
          "weekdays": {
            "description": "Which weekdays may dial, as a 7-bit mask with **Monday = bit 0** (`0b0011111` = 31 = Mon-Fri, 127 = every day). `0` is refused: a campaign with no enabled weekday can never dial, and accepting it would leave it `running` and silently idle.",
            "examples": [
              31
            ],
            "maximum": 127,
            "minimum": 1,
            "type": "integer"
          },
          "windowEndMinute": {
            "description": "Latest minute of the day this campaign may dial, as minutes past midnight IST (1260 = 21:00). 1440 is accepted so a window can run to midnight. Must be later than `windowStartMinute`, and the **retry tail has to fit inside it too** — a schedule whose retries would land outside the window is refused at launch.",
            "examples": [
              1260
            ],
            "maximum": 1440,
            "minimum": 0,
            "type": "integer"
          },
          "windowStartMinute": {
            "description": "Earliest minute of the day this campaign may dial, as **minutes past midnight IST** (540 = 09:00). Narrower than the legal band, never wider: the compliance gate still applies and will block a call this window would have allowed.",
            "examples": [
              540
            ],
            "maximum": 1439,
            "minimum": 0,
            "type": "integer"
          }
        },
        "type": "object"
      },
      "UpdateKnowledgeBaseDto": {
        "properties": {
          "agentIds": {
            "description": "The complete set of agents this base should be attached to — a replacement, not a diff. Send the full list every time; omitting the key leaves attachments untouched, and sending an empty array detaches it from everything.",
            "examples": [
              [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ]
            ],
            "items": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            },
            "maxItems": 50,
            "type": "array"
          },
          "description": {
            "description": "What this base covers. For your own reference; the agent does not read it.",
            "examples": [
              "Delivery timelines, COD rules and the returns window."
            ],
            "maxLength": 280,
            "type": "string"
          },
          "name": {
            "description": "Your name for the knowledge base.",
            "examples": [
              "Shipping and returns policy"
            ],
            "maxLength": 64,
            "minLength": 1,
            "pattern": "^[^\\p{C}]+$",
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdateNumberDto": {
        "properties": {
          "agentId": {
            "anyOf": [
              {
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which agent answers inbound calls on this number. Send null to unbind. Kept, not cleared, when you switch to a BYO routing mode — it is simply ignored while BYO, and switching back restores the binding.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ]
          },
          "label": {
            "anyOf": [
              {
                "maxLength": 48,
                "minLength": 1,
                "pattern": "^[^\\p{C}]+$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your name for the number. Send null to clear it; omit the key to leave it alone.",
            "examples": [
              "Support line — Bengaluru"
            ]
          },
          "mediaEndpoint": {
            "anyOf": [
              {
                "additionalProperties": false,
                "properties": {
                  "authSecretId": {
                    "description": "Reference to a stored secret sent as the endpoint credential. A reference, never an inline value — this object rides dashboard reads, and a secret in it would be readable there.",
                    "examples": [
                      "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                    ],
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "type": "string"
                  },
                  "customParameters": {
                    "additionalProperties": {
                      "maxLength": 256,
                      "type": "string"
                    },
                    "description": "Static values delivered to your endpoint in the start frame. Merged with per-call variables and the identity facts for the call, later winning.",
                    "examples": [
                      {
                        "tenant": "acme"
                      }
                    ],
                    "propertyNames": {
                      "maxLength": 64,
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "format": {
                    "description": "Audio encoding on the media socket. Defaults to linear16; mulaw8k exists for stacks built against Twilio-shaped mulaw streams.",
                    "enum": [
                      "linear16",
                      "mulaw8k"
                    ],
                    "examples": [
                      "linear16"
                    ],
                    "type": "string"
                  },
                  "sampleRate": {
                    "anyOf": [
                      {
                        "const": 8000,
                        "type": "number"
                      },
                      {
                        "const": 16000,
                        "type": "number"
                      }
                    ],
                    "description": "Sample rate in Hz, 8000 or 16000. Defaults to 16000.",
                    "examples": [
                      16000
                    ]
                  },
                  "type": {
                    "description": "static names one wss:// URL used for every call, with the call id appended as a query parameter. webhook names an https:// URL fetched per call that answers with the wss:// to use, which is how you route calls to different backends.",
                    "enum": [
                      "static",
                      "webhook"
                    ],
                    "examples": [
                      "static"
                    ],
                    "type": "string"
                  },
                  "url": {
                    "description": "The endpoint. wss:// for a static endpoint, https:// for a webhook one. Must be publicly reachable.",
                    "examples": [
                      "wss://media.example.com/tone"
                    ],
                    "maxLength": 600,
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "url"
                ],
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where to send call audio when routingMode is byo_ws. Ignored in tone_agent mode and live again on the switch. Must be publicly reachable — private address space is refused here and again at connect time after DNS resolution."
          },
          "recordCalls": {
            "description": "Record calls on this number. Defaults on. This can only turn recording OFF: it is combined with the deployment-level recording setting, so it can never enable recording where the platform has it disabled.",
            "examples": [
              true
            ],
            "type": "boolean"
          },
          "routingMode": {
            "description": "Who answers this number. `tone_agent` runs a Tone agent; `byo_ws` bridges the audio to your own WebSocket stack and bills the telephony-plus-platform rate; `byo_sip` reserves the number for a SIP trunk and is NOT dialable through POST /v1/calls. Switching modes never reprices past calls — each call snapshots its own mode. Open set — handle an unrecognised value rather than throwing. Today: `tone_agent`, `byo_ws`, `byo_sip`.",
            "enum": [
              "tone_agent",
              "byo_ws",
              "byo_sip"
            ],
            "examples": [
              "tone_agent"
            ],
            "type": "string",
            "x-known-values": [
              "tone_agent",
              "byo_ws",
              "byo_sip"
            ]
          }
        },
        "type": "object"
      },
      "UpdateWebhookEndpointDto": {
        "properties": {
          "description": {
            "description": "Your label for this endpoint. Shown in the delivery log.",
            "examples": [
              "Production CRM sync"
            ],
            "maxLength": 120,
            "type": "string"
          },
          "enabled": {
            "description": "Whether deliveries are sent. Disable to stop delivery without losing the endpoint, its secret or its history.",
            "examples": [
              true
            ],
            "type": "boolean"
          },
          "events": {
            "default": [
              "call.completed"
            ],
            "description": "Which events to send to this endpoint. Subscribe only to what you consume — every delivery is retried up to 14 times over roughly a day, and 20 consecutive failures across all deliveries disables the endpoint. Open set — handle an unrecognised value rather than throwing. Today: `call.initiated`, `call.answered`, `call.completed`, `call.failed`, `campaign.completed`, `campaign.paused`, `compliance.check.blocked`, `wallet.balance.low`, `number.suspended`, `number.reactivated`, `knowledge.build.completed`, `knowledge.build.failed`.",
            "examples": [
              [
                "call.completed",
                "call.failed"
              ]
            ],
            "items": {
              "enum": [
                "call.initiated",
                "call.answered",
                "call.completed",
                "call.failed",
                "campaign.completed",
                "campaign.paused",
                "compliance.check.blocked",
                "wallet.balance.low",
                "number.suspended",
                "number.reactivated",
                "knowledge.build.completed",
                "knowledge.build.failed"
              ],
              "type": "string"
            },
            "minItems": 1,
            "type": "array",
            "x-known-values": [
              "call.initiated",
              "call.answered",
              "call.completed",
              "call.failed",
              "campaign.completed",
              "campaign.paused",
              "compliance.check.blocked",
              "wallet.balance.low",
              "number.suspended",
              "number.reactivated",
              "knowledge.build.completed",
              "knowledge.build.failed"
            ]
          },
          "url": {
            "description": "Where to POST deliveries. Must be a public https:// URL — private and link-local addresses are refused at save time rather than discovered at delivery time. Answer 2xx within 10 seconds; anything slower is retried and will manufacture duplicates.",
            "examples": [
              "https://hooks.example.com/tone"
            ],
            "format": "uri",
            "maxLength": 2048,
            "type": "string"
          }
        },
        "type": "object"
      },
      "UploadTargetResponse": {
        "properties": {
          "documentId": {
            "description": "Already reserved. Pass it to the confirm call once the upload succeeds.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "expiresInSeconds": {
            "description": "How long the presigned upload URL stays valid. Upload before it lapses, then call the confirm endpoint.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "headers": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Send these verbatim on the PUT — the signature covers them.",
            "propertyNames": {
              "type": "string"
            },
            "type": "object"
          },
          "url": {
            "description": "PUT the file here. A short-lived signed URL — upload before it expires, then confirm.",
            "examples": [
              "https://uploads.usetone.ai/kb/9f1c2d84…?signature=…"
            ],
            "type": "string"
          }
        },
        "required": [
          "documentId",
          "url",
          "headers",
          "expiresInSeconds"
        ],
        "type": "object"
      },
      "VoiceCatalogResponse": {
        "properties": {
          "defaultAgentLanguages": {
            "description": "The language list a new agent starts with.",
            "examples": [
              [
                "en-IN",
                "hi-IN"
              ]
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "fetchedAt": {
            "description": "When the underlying document was last fetched successfully. RFC 3339, UTC.",
            "examples": [
              "2026-08-25T04:00:00Z"
            ],
            "type": "string"
          },
          "languageNames": {
            "additionalProperties": {
              "properties": {
                "english": {
                  "description": "The language name in English.",
                  "examples": [
                    "Hindi"
                  ],
                  "type": "string"
                },
                "native": {
                  "description": "The language name in its own script.",
                  "examples": [
                    "हिन्दी"
                  ],
                  "type": "string"
                }
              },
              "required": [
                "english",
                "native"
              ],
              "type": "object"
            },
            "description": "Display names per language code, for building a picker.",
            "propertyNames": {
              "type": "string"
            },
            "type": "object"
          },
          "llm": {
            "description": "What an agent can think on.",
            "properties": {
              "defaults": {
                "description": "What a new agent gets when it names no model.",
                "properties": {
                  "model": {
                    "description": "The default language model id.",
                    "examples": [
                      "gemini-2.5-flash"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "model"
                ],
                "type": "object"
              },
              "models": {
                "description": "Every language model an agent may be set to.",
                "items": {
                  "properties": {
                    "deprecated": {
                      "description": "Sarvam no longer lists this. Still accepted on save; hide it from new pickers.",
                      "type": "boolean"
                    },
                    "description": {
                      "description": "One line on what this is and when to choose it, written for the person picking.",
                      "examples": [
                        "Latest speech model. Adds `temperature`; drops `pitch` and `loudness`."
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "The value to send when selecting this language model.",
                      "examples": [
                        "gemini-2.5-flash"
                      ],
                      "type": "string"
                    },
                    "label": {
                      "description": "Human-readable name, for a picker.",
                      "examples": [
                        "Bulbul v3"
                      ],
                      "type": "string"
                    },
                    "provider": {
                      "description": "Who serves this model. Open set — handle an unrecognised value rather than throwing. Today: `gemini`, `sarvam`.",
                      "type": "string",
                      "x-known-values": [
                        "gemini",
                        "sarvam"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "label",
                    "description",
                    "provider"
                  ],
                  "type": "object"
                },
                "type": "array"
              }
            },
            "required": [
              "models",
              "defaults"
            ],
            "type": "object"
          },
          "previewSamples": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "The sentence each voice preview speaks, in native script.",
            "propertyNames": {
              "type": "string"
            },
            "type": "object"
          },
          "source": {
            "description": "`spec` — parsed from Sarvam’s published document. `seed` — the built-in floor, served before the first successful fetch or when the document is unreachable. Open set — handle an unrecognised value rather than throwing. Today: `spec`, `seed`.",
            "type": "string",
            "x-known-values": [
              "spec",
              "seed"
            ]
          },
          "stt": {
            "description": "What an agent can listen with.",
            "properties": {
              "autoDetect": {
                "description": "The language code that means \"detect it\". Understood far wider than TTS can speak.",
                "examples": [
                  "auto"
                ],
                "type": "string"
              },
              "defaults": {
                "description": "What a new agent gets when it names no transcription settings.",
                "properties": {
                  "language": {
                    "description": "The default language code, usually the auto-detect value.",
                    "examples": [
                      "auto"
                    ],
                    "type": "string"
                  },
                  "mode": {
                    "description": "The default mode id.",
                    "examples": [
                      "transcribe"
                    ],
                    "type": "string"
                  },
                  "model": {
                    "description": "The default transcription model id.",
                    "examples": [
                      "saaras:v3"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "model",
                  "mode",
                  "language"
                ],
                "type": "object"
              },
              "languages": {
                "description": "Language codes the transcriber understands. Wider than the set text-to-speech can speak, which is why a detected language is clamped to the agent own language list before a reply is synthesised.",
                "examples": [
                  [
                    "en-IN",
                    "hi-IN",
                    "gu-IN",
                    "ta-IN"
                  ]
                ],
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "models": {
                "description": "Every transcription model an agent may be set to.",
                "items": {
                  "properties": {
                    "deprecated": {
                      "description": "Sarvam no longer lists this. Still accepted on save; hide it from new pickers.",
                      "type": "boolean"
                    },
                    "description": {
                      "description": "One line on what this is and when to choose it, written for the person picking.",
                      "examples": [
                        "Latest speech model. Adds `temperature`; drops `pitch` and `loudness`."
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "The value to send when selecting this transcription model.",
                      "examples": [
                        "saaras:v3"
                      ],
                      "type": "string"
                    },
                    "label": {
                      "description": "Human-readable name, for a picker.",
                      "examples": [
                        "Bulbul v3"
                      ],
                      "type": "string"
                    },
                    "supportsModes": {
                      "description": "`mode` is a Saaras v3+ parameter — saarika rejects it outright.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "label",
                    "description",
                    "supportsModes"
                  ],
                  "type": "object"
                },
                "type": "array"
              },
              "modes": {
                "description": "How the transcriber handles language — transcribing faithfully versus translating.",
                "items": {
                  "properties": {
                    "description": {
                      "description": "What this does to the text the model sees. Not cosmetic — the wrong mode silently invalidates a prompt written for a different transcript shape.",
                      "examples": [
                        "Transcribes faithfully in the language spoken, without translating."
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "The value to send when selecting this mode.",
                      "examples": [
                        "transcribe"
                      ],
                      "type": "string"
                    },
                    "label": {
                      "description": "Human-readable name, for a picker.",
                      "examples": [
                        "Bulbul v3"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "label",
                    "description"
                  ],
                  "type": "object"
                },
                "type": "array"
              }
            },
            "required": [
              "models",
              "modes",
              "languages",
              "autoDetect",
              "defaults"
            ],
            "type": "object"
          },
          "tts": {
            "description": "What an agent can speak with.",
            "properties": {
              "defaults": {
                "description": "What a new agent gets when it names no voice.",
                "properties": {
                  "model": {
                    "description": "The default speech model id.",
                    "examples": [
                      "bulbul:v3"
                    ],
                    "type": "string"
                  },
                  "speaker": {
                    "description": "The default voice id, valid for the default model.",
                    "examples": [
                      "anushka"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "model",
                  "speaker"
                ],
                "type": "object"
              },
              "languages": {
                "description": "Language codes the speech models can speak.",
                "examples": [
                  [
                    "en-IN",
                    "hi-IN",
                    "gu-IN"
                  ]
                ],
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "models": {
                "description": "Every speech model an agent may be set to.",
                "items": {
                  "properties": {
                    "deprecated": {
                      "description": "Sarvam no longer lists this. Still accepted on save; hide it from new pickers.",
                      "type": "boolean"
                    },
                    "description": {
                      "description": "One line on what this is and when to choose it, written for the person picking.",
                      "examples": [
                        "Latest speech model. Adds `temperature`; drops `pitch` and `loudness`."
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "The value to send when selecting this speech model.",
                      "examples": [
                        "bulbul:v3"
                      ],
                      "type": "string"
                    },
                    "label": {
                      "description": "Human-readable name, for a picker.",
                      "examples": [
                        "Bulbul v3"
                      ],
                      "type": "string"
                    },
                    "options": {
                      "description": "Tuning knobs THIS model accepts — model-specific and mutually exclusive. v3 dropped `pitch`/`loudness` and added `temperature`; sending a key the model does not know is a 400 mid-call.",
                      "items": {
                        "properties": {
                          "default": {
                            "description": "What the model uses when the option is not set.",
                            "examples": [
                              1
                            ],
                            "type": "number"
                          },
                          "description": {
                            "description": "One line on what this is and when to choose it, written for the person picking.",
                            "examples": [
                              "Latest speech model. Adds `temperature`; drops `pitch` and `loudness`."
                            ],
                            "type": "string"
                          },
                          "key": {
                            "description": "The option name, as a key of `voice.ttsOptions` on an agent.",
                            "examples": [
                              "pace"
                            ],
                            "type": "string"
                          },
                          "label": {
                            "description": "Human-readable name, for a picker.",
                            "examples": [
                              "Bulbul v3"
                            ],
                            "type": "string"
                          },
                          "max": {
                            "description": "Highest accepted value. 🔴 Trust this over any vendor prose — Sarvam documents `temperature` up to 2.0 and the API rejects anything above 1.0, so this catalog carries the corrected ceiling.",
                            "examples": [
                              2
                            ],
                            "type": "number"
                          },
                          "min": {
                            "description": "Lowest accepted value.",
                            "examples": [
                              0.5
                            ],
                            "type": "number"
                          },
                          "step": {
                            "description": "Granularity, for rendering a slider.",
                            "examples": [
                              0.1
                            ],
                            "type": "number"
                          }
                        },
                        "required": [
                          "key",
                          "label",
                          "description",
                          "min",
                          "max",
                          "default",
                          "step"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "id",
                    "label",
                    "description",
                    "options"
                  ],
                  "type": "object"
                },
                "type": "array"
              },
              "sampleRates": {
                "description": "Output sample rates in Hz.",
                "examples": [
                  [
                    8000,
                    16000,
                    22050
                  ]
                ],
                "items": {
                  "maximum": 9007199254740991,
                  "minimum": -9007199254740991,
                  "type": "integer"
                },
                "type": "array"
              },
              "speakers": {
                "description": "Every voice, each naming the model it belongs to. 🔴 The (model, speaker) pair is the constraint, not the name — a voice from one model version is rejected on another, at write time rather than mid-call.",
                "items": {
                  "properties": {
                    "deprecated": {
                      "description": "Sarvam no longer lists this. Still accepted on save; hide it from new pickers.",
                      "type": "boolean"
                    },
                    "gender": {
                      "description": "The voice's apparent gender, for building a picker. Open set — handle an unrecognised value rather than throwing. Today: `female`, `male`, `unknown`.",
                      "examples": [
                        "female"
                      ],
                      "type": "string",
                      "x-known-values": [
                        "female",
                        "male",
                        "unknown"
                      ]
                    },
                    "id": {
                      "description": "The value to send when selecting this voice.",
                      "examples": [
                        "simran"
                      ],
                      "type": "string"
                    },
                    "label": {
                      "description": "Human-readable name, for a picker.",
                      "examples": [
                        "Bulbul v3"
                      ],
                      "type": "string"
                    },
                    "models": {
                      "description": "Which TTS models accept this voice — almost never both. The `(model, speaker)` PAIR is the constraint, not the name: a v3 voice is a hard 400 on v2.",
                      "examples": [
                        [
                          "bulbul:v3"
                        ]
                      ],
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "id",
                    "label",
                    "gender",
                    "models"
                  ],
                  "type": "object"
                },
                "type": "array"
              }
            },
            "required": [
              "models",
              "speakers",
              "languages",
              "sampleRates",
              "defaults"
            ],
            "type": "object"
          },
          "version": {
            "description": "Content hash of everything below. Also the ETag, and the first segment of every voice-preview URL — so a catalog change mints new preview URLs instead of serving stale audio from an immutable cache.",
            "examples": [
              "c7f2a9e1b4d6"
            ],
            "type": "string"
          }
        },
        "required": [
          "version",
          "source",
          "fetchedAt",
          "llm",
          "stt",
          "tts",
          "languageNames",
          "defaultAgentLanguages",
          "previewSamples"
        ],
        "type": "object"
      },
      "WalletResponse": {
        "properties": {
          "balancePaise": {
            "description": "Prepaid balance in paise. Can go negative — a call in flight is billed at its end.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "currency": {
            "const": "INR",
            "description": "Always INR. Tone bills Indian telephony in rupees.",
            "examples": [
              "INR"
            ],
            "type": "string"
          },
          "estimatedMinutesRemaining": {
            "description": "Whole minutes the balance covers at the rate above. An estimate for display, not a quota.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "lowBalanceThresholdPaise": {
            "description": "Where \"running low\" starts for this org — the same number the `wallet.balance.low` webhook fires on, so your alerting and ours agree.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "ratePaisePerMinute": {
            "description": "The org’s effective per-minute rate — the negotiated rate where one exists, list otherwise. A BYO call bills the component subset instead, so this does not describe every call.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          }
        },
        "required": [
          "balancePaise",
          "currency",
          "ratePaisePerMinute",
          "estimatedMinutesRemaining",
          "lowBalanceThresholdPaise"
        ],
        "type": "object"
      },
      "WalletUsageResponse": {
        "properties": {
          "addedPaise": {
            "description": "Top-ups net of refunds over the same window, for context beside the spend.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "agentId": {
            "anyOf": [
              {
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Echo of the filter. When set, only `calls` is narrowed — rentals, adjustments and top-ups do not belong to an agent, so those report zero rather than pretending an org-wide figure is agent-specific."
          },
          "categories": {
            "description": "Always one row per category, zeroes included, so a rendered breakdown never reflows.",
            "items": {
              "properties": {
                "category": {
                  "description": "Which kind of spend this row totals. Open set — handle an unrecognised value rather than throwing. Today: `calls`, `numbers`, `compliance`, `adjustments`.",
                  "examples": [
                    "calls"
                  ],
                  "type": "string",
                  "x-known-values": [
                    "calls",
                    "numbers",
                    "compliance",
                    "adjustments"
                  ]
                },
                "entries": {
                  "description": "Ledger entries behind the figure, so a row can say \"42 calls\".",
                  "maximum": 9007199254740991,
                  "minimum": -9007199254740991,
                  "type": "integer"
                },
                "spentPaise": {
                  "description": "Net spend as a POSITIVE figure. Negative only if refunds outweighed spend.",
                  "maximum": 9007199254740991,
                  "minimum": -9007199254740991,
                  "type": "integer"
                }
              },
              "required": [
                "category",
                "spentPaise",
                "entries"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "from": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Start of the window this breakdown covers. RFC 3339, UTC. Null for `all` — there is no start date."
          },
          "period": {
            "description": "The window this breakdown covers, echoing the period you asked for.",
            "enum": [
              "7d",
              "30d",
              "all"
            ],
            "type": "string"
          },
          "to": {
            "description": "The end of the window this breakdown covers. RFC 3339, UTC.",
            "type": "string"
          },
          "totalSpentPaise": {
            "description": "Sum of the categories below. Positive means money left the wallet.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          }
        },
        "required": [
          "period",
          "agentId",
          "from",
          "to",
          "totalSpentPaise",
          "addedPaise",
          "categories"
        ],
        "type": "object"
      },
      "WebhookDeliveryResponse": {
        "properties": {
          "attempts": {
            "description": "How many times delivery has been tried. Up to 14 over roughly a day before we stop.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "callId": {
            "anyOf": [
              {
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The subject when it is a call. Null for every other subject; prefer `subjectId`."
          },
          "createdAt": {
            "description": "When the delivery was first attempted. RFC 3339, UTC.",
            "type": "string"
          },
          "deliveredAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When your endpoint answered 2xx. RFC 3339, UTC. Null while the delivery is still pending or has exhausted its retries."
          },
          "endpointId": {
            "description": "Which endpoint this delivery was sent to.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "eventType": {
            "description": "Open set — handle an unrecognised value rather than throwing. Today: `call.initiated`, `call.answered`, `call.completed`, `call.failed`, `campaign.completed`, `campaign.paused`, `compliance.check.blocked`, `wallet.balance.low`, `number.suspended`, `number.reactivated`, `knowledge.build.completed`, `knowledge.build.failed`.",
            "type": "string",
            "x-known-values": [
              "call.initiated",
              "call.answered",
              "call.completed",
              "call.failed",
              "campaign.completed",
              "campaign.paused",
              "compliance.check.blocked",
              "wallet.balance.low",
              "number.suspended",
              "number.reactivated",
              "knowledge.build.completed",
              "knowledge.build.failed"
            ]
          },
          "id": {
            "description": "Also the event id — `x-tone-event-id` on the wire.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "lastError": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A classification of the failure — deliberately never your server’s response body.",
            "examples": [
              "connection_timeout"
            ]
          },
          "lastStatus": {
            "anyOf": [
              {
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The HTTP status your endpoint last answered with. Null if it never responded."
          },
          "status": {
            "description": "Open set — handle an unrecognised value rather than throwing. Today: `pending`, `delivered`, `failed`.",
            "type": "string",
            "x-known-values": [
              "pending",
              "delivered",
              "failed"
            ]
          },
          "subjectId": {
            "description": "The id of the resource the event was about — a call id, a campaign id, and so on.",
            "examples": [
              "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
            ],
            "type": "string"
          },
          "subjectType": {
            "description": "What the event is about: `call`, `campaign`, `number`, …",
            "examples": [
              "call"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "callId",
          "subjectType",
          "subjectId",
          "endpointId",
          "eventType",
          "status",
          "attempts",
          "lastStatus",
          "lastError",
          "createdAt",
          "deliveredAt"
        ],
        "type": "object"
      },
      "WebhookEndpointResponse": {
        "properties": {
          "consecutiveFailures": {
            "description": "Resets to 0 on the first success.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "createdAt": {
            "description": "RFC 3339, UTC.",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Your label for this endpoint.",
            "examples": [
              "Production — order service"
            ]
          },
          "disabledReason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why we switched it off, when we did — never silent, and the owners are emailed. Sustained failures disable an endpoint after the retry ladder is exhausted.",
            "examples": [
              null
            ]
          },
          "enabled": {
            "description": "Whether deliveries are being sent. Set false by you, or automatically after 20 consecutive delivery failures.",
            "type": "boolean"
          },
          "events": {
            "description": "Which events this endpoint receives. Open set — handle an unrecognised value rather than throwing. Today: `call.initiated`, `call.answered`, `call.completed`, `call.failed`, `campaign.completed`, `campaign.paused`, `compliance.check.blocked`, `wallet.balance.low`, `number.suspended`, `number.reactivated`, `knowledge.build.completed`, `knowledge.build.failed`.",
            "examples": [
              [
                "call.completed",
                "campaign.finished"
              ]
            ],
            "items": {
              "type": "string"
            },
            "type": "array",
            "x-known-values": [
              "call.initiated",
              "call.answered",
              "call.completed",
              "call.failed",
              "campaign.completed",
              "campaign.paused",
              "compliance.check.blocked",
              "wallet.balance.low",
              "number.suspended",
              "number.reactivated",
              "knowledge.build.completed",
              "knowledge.build.failed"
            ]
          },
          "id": {
            "description": "The webhook endpoint's unique id.",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "type": "string"
          },
          "url": {
            "description": "Where deliveries are POSTed. Vetted at save time — a private-range URL is refused by the form, not discovered at delivery.",
            "examples": [
              "https://hooks.acme.example/tone"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "url",
          "description",
          "events",
          "enabled",
          "disabledReason",
          "consecutiveFailures",
          "createdAt"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "apiKey": {
        "bearerFormat": "JWT",
        "description": "`Authorization: Bearer tone_live_…` or `tone_test_…`. The prefix IS the environment: a test key reaches only the sandbox, and no request field bridges the two.",
        "scheme": "bearer",
        "type": "http"
      },
      "session": {
        "description": "Dashboard session cookie. Present only on routes deliberately closed to API keys (minting credentials, funding the wallet, changing compliance enforcement).",
        "in": "cookie",
        "name": "tone.session",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "contact": {
      "email": "hello@usetone.ai",
      "name": "Tone support",
      "url": "https://usetone.ai"
    },
    "description": "The +91 phone-number API for AI agents.\n\n`/v1` is a promise, not a version number: changes are additive only. New endpoints,\nnew optional request fields, new response fields and new enum members can appear at any\ntime and are NOT breaking. Nothing you receive today is removed, renamed or retyped.\n\n**Treat every enum as open.** Fields documented with `x-known-values` list what exists\ntoday, not what can ever arrive — handle an unrecognised value instead of throwing.\n\nSuccessful responses are wrapped in `{ data, meta? }`. Failures replace it with\n`{ error }` — branch on `error.code`, never on `error.message`.",
    "termsOfService": "https://usetone.ai/terms",
    "title": "Tone API",
    "version": "1.0.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/health": {
      "get": {
        "description": "Touches no dependencies and never fails while the process can answer. Unversioned and un-enveloped on purpose, so a load balancer gets a stable, standard contract. Use it for restart decisions, not for traffic decisions.",
        "operationId": "health.liveness",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [],
        "summary": "Liveness — is the process up?",
        "tags": [
          "health"
        ],
        "x-tone-audience": "public",
        "x-tone-scopes": []
      }
    },
    "/health/ready": {
      "get": {
        "description": "Checks Postgres. Answers `503` when a dependency is down, which is the signal to stop sending this instance traffic without restarting it. Cache status rides along in the payload but never fails the probe — it is an optimisation, not a dependency. Queue depths ride along the same way: the API only ever produces, so a broker outage defers work rather than breaking a request. The process that cannot run without a broker is `tone-worker`, which refuses to boot instead of reporting here.",
        "operationId": "health.readiness",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "details": {
                    "database": {
                      "status": "up"
                    }
                  },
                  "error": {},
                  "info": {
                    "database": {
                      "status": "up"
                    }
                  },
                  "status": "ok"
                },
                "schema": {
                  "properties": {
                    "details": {
                      "additionalProperties": {
                        "additionalProperties": true,
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "status"
                        ],
                        "type": "object"
                      },
                      "examples": [
                        {
                          "database": {
                            "status": "up"
                          }
                        }
                      ],
                      "type": "object"
                    },
                    "error": {
                      "additionalProperties": {
                        "additionalProperties": true,
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "status"
                        ],
                        "type": "object"
                      },
                      "examples": [
                        {}
                      ],
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "info": {
                      "additionalProperties": {
                        "additionalProperties": true,
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "status"
                        ],
                        "type": "object"
                      },
                      "examples": [
                        {
                          "database": {
                            "status": "up"
                          }
                        }
                      ],
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "status": {
                      "examples": [
                        "ok"
                      ],
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The Health Check is successful"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "details": {
                      "additionalProperties": {
                        "additionalProperties": true,
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "status"
                        ],
                        "type": "object"
                      },
                      "examples": [
                        {
                          "database": {
                            "status": "up"
                          },
                          "redis": {
                            "message": "Could not connect",
                            "status": "down"
                          }
                        }
                      ],
                      "type": "object"
                    },
                    "error": {
                      "additionalProperties": {
                        "additionalProperties": true,
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "status"
                        ],
                        "type": "object"
                      },
                      "examples": [
                        {
                          "redis": {
                            "message": "Could not connect",
                            "status": "down"
                          }
                        }
                      ],
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "info": {
                      "additionalProperties": {
                        "additionalProperties": true,
                        "properties": {
                          "status": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "status"
                        ],
                        "type": "object"
                      },
                      "examples": [
                        {
                          "database": {
                            "status": "up"
                          }
                        }
                      ],
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "status": {
                      "examples": [
                        "error"
                      ],
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The Health Check is not successful"
          }
        },
        "security": [],
        "summary": "Readiness — are dependencies reachable?",
        "tags": [
          "health"
        ],
        "x-tone-audience": "public",
        "x-tone-scopes": []
      }
    },
    "/v1": {
      "get": {
        "description": "A cheap, unauthenticated way to confirm you are pointed at the right host and to read back the API version. Not a health check — use `/health` for that.",
        "operationId": "meta.info",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": null
                },
                "schema": {
                  "properties": {
                    "data": {
                      "description": "The resource, or an array of them on a list endpoint. Null for endpoints that return no body."
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": ""
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [],
        "summary": "API root — service metadata",
        "tags": [
          "meta"
        ],
        "x-tone-audience": "public",
        "x-tone-scopes": []
      }
    },
    "/v1/agents": {
      "get": {
        "description": "Every agent, live and draft. Small enough that it is not paginated.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "agents.list",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "callSettings": {
                        "background": {
                          "sound": "none",
                          "volume": 0.3
                        },
                        "hangupLine": {
                          "text": "Thanks for your time. Goodbye."
                        },
                        "maxCallSeconds": 600,
                        "nudges": {
                          "enabled": true,
                          "hangupAfter": true,
                          "steps": [
                            {
                              "afterSeconds": 15,
                              "line": {
                                "text": null
                              }
                            }
                          ]
                        },
                        "openingLine": {
                          "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                        },
                        "voicemail": {
                          "enabled": true,
                          "windowSeconds": 30
                        }
                      },
                      "createdAt": "2026-08-25T09:14:22Z",
                      "evaluationCriteria": [
                        {
                          "id": "confirmed_order",
                          "name": "Confirmed the order",
                          "prompt": "Did the customer explicitly confirm they still want the order?"
                        }
                      ],
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "inputVariables": [
                        {
                          "default": "there",
                          "description": "The customer’s first name, as it appears on the order.",
                          "name": "customer_name"
                        }
                      ],
                      "knowledgeBaseIds": [
                        "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                      ],
                      "languages": [
                        "hi-IN",
                        "en-IN"
                      ],
                      "llmProvider": "google",
                      "name": "Order confirmation",
                      "outputVariables": [
                        {
                          "description": "Which day the customer agreed to take delivery. Leave empty if they did not commit to one.",
                          "enumValues": [
                            "monday",
                            "tuesday",
                            "wednesday"
                          ],
                          "name": "delivery_day",
                          "type": "enum"
                        }
                      ],
                      "purpose": "promotional",
                      "status": "draft",
                      "sttLanguage": "auto",
                      "sttMode": "transcribe",
                      "sttModel": "saaras:v3",
                      "sttProvider": "sarvam",
                      "systemPrompt": "You call customers to confirm a cash-on-delivery order…",
                      "tools": [
                        {
                          "connectionId": "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d",
                          "description": "Call this once the customer has agreed to a specific delivery date and time window.",
                          "http": {
                            "auth": {
                              "header": "x-api-key",
                              "in": "header",
                              "name": "api_key",
                              "secondary": {
                                "in": "header",
                                "name": "x-acme-secret",
                                "secretId": "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                              },
                              "secretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                              "type": "bearer"
                            },
                            "bodyFormat": "json",
                            "bodyRoot": "object",
                            "headers": {
                              "x-acme-source": "tone"
                            },
                            "method": "POST",
                            "timeoutMs": 5000,
                            "url": "https://api.acme.example/v1/deliveries"
                          },
                          "mock": {
                            "enabled": true,
                            "response": "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                          },
                          "name": "book_delivery_slot",
                          "parameters": [
                            {
                              "description": "The agreed date as YYYY-MM-DD.",
                              "name": "delivery_date",
                              "required": true,
                              "type": "string"
                            }
                          ],
                          "preset": "cal.com/book",
                          "speech": {
                            "en-IN": "Let me check that for you.",
                            "hi-IN": "मैं अभी देखता हूँ।"
                          }
                        }
                      ],
                      "ttsModel": "bulbul:v3",
                      "ttsOptions": {
                        "pace": 1
                      },
                      "ttsProvider": "sarvam",
                      "ttsVoice": "simran",
                      "updatedAt": "2026-08-25T09:14:22Z"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/AgentResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "List the organization’s agents",
        "tags": [
          "agents"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      },
      "post": {
        "description": "A new agent is always a draft, whatever you send: a draft can be dialled outbound but will NOT answer inbound calls, so publishing is the deliberate step that puts it on a phone line. The `(ttsModel, ttsVoice)` pair is validated here — a voice belonging to a different model version is rejected now rather than failing mid-call.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "agents.create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "callSettings": {
                  "background": {
                    "sound": "none",
                    "volume": 0.3
                  },
                  "hangupLine": {
                    "text": "Thanks for your time. Goodbye."
                  },
                  "maxCallSeconds": 600,
                  "nudges": {
                    "enabled": true,
                    "hangupAfter": true,
                    "steps": [
                      {
                        "afterSeconds": 15,
                        "line": {
                          "text": null
                        }
                      }
                    ]
                  },
                  "openingLine": {
                    "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                  },
                  "voicemail": {
                    "enabled": true,
                    "windowSeconds": 30
                  }
                },
                "evaluationCriteria": [
                  {
                    "id": "confirmed_order",
                    "name": "Confirmed the order",
                    "prompt": "Did the customer explicitly confirm they still want the order?"
                  }
                ],
                "inputVariables": [
                  {
                    "default": "there",
                    "description": "The customer’s first name, as it appears on the order.",
                    "name": "customer_name"
                  }
                ],
                "knowledgeBaseIds": [
                  "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                ],
                "llmModel": "gemini-2.5-flash",
                "name": "Order confirmation",
                "outputVariables": [
                  {
                    "description": "Which day the customer agreed to take delivery. Leave empty if they did not commit to one.",
                    "enumValues": [
                      "monday",
                      "tuesday",
                      "wednesday"
                    ],
                    "name": "delivery_day",
                    "type": "enum"
                  }
                ],
                "purpose": "transactional",
                "systemPrompt": "You call customers to confirm a cash-on-delivery order. Confirm the order, ask which day suits them for delivery, then thank them and end the call. Be brief and polite.",
                "tools": [
                  {
                    "connectionId": "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d",
                    "description": "Call this once the customer has agreed to a specific delivery date and time window.",
                    "http": {
                      "auth": {
                        "header": "x-api-key",
                        "in": "header",
                        "name": "api_key",
                        "secondary": {
                          "in": "header",
                          "name": "x-acme-secret",
                          "secretId": "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                        },
                        "secretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                        "type": "bearer"
                      },
                      "bodyFormat": "json",
                      "bodyRoot": "object",
                      "headers": {
                        "x-acme-source": "tone"
                      },
                      "method": "POST",
                      "timeoutMs": 5000,
                      "url": "https://api.acme.example/v1/deliveries"
                    },
                    "mock": {
                      "enabled": true,
                      "response": "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                    },
                    "name": "book_delivery_slot",
                    "parameters": [
                      {
                        "description": "The agreed date as YYYY-MM-DD.",
                        "name": "delivery_date",
                        "required": true,
                        "type": "string"
                      }
                    ],
                    "preset": "cal.com/book",
                    "speech": {
                      "en-IN": "Let me check that for you.",
                      "hi-IN": "मैं अभी देखता हूँ।"
                    }
                  }
                ],
                "voice": {
                  "languages": [
                    "hi-IN",
                    "en-IN"
                  ],
                  "sttLanguage": "auto",
                  "sttMode": "transcribe",
                  "sttModel": "saaras:v3",
                  "ttsModel": "bulbul:v3",
                  "ttsOptions": {
                    "pace": 1
                  },
                  "ttsVoice": "simran"
                }
              },
              "schema": {
                "$ref": "#/components/schemas/CreateAgentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "callSettings": {
                      "background": {
                        "sound": "none",
                        "volume": 0.3
                      },
                      "hangupLine": {
                        "text": "Thanks for your time. Goodbye."
                      },
                      "maxCallSeconds": 600,
                      "nudges": {
                        "enabled": true,
                        "hangupAfter": true,
                        "steps": [
                          {
                            "afterSeconds": 15,
                            "line": {
                              "text": null
                            }
                          }
                        ]
                      },
                      "openingLine": {
                        "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                      },
                      "voicemail": {
                        "enabled": true,
                        "windowSeconds": 30
                      }
                    },
                    "createdAt": "2026-08-25T09:14:22Z",
                    "evaluationCriteria": [
                      {
                        "id": "confirmed_order",
                        "name": "Confirmed the order",
                        "prompt": "Did the customer explicitly confirm they still want the order?"
                      }
                    ],
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "inputVariables": [
                      {
                        "default": "there",
                        "description": "The customer’s first name, as it appears on the order.",
                        "name": "customer_name"
                      }
                    ],
                    "knowledgeBaseIds": [
                      "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                    ],
                    "languages": [
                      "hi-IN",
                      "en-IN"
                    ],
                    "llmProvider": "google",
                    "name": "Order confirmation",
                    "outputVariables": [
                      {
                        "description": "Which day the customer agreed to take delivery. Leave empty if they did not commit to one.",
                        "enumValues": [
                          "monday",
                          "tuesday",
                          "wednesday"
                        ],
                        "name": "delivery_day",
                        "type": "enum"
                      }
                    ],
                    "purpose": "promotional",
                    "status": "draft",
                    "sttLanguage": "auto",
                    "sttMode": "transcribe",
                    "sttModel": "saaras:v3",
                    "sttProvider": "sarvam",
                    "systemPrompt": "You call customers to confirm a cash-on-delivery order…",
                    "tools": [
                      {
                        "connectionId": "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d",
                        "description": "Call this once the customer has agreed to a specific delivery date and time window.",
                        "http": {
                          "auth": {
                            "header": "x-api-key",
                            "in": "header",
                            "name": "api_key",
                            "secondary": {
                              "in": "header",
                              "name": "x-acme-secret",
                              "secretId": "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                            },
                            "secretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                            "type": "bearer"
                          },
                          "bodyFormat": "json",
                          "bodyRoot": "object",
                          "headers": {
                            "x-acme-source": "tone"
                          },
                          "method": "POST",
                          "timeoutMs": 5000,
                          "url": "https://api.acme.example/v1/deliveries"
                        },
                        "mock": {
                          "enabled": true,
                          "response": "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                        },
                        "name": "book_delivery_slot",
                        "parameters": [
                          {
                            "description": "The agreed date as YYYY-MM-DD.",
                            "name": "delivery_date",
                            "required": true,
                            "type": "string"
                          }
                        ],
                        "preset": "cal.com/book",
                        "speech": {
                          "en-IN": "Let me check that for you.",
                          "hi-IN": "मैं अभी देखता हूँ।"
                        }
                      }
                    ],
                    "ttsModel": "bulbul:v3",
                    "ttsOptions": {
                      "pace": 1
                    },
                    "ttsProvider": "sarvam",
                    "ttsVoice": "simran",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AgentResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Create an agent (always as a draft)",
        "tags": [
          "agents"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/agents/{id}": {
      "delete": {
        "description": "Any number bound to this agent is unassigned rather than released, so you keep the number and can rebind it. Calls the agent already made are kept: deleting the agent must not erase the record of what it said.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "agents.remove",
        "parameters": [
          {
            "description": "The agent's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "content": {
              "application/json": {
                "example": {
                  "data": null
                },
                "schema": {
                  "properties": {
                    "data": {
                      "description": "The resource, or an array of them on a list endpoint. Null for endpoints that return no body."
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Delete an agent (its numbers unassign; its call log survives)",
        "tags": [
          "agents"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      },
      "get": {
        "description": "Returns the WORKING COPY — what an edit would change and what the next publish would freeze. To read what actually ran on a call, fetch that version by number instead.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "agents.findById",
        "parameters": [
          {
            "description": "The agent's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "callSettings": {
                      "background": {
                        "sound": "none",
                        "volume": 0.3
                      },
                      "hangupLine": {
                        "text": "Thanks for your time. Goodbye."
                      },
                      "maxCallSeconds": 600,
                      "nudges": {
                        "enabled": true,
                        "hangupAfter": true,
                        "steps": [
                          {
                            "afterSeconds": 15,
                            "line": {
                              "text": null
                            }
                          }
                        ]
                      },
                      "openingLine": {
                        "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                      },
                      "voicemail": {
                        "enabled": true,
                        "windowSeconds": 30
                      }
                    },
                    "createdAt": "2026-08-25T09:14:22Z",
                    "evaluationCriteria": [
                      {
                        "id": "confirmed_order",
                        "name": "Confirmed the order",
                        "prompt": "Did the customer explicitly confirm they still want the order?"
                      }
                    ],
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "inputVariables": [
                      {
                        "default": "there",
                        "description": "The customer’s first name, as it appears on the order.",
                        "name": "customer_name"
                      }
                    ],
                    "knowledgeBaseIds": [
                      "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                    ],
                    "languages": [
                      "hi-IN",
                      "en-IN"
                    ],
                    "llmProvider": "google",
                    "name": "Order confirmation",
                    "outputVariables": [
                      {
                        "description": "Which day the customer agreed to take delivery. Leave empty if they did not commit to one.",
                        "enumValues": [
                          "monday",
                          "tuesday",
                          "wednesday"
                        ],
                        "name": "delivery_day",
                        "type": "enum"
                      }
                    ],
                    "purpose": "promotional",
                    "status": "draft",
                    "sttLanguage": "auto",
                    "sttMode": "transcribe",
                    "sttModel": "saaras:v3",
                    "sttProvider": "sarvam",
                    "systemPrompt": "You call customers to confirm a cash-on-delivery order…",
                    "tools": [
                      {
                        "connectionId": "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d",
                        "description": "Call this once the customer has agreed to a specific delivery date and time window.",
                        "http": {
                          "auth": {
                            "header": "x-api-key",
                            "in": "header",
                            "name": "api_key",
                            "secondary": {
                              "in": "header",
                              "name": "x-acme-secret",
                              "secretId": "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                            },
                            "secretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                            "type": "bearer"
                          },
                          "bodyFormat": "json",
                          "bodyRoot": "object",
                          "headers": {
                            "x-acme-source": "tone"
                          },
                          "method": "POST",
                          "timeoutMs": 5000,
                          "url": "https://api.acme.example/v1/deliveries"
                        },
                        "mock": {
                          "enabled": true,
                          "response": "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                        },
                        "name": "book_delivery_slot",
                        "parameters": [
                          {
                            "description": "The agreed date as YYYY-MM-DD.",
                            "name": "delivery_date",
                            "required": true,
                            "type": "string"
                          }
                        ],
                        "preset": "cal.com/book",
                        "speech": {
                          "en-IN": "Let me check that for you.",
                          "hi-IN": "मैं अभी देखता हूँ।"
                        }
                      }
                    ],
                    "ttsModel": "bulbul:v3",
                    "ttsOptions": {
                      "pace": 1
                    },
                    "ttsProvider": "sarvam",
                    "ttsVoice": "simran",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AgentResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Fetch a single agent",
        "tags": [
          "agents"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      },
      "patch": {
        "description": "Edits the working copy; live calls and the published version are untouched until you publish. Sending `voice` re-validates the whole speech stack, because a model change can invalidate a voice that was legal before. List-shaped fields (`knowledgeBaseIds`, `inputVariables`, `outputVariables`, `evaluationCriteria`, `tools`) are REPLACEMENTS, not merges — omit a key to leave it alone, send an empty array to clear it.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "agents.update",
        "parameters": [
          {
            "description": "The agent's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "callSettings": {
                  "background": {
                    "sound": "none",
                    "volume": 0.3
                  },
                  "hangupLine": {
                    "text": "Thanks for your time. Goodbye."
                  },
                  "maxCallSeconds": 600,
                  "nudges": {
                    "enabled": true,
                    "hangupAfter": true,
                    "steps": [
                      {
                        "afterSeconds": 15,
                        "line": {
                          "text": null
                        }
                      }
                    ]
                  },
                  "openingLine": {
                    "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                  },
                  "voicemail": {
                    "enabled": true,
                    "windowSeconds": 30
                  }
                },
                "evaluationCriteria": [
                  {
                    "id": "confirmed_order",
                    "name": "Confirmed the order",
                    "prompt": "Did the customer explicitly confirm they still want the order?"
                  }
                ],
                "inputVariables": [
                  {
                    "default": "there",
                    "description": "The customer’s first name, as it appears on the order.",
                    "name": "customer_name"
                  }
                ],
                "knowledgeBaseIds": [
                  "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                ],
                "llmModel": "gemini-2.5-flash",
                "name": "Order confirmation",
                "outputVariables": [
                  {
                    "description": "Which day the customer agreed to take delivery. Leave empty if they did not commit to one.",
                    "enumValues": [
                      "monday",
                      "tuesday",
                      "wednesday"
                    ],
                    "name": "delivery_day",
                    "type": "enum"
                  }
                ],
                "purpose": "transactional",
                "status": "live",
                "systemPrompt": "You call customers to confirm a cash-on-delivery order. Confirm the order, ask which day suits them for delivery, then thank them and end the call. Be brief and polite.",
                "tools": [
                  {
                    "connectionId": "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d",
                    "description": "Call this once the customer has agreed to a specific delivery date and time window.",
                    "http": {
                      "auth": {
                        "header": "x-api-key",
                        "in": "header",
                        "name": "api_key",
                        "secondary": {
                          "in": "header",
                          "name": "x-acme-secret",
                          "secretId": "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                        },
                        "secretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                        "type": "bearer"
                      },
                      "bodyFormat": "json",
                      "bodyRoot": "object",
                      "headers": {
                        "x-acme-source": "tone"
                      },
                      "method": "POST",
                      "timeoutMs": 5000,
                      "url": "https://api.acme.example/v1/deliveries"
                    },
                    "mock": {
                      "enabled": true,
                      "response": "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                    },
                    "name": "book_delivery_slot",
                    "parameters": [
                      {
                        "description": "The agreed date as YYYY-MM-DD.",
                        "name": "delivery_date",
                        "required": true,
                        "type": "string"
                      }
                    ],
                    "preset": "cal.com/book",
                    "speech": {
                      "en-IN": "Let me check that for you.",
                      "hi-IN": "मैं अभी देखता हूँ।"
                    }
                  }
                ],
                "voice": {
                  "languages": [
                    "hi-IN",
                    "en-IN"
                  ],
                  "sttLanguage": "auto",
                  "sttMode": "transcribe",
                  "sttModel": "saaras:v3",
                  "ttsModel": "bulbul:v3",
                  "ttsOptions": {
                    "pace": 1
                  },
                  "ttsVoice": "simran"
                }
              },
              "schema": {
                "$ref": "#/components/schemas/UpdateAgentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "callSettings": {
                      "background": {
                        "sound": "none",
                        "volume": 0.3
                      },
                      "hangupLine": {
                        "text": "Thanks for your time. Goodbye."
                      },
                      "maxCallSeconds": 600,
                      "nudges": {
                        "enabled": true,
                        "hangupAfter": true,
                        "steps": [
                          {
                            "afterSeconds": 15,
                            "line": {
                              "text": null
                            }
                          }
                        ]
                      },
                      "openingLine": {
                        "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                      },
                      "voicemail": {
                        "enabled": true,
                        "windowSeconds": 30
                      }
                    },
                    "createdAt": "2026-08-25T09:14:22Z",
                    "evaluationCriteria": [
                      {
                        "id": "confirmed_order",
                        "name": "Confirmed the order",
                        "prompt": "Did the customer explicitly confirm they still want the order?"
                      }
                    ],
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "inputVariables": [
                      {
                        "default": "there",
                        "description": "The customer’s first name, as it appears on the order.",
                        "name": "customer_name"
                      }
                    ],
                    "knowledgeBaseIds": [
                      "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                    ],
                    "languages": [
                      "hi-IN",
                      "en-IN"
                    ],
                    "llmProvider": "google",
                    "name": "Order confirmation",
                    "outputVariables": [
                      {
                        "description": "Which day the customer agreed to take delivery. Leave empty if they did not commit to one.",
                        "enumValues": [
                          "monday",
                          "tuesday",
                          "wednesday"
                        ],
                        "name": "delivery_day",
                        "type": "enum"
                      }
                    ],
                    "purpose": "promotional",
                    "status": "draft",
                    "sttLanguage": "auto",
                    "sttMode": "transcribe",
                    "sttModel": "saaras:v3",
                    "sttProvider": "sarvam",
                    "systemPrompt": "You call customers to confirm a cash-on-delivery order…",
                    "tools": [
                      {
                        "connectionId": "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d",
                        "description": "Call this once the customer has agreed to a specific delivery date and time window.",
                        "http": {
                          "auth": {
                            "header": "x-api-key",
                            "in": "header",
                            "name": "api_key",
                            "secondary": {
                              "in": "header",
                              "name": "x-acme-secret",
                              "secretId": "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                            },
                            "secretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                            "type": "bearer"
                          },
                          "bodyFormat": "json",
                          "bodyRoot": "object",
                          "headers": {
                            "x-acme-source": "tone"
                          },
                          "method": "POST",
                          "timeoutMs": 5000,
                          "url": "https://api.acme.example/v1/deliveries"
                        },
                        "mock": {
                          "enabled": true,
                          "response": "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                        },
                        "name": "book_delivery_slot",
                        "parameters": [
                          {
                            "description": "The agreed date as YYYY-MM-DD.",
                            "name": "delivery_date",
                            "required": true,
                            "type": "string"
                          }
                        ],
                        "preset": "cal.com/book",
                        "speech": {
                          "en-IN": "Let me check that for you.",
                          "hi-IN": "मैं अभी देखता हूँ।"
                        }
                      }
                    ],
                    "ttsModel": "bulbul:v3",
                    "ttsOptions": {
                      "pace": 1
                    },
                    "ttsProvider": "sarvam",
                    "ttsVoice": "simran",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AgentResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Update an agent (voice changes re-validate the whole stack)",
        "tags": [
          "agents"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/agents/{id}/publish": {
      "post": {
        "description": "Freezes the current working copy into an immutable numbered version and points the agent at it. Publishing is what changes behaviour — editing does not. A running campaign finishes on the version it launched with; inbound calls always answer with the live version.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "agents.publish",
        "parameters": [
          {
            "description": "The agent's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "callSettings": {
                      "background": {
                        "sound": "none",
                        "volume": 0.3
                      },
                      "hangupLine": {
                        "text": "Thanks for your time. Goodbye."
                      },
                      "maxCallSeconds": 600,
                      "nudges": {
                        "enabled": true,
                        "hangupAfter": true,
                        "steps": [
                          {
                            "afterSeconds": 15,
                            "line": {
                              "text": null
                            }
                          }
                        ]
                      },
                      "openingLine": {
                        "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                      },
                      "voicemail": {
                        "enabled": true,
                        "windowSeconds": 30
                      }
                    },
                    "createdAt": "2026-08-25T09:14:22Z",
                    "evaluationCriteria": [
                      {
                        "id": "confirmed_order",
                        "name": "Confirmed the order",
                        "prompt": "Did the customer explicitly confirm they still want the order?"
                      }
                    ],
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "inputVariables": [
                      {
                        "default": "there",
                        "description": "The customer’s first name, as it appears on the order.",
                        "name": "customer_name"
                      }
                    ],
                    "knowledgeBaseIds": [
                      "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                    ],
                    "llmModel": "gemini-2.5-flash",
                    "outputVariables": [
                      {
                        "description": "Which day the customer agreed to take delivery. Leave empty if they did not commit to one.",
                        "enumValues": [
                          "monday",
                          "tuesday",
                          "wednesday"
                        ],
                        "name": "delivery_day",
                        "type": "enum"
                      }
                    ],
                    "purpose": "promotional",
                    "systemPrompt": "You call customers to confirm a cash-on-delivery order…",
                    "tools": [
                      {
                        "connectionId": "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d",
                        "description": "Call this once the customer has agreed to a specific delivery date and time window.",
                        "http": {
                          "auth": {
                            "header": "x-api-key",
                            "in": "header",
                            "name": "api_key",
                            "secondary": {
                              "in": "header",
                              "name": "x-acme-secret",
                              "secretId": "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                            },
                            "secretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                            "type": "bearer"
                          },
                          "bodyFormat": "json",
                          "bodyRoot": "object",
                          "headers": {
                            "x-acme-source": "tone"
                          },
                          "method": "POST",
                          "timeoutMs": 5000,
                          "url": "https://api.acme.example/v1/deliveries"
                        },
                        "mock": {
                          "enabled": true,
                          "response": "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                        },
                        "name": "book_delivery_slot",
                        "parameters": [
                          {
                            "description": "The agreed date as YYYY-MM-DD.",
                            "name": "delivery_date",
                            "required": true,
                            "type": "string"
                          }
                        ],
                        "preset": "cal.com/book",
                        "speech": {
                          "en-IN": "Let me check that for you.",
                          "hi-IN": "मैं अभी देखता हूँ।"
                        }
                      }
                    ],
                    "ttsOptions": {
                      "pace": 1
                    },
                    "version": 0,
                    "voice": {
                      "languages": [
                        "hi-IN",
                        "en-IN"
                      ],
                      "sttLanguage": "auto",
                      "sttMode": "transcribe",
                      "sttModel": "saaras:v3",
                      "ttsModel": "bulbul:v3",
                      "ttsVoice": "simran"
                    }
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AgentVersionResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Publish the working copy as a new live version",
        "tags": [
          "agents"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/agents/{id}/rollback": {
      "post": {
        "description": "Rolling back MINTS A NEW VERSION carrying the old content rather than moving a pointer backwards, so the history stays append-only and the rollback itself is visible in it.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "agents.rollback",
        "parameters": [
          {
            "description": "The agent's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "version": 3
              },
              "schema": {
                "$ref": "#/components/schemas/RollbackAgentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "callSettings": {
                      "background": {
                        "sound": "none",
                        "volume": 0.3
                      },
                      "hangupLine": {
                        "text": "Thanks for your time. Goodbye."
                      },
                      "maxCallSeconds": 600,
                      "nudges": {
                        "enabled": true,
                        "hangupAfter": true,
                        "steps": [
                          {
                            "afterSeconds": 15,
                            "line": {
                              "text": null
                            }
                          }
                        ]
                      },
                      "openingLine": {
                        "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                      },
                      "voicemail": {
                        "enabled": true,
                        "windowSeconds": 30
                      }
                    },
                    "createdAt": "2026-08-25T09:14:22Z",
                    "evaluationCriteria": [
                      {
                        "id": "confirmed_order",
                        "name": "Confirmed the order",
                        "prompt": "Did the customer explicitly confirm they still want the order?"
                      }
                    ],
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "inputVariables": [
                      {
                        "default": "there",
                        "description": "The customer’s first name, as it appears on the order.",
                        "name": "customer_name"
                      }
                    ],
                    "knowledgeBaseIds": [
                      "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                    ],
                    "llmModel": "gemini-2.5-flash",
                    "outputVariables": [
                      {
                        "description": "Which day the customer agreed to take delivery. Leave empty if they did not commit to one.",
                        "enumValues": [
                          "monday",
                          "tuesday",
                          "wednesday"
                        ],
                        "name": "delivery_day",
                        "type": "enum"
                      }
                    ],
                    "purpose": "promotional",
                    "systemPrompt": "You call customers to confirm a cash-on-delivery order…",
                    "tools": [
                      {
                        "connectionId": "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d",
                        "description": "Call this once the customer has agreed to a specific delivery date and time window.",
                        "http": {
                          "auth": {
                            "header": "x-api-key",
                            "in": "header",
                            "name": "api_key",
                            "secondary": {
                              "in": "header",
                              "name": "x-acme-secret",
                              "secretId": "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                            },
                            "secretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                            "type": "bearer"
                          },
                          "bodyFormat": "json",
                          "bodyRoot": "object",
                          "headers": {
                            "x-acme-source": "tone"
                          },
                          "method": "POST",
                          "timeoutMs": 5000,
                          "url": "https://api.acme.example/v1/deliveries"
                        },
                        "mock": {
                          "enabled": true,
                          "response": "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                        },
                        "name": "book_delivery_slot",
                        "parameters": [
                          {
                            "description": "The agreed date as YYYY-MM-DD.",
                            "name": "delivery_date",
                            "required": true,
                            "type": "string"
                          }
                        ],
                        "preset": "cal.com/book",
                        "speech": {
                          "en-IN": "Let me check that for you.",
                          "hi-IN": "मैं अभी देखता हूँ।"
                        }
                      }
                    ],
                    "ttsOptions": {
                      "pace": 1
                    },
                    "version": 0,
                    "voice": {
                      "languages": [
                        "hi-IN",
                        "en-IN"
                      ],
                      "sttLanguage": "auto",
                      "sttMode": "transcribe",
                      "sttModel": "saaras:v3",
                      "ttsModel": "bulbul:v3",
                      "ttsVoice": "simran"
                    }
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AgentVersionResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Restore an older version (mints a new one)",
        "tags": [
          "agents"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/agents/{id}/versions": {
      "get": {
        "description": "Versions are kept forever. Each entry is exactly what ran on the calls pinned to it.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "agents.versions",
        "parameters": [
          {
            "description": "The agent's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "How many results to return. 1-100, defaulting to 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "examples": [
                50
              ],
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "callSettings": {
                        "background": {
                          "sound": "none",
                          "volume": 0.3
                        },
                        "hangupLine": {
                          "text": "Thanks for your time. Goodbye."
                        },
                        "maxCallSeconds": 600,
                        "nudges": {
                          "enabled": true,
                          "hangupAfter": true,
                          "steps": [
                            {
                              "afterSeconds": 15,
                              "line": {
                                "text": null
                              }
                            }
                          ]
                        },
                        "openingLine": {
                          "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                        },
                        "voicemail": {
                          "enabled": true,
                          "windowSeconds": 30
                        }
                      },
                      "createdAt": "2026-08-25T09:14:22Z",
                      "evaluationCriteria": [
                        {
                          "id": "confirmed_order",
                          "name": "Confirmed the order",
                          "prompt": "Did the customer explicitly confirm they still want the order?"
                        }
                      ],
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "inputVariables": [
                        {
                          "default": "there",
                          "description": "The customer’s first name, as it appears on the order.",
                          "name": "customer_name"
                        }
                      ],
                      "knowledgeBaseIds": [
                        "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                      ],
                      "llmModel": "gemini-2.5-flash",
                      "outputVariables": [
                        {
                          "description": "Which day the customer agreed to take delivery. Leave empty if they did not commit to one.",
                          "enumValues": [
                            "monday",
                            "tuesday",
                            "wednesday"
                          ],
                          "name": "delivery_day",
                          "type": "enum"
                        }
                      ],
                      "purpose": "promotional",
                      "systemPrompt": "You call customers to confirm a cash-on-delivery order…",
                      "tools": [
                        {
                          "connectionId": "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d",
                          "description": "Call this once the customer has agreed to a specific delivery date and time window.",
                          "http": {
                            "auth": {
                              "header": "x-api-key",
                              "in": "header",
                              "name": "api_key",
                              "secondary": {
                                "in": "header",
                                "name": "x-acme-secret",
                                "secretId": "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                              },
                              "secretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                              "type": "bearer"
                            },
                            "bodyFormat": "json",
                            "bodyRoot": "object",
                            "headers": {
                              "x-acme-source": "tone"
                            },
                            "method": "POST",
                            "timeoutMs": 5000,
                            "url": "https://api.acme.example/v1/deliveries"
                          },
                          "mock": {
                            "enabled": true,
                            "response": "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                          },
                          "name": "book_delivery_slot",
                          "parameters": [
                            {
                              "description": "The agreed date as YYYY-MM-DD.",
                              "name": "delivery_date",
                              "required": true,
                              "type": "string"
                            }
                          ],
                          "preset": "cal.com/book",
                          "speech": {
                            "en-IN": "Let me check that for you.",
                            "hi-IN": "मैं अभी देखता हूँ।"
                          }
                        }
                      ],
                      "ttsOptions": {
                        "pace": 1
                      },
                      "version": 0,
                      "voice": {
                        "languages": [
                          "hi-IN",
                          "en-IN"
                        ],
                        "sttLanguage": "auto",
                        "sttMode": "transcribe",
                        "sttModel": "saaras:v3",
                        "ttsModel": "bulbul:v3",
                        "ttsVoice": "simran"
                      }
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/AgentVersionResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Version history, newest first",
        "tags": [
          "agents"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/agents/{id}/versions/{version}": {
      "get": {
        "description": "The immutable content of a single published version — prompt, voice, tools and the knowledge bases it was published with. This is how a finished call stays explainable after the agent has moved on.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "agents.version",
        "parameters": [
          {
            "description": "The agent's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Which version to read, counting from 1.",
            "in": "path",
            "name": "version",
            "required": true,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "callSettings": {
                      "background": {
                        "sound": "none",
                        "volume": 0.3
                      },
                      "hangupLine": {
                        "text": "Thanks for your time. Goodbye."
                      },
                      "maxCallSeconds": 600,
                      "nudges": {
                        "enabled": true,
                        "hangupAfter": true,
                        "steps": [
                          {
                            "afterSeconds": 15,
                            "line": {
                              "text": null
                            }
                          }
                        ]
                      },
                      "openingLine": {
                        "text": "Hi {{customer_name}}, I’m calling from Acme about your order."
                      },
                      "voicemail": {
                        "enabled": true,
                        "windowSeconds": 30
                      }
                    },
                    "createdAt": "2026-08-25T09:14:22Z",
                    "evaluationCriteria": [
                      {
                        "id": "confirmed_order",
                        "name": "Confirmed the order",
                        "prompt": "Did the customer explicitly confirm they still want the order?"
                      }
                    ],
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "inputVariables": [
                      {
                        "default": "there",
                        "description": "The customer’s first name, as it appears on the order.",
                        "name": "customer_name"
                      }
                    ],
                    "knowledgeBaseIds": [
                      "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                    ],
                    "llmModel": "gemini-2.5-flash",
                    "outputVariables": [
                      {
                        "description": "Which day the customer agreed to take delivery. Leave empty if they did not commit to one.",
                        "enumValues": [
                          "monday",
                          "tuesday",
                          "wednesday"
                        ],
                        "name": "delivery_day",
                        "type": "enum"
                      }
                    ],
                    "purpose": "promotional",
                    "systemPrompt": "You call customers to confirm a cash-on-delivery order…",
                    "tools": [
                      {
                        "connectionId": "b4e6d8a1-9c3f-4b2e-8d7a-1f0e9c8b7a6d",
                        "description": "Call this once the customer has agreed to a specific delivery date and time window.",
                        "http": {
                          "auth": {
                            "header": "x-api-key",
                            "in": "header",
                            "name": "api_key",
                            "secondary": {
                              "in": "header",
                              "name": "x-acme-secret",
                              "secretId": "7c2b8e5d-1a3f-4e6b-8c9d-0e1f2a3b4c5d"
                            },
                            "secretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                            "type": "bearer"
                          },
                          "bodyFormat": "json",
                          "bodyRoot": "object",
                          "headers": {
                            "x-acme-source": "tone"
                          },
                          "method": "POST",
                          "timeoutMs": 5000,
                          "url": "https://api.acme.example/v1/deliveries"
                        },
                        "mock": {
                          "enabled": true,
                          "response": "{\"status\":\"booked\",\"slot\":\"2026-09-02T10:00:00+05:30\"}"
                        },
                        "name": "book_delivery_slot",
                        "parameters": [
                          {
                            "description": "The agreed date as YYYY-MM-DD.",
                            "name": "delivery_date",
                            "required": true,
                            "type": "string"
                          }
                        ],
                        "preset": "cal.com/book",
                        "speech": {
                          "en-IN": "Let me check that for you.",
                          "hi-IN": "मैं अभी देखता हूँ।"
                        }
                      }
                    ],
                    "ttsOptions": {
                      "pace": 1
                    },
                    "version": 0,
                    "voice": {
                      "languages": [
                        "hi-IN",
                        "en-IN"
                      ],
                      "sttLanguage": "auto",
                      "sttMode": "transcribe",
                      "sttModel": "saaras:v3",
                      "ttsModel": "bulbul:v3",
                      "ttsVoice": "simran"
                    }
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AgentVersionResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "One version by its number",
        "tags": [
          "agents"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/calls": {
      "get": {
        "description": "Every call, inbound and outbound, including campaign calls. Filter by agent, number, campaign, direction, disposition or date range. A campaign filter here returns every ATTEMPT including retries, which the recipient list cannot give you.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "calls.list",
        "parameters": [
          {
            "description": "How many calls to return. 1-100.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "examples": [
                25
              ],
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Opaque page cursor — pass `meta.pagination.cursor` from the previous response. Its contents are an implementation detail; do not parse or construct one.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "examples": [
                "eyJjIjoiMjAyNi0wOC0yNVQwOToxNDoyMi4xMTFaIiwiaSI6IjlmMWMyZDg0LTRlM2EtNGY2Yy1iOTAyLTdkMWU4YTMzYzQ1MSJ9"
              ],
              "minLength": 1,
              "type": "string"
            }
          },
          {
            "description": "Only calls run by this agent, across every one of its versions.",
            "in": "query",
            "name": "agent_id",
            "required": false,
            "schema": {
              "examples": [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ],
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "description": "Only calls placed from, or received on, this number.",
            "in": "query",
            "name": "number_id",
            "required": false,
            "schema": {
              "examples": [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ],
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "description": "Every call this campaign placed, retries included — which is what the recipient list cannot give you, since a recipient row names only its LAST attempt.",
            "in": "query",
            "name": "campaign_id",
            "required": false,
            "schema": {
              "examples": [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ],
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "description": "Which way the call went. Open set — handle an unrecognised value rather than throwing. Today: `inbound`, `outbound`.",
            "in": "query",
            "name": "direction",
            "required": false,
            "schema": {
              "enum": [
                "inbound",
                "outbound"
              ],
              "examples": [
                "outbound"
              ],
              "type": "string"
            },
            "x-known-values": [
              "inbound",
              "outbound"
            ]
          },
          {
            "description": "How the call was carried. `browser` is the in-dashboard microphone test only; every dial the API places is `pstn`. Open set — handle an unrecognised value rather than throwing. Today: `browser`, `pstn`.",
            "in": "query",
            "name": "channel",
            "required": false,
            "schema": {
              "enum": [
                "browser",
                "pstn"
              ],
              "examples": [
                "pstn"
              ],
              "type": "string"
            },
            "x-known-values": [
              "browser",
              "pstn"
            ]
          },
          {
            "description": "Where the call is in its lifecycle. Open set — handle an unrecognised value rather than throwing. Today: `queued`, `in_progress`, `ended`.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "queued",
                "in_progress",
                "ended"
              ],
              "examples": [
                "ended"
              ],
              "type": "string"
            },
            "x-known-values": [
              "queued",
              "in_progress",
              "ended"
            ]
          },
          {
            "description": "How the call finished. Only set once `status` is `ended`. Open set — handle an unrecognised value rather than throwing. Today: `answered`, `no_answer`, `busy`, `failed`, `voicemail`, `unknown`.",
            "in": "query",
            "name": "disposition",
            "required": false,
            "schema": {
              "enum": [
                "answered",
                "no_answer",
                "busy",
                "failed",
                "voicemail",
                "unknown"
              ],
              "examples": [
                "answered"
              ],
              "type": "string"
            },
            "x-known-values": [
              "answered",
              "no_answer",
              "busy",
              "failed",
              "voicemail",
              "unknown"
            ]
          },
          {
            "description": "Ignored when you authenticate with an API key: the key's own prefix pins the environment, so a `tone_test_` key structurally cannot read live calls.",
            "in": "query",
            "name": "environment",
            "required": false,
            "schema": {
              "enum": [
                "live",
                "test"
              ],
              "examples": [
                "live"
              ],
              "type": "string"
            }
          },
          {
            "description": "Inclusive lower bound on `createdAt`. A bare date (`2026-08-01`) is accepted and read as midnight UTC.",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "examples": [
                "2026-08-01"
              ],
              "type": "string"
            }
          },
          {
            "description": "Exclusive upper bound on `createdAt`. Must be later than `from`.",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "examples": [
                "2026-08-25T00:00:00Z"
              ],
              "type": "string"
            }
          },
          {
            "description": "Include rows for calls that never started — an abandoned browser test dialog mints one, so they are hidden by default.",
            "in": "query",
            "name": "include_unstarted",
            "required": false,
            "schema": {
              "enum": [
                "0",
                "1",
                "true",
                "false"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "agent": {
                        "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                        "name": "Order confirmation"
                      },
                      "agentVersion": 3,
                      "billedPaise": 600,
                      "campaignId": null,
                      "channel": "pstn",
                      "compliance": "passed",
                      "createdAt": "2026-08-25T09:14:22Z",
                      "direction": "outbound",
                      "disposition": "answered",
                      "durationSeconds": 45,
                      "endReason": "agent_ended",
                      "endedAt": "2026-08-25T09:15:11Z",
                      "environment": "live",
                      "evaluations": {},
                      "hasRecording": true,
                      "hasTranscript": true,
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "initiator": {
                        "id": "key_8f14a2c9",
                        "type": "api_key"
                      },
                      "number": {
                        "e164": "+918045678901",
                        "id": "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43"
                      },
                      "outputs": {
                        "confirmed": true,
                        "delivery_day": "Thursday"
                      },
                      "peer": "+919876543210",
                      "quality": {
                        "answerP50Ms": 480,
                        "perceivedP50Ms": 0,
                        "turns": 6
                      },
                      "ratePaisePerMinute": 600,
                      "startedAt": "2026-08-25T09:14:26Z",
                      "status": "ended",
                      "summary": "Customer confirmed the order and asked for Thursday delivery.",
                      "variables": {
                        "customer_name": "Priya",
                        "order_id": "AC-4417"
                      },
                      "verdict": "success"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/CallResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "List calls, newest first (cursor-paginated)",
        "tags": [
          "calls"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      },
      "post": {
        "description": "Runs the full pre-dial compliance gate inside the same transaction, so a refusal is a `403` with the audit rows already written and no carrier contacted. Requires `agentId` on a number that routes to a Tone agent and forbids it on a BYO number. Over your concurrent-call quota this returns `429` BEFORE the gate runs, so no verdict is recorded. Send an `Idempotency-Key` — a timeout is otherwise indistinguishable from a call you did not place.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "calls.create",
        "parameters": [
          {
            "description": "Optional but recommended. Retrying with the same key replays the first response instead of placing a second call. Reusing a key with a different body is `422`; a concurrent duplicate is `409`. Keys are remembered for 24 hours.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 255,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                "numberId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                "toE164": "+919876543210"
              },
              "schema": {
                "$ref": "#/components/schemas/CreateCallDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "agentVersion": 3,
                    "billedPaise": 600,
                    "campaignId": null,
                    "channel": "pstn",
                    "compliance": "passed",
                    "createdAt": "2026-08-25T09:14:22Z",
                    "direction": "outbound",
                    "disposition": "answered",
                    "durationSeconds": 45,
                    "endReason": "agent_ended",
                    "endedAt": "2026-08-25T09:15:11Z",
                    "environment": "live",
                    "evaluations": {},
                    "hasRecording": true,
                    "hasTranscript": true,
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "initiator": {
                      "id": "key_8f14a2c9",
                      "type": "api_key"
                    },
                    "number": {
                      "e164": "+918045678901",
                      "id": "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43"
                    },
                    "outputs": {
                      "confirmed": true,
                      "delivery_day": "Thursday"
                    },
                    "peer": "+919876543210",
                    "quality": {
                      "answerP50Ms": 480,
                      "perceivedP50Ms": 0,
                      "turns": 6
                    },
                    "ratePaisePerMinute": 600,
                    "startedAt": "2026-08-25T09:14:26Z",
                    "status": "ended",
                    "summary": "Customer confirmed the order and asked for Thursday delivery.",
                    "variables": {
                      "customer_name": "Priya",
                      "order_id": "AC-4417"
                    },
                    "verdict": "success"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CallResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "Idempotent-Replayed": {
                "description": "`true` when this response is a replay of an earlier request with the same `Idempotency-Key`, rather than fresh work.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Place an outbound call (runs the compliance gate)",
        "tags": [
          "calls"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/calls/export.csv": {
      "get": {
        "description": "Takes the same filters as the list endpoint and streams a CSV rather than JSON. The column order is deliberately frozen — new fields are appended, never inserted — so a positional parser keeps working.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "calls.exportCsv",
        "parameters": [
          {
            "description": "Only calls run by this agent, across every one of its versions.",
            "in": "query",
            "name": "agent_id",
            "required": false,
            "schema": {
              "examples": [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ],
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "description": "Only calls placed from, or received on, this number.",
            "in": "query",
            "name": "number_id",
            "required": false,
            "schema": {
              "examples": [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ],
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "description": "Every call this campaign placed, retries included — which is what the recipient list cannot give you, since a recipient row names only its LAST attempt.",
            "in": "query",
            "name": "campaign_id",
            "required": false,
            "schema": {
              "examples": [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ],
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "description": "Which way the call went. Open set — handle an unrecognised value rather than throwing. Today: `inbound`, `outbound`.",
            "in": "query",
            "name": "direction",
            "required": false,
            "schema": {
              "enum": [
                "inbound",
                "outbound"
              ],
              "examples": [
                "outbound"
              ],
              "type": "string"
            },
            "x-known-values": [
              "inbound",
              "outbound"
            ]
          },
          {
            "description": "How the call was carried. `browser` is the in-dashboard microphone test only; every dial the API places is `pstn`. Open set — handle an unrecognised value rather than throwing. Today: `browser`, `pstn`.",
            "in": "query",
            "name": "channel",
            "required": false,
            "schema": {
              "enum": [
                "browser",
                "pstn"
              ],
              "examples": [
                "pstn"
              ],
              "type": "string"
            },
            "x-known-values": [
              "browser",
              "pstn"
            ]
          },
          {
            "description": "Where the call is in its lifecycle. Open set — handle an unrecognised value rather than throwing. Today: `queued`, `in_progress`, `ended`.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "queued",
                "in_progress",
                "ended"
              ],
              "examples": [
                "ended"
              ],
              "type": "string"
            },
            "x-known-values": [
              "queued",
              "in_progress",
              "ended"
            ]
          },
          {
            "description": "How the call finished. Only set once `status` is `ended`. Open set — handle an unrecognised value rather than throwing. Today: `answered`, `no_answer`, `busy`, `failed`, `voicemail`, `unknown`.",
            "in": "query",
            "name": "disposition",
            "required": false,
            "schema": {
              "enum": [
                "answered",
                "no_answer",
                "busy",
                "failed",
                "voicemail",
                "unknown"
              ],
              "examples": [
                "answered"
              ],
              "type": "string"
            },
            "x-known-values": [
              "answered",
              "no_answer",
              "busy",
              "failed",
              "voicemail",
              "unknown"
            ]
          },
          {
            "description": "Ignored when you authenticate with an API key: the key's own prefix pins the environment, so a `tone_test_` key structurally cannot read live calls.",
            "in": "query",
            "name": "environment",
            "required": false,
            "schema": {
              "enum": [
                "live",
                "test"
              ],
              "examples": [
                "live"
              ],
              "type": "string"
            }
          },
          {
            "description": "Inclusive lower bound on `createdAt`. A bare date (`2026-08-01`) is accepted and read as midnight UTC.",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "examples": [
                "2026-08-01"
              ],
              "type": "string"
            }
          },
          {
            "description": "Exclusive upper bound on `createdAt`. Must be later than `from`.",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "examples": [
                "2026-08-25T00:00:00Z"
              ],
              "type": "string"
            }
          },
          {
            "description": "Include rows for calls that never started — an abandoned browser test dialog mints one, so they are hidden by default.",
            "in": "query",
            "name": "include_unstarted",
            "required": false,
            "schema": {
              "enum": [
                "0",
                "1",
                "true",
                "false"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Export the filtered call log as CSV (newest first, max 10,000 rows)",
        "tags": [
          "calls"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/calls/{id}": {
      "get": {
        "description": "The full call detail record: outcome, duration, what was billed, the agent version that ran it, your declared output variables, the evaluation verdicts and the per-call variables it was given.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "calls.findById",
        "parameters": [
          {
            "description": "The call's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "agentVersion": 3,
                    "billedPaise": 600,
                    "campaignId": null,
                    "channel": "pstn",
                    "compliance": "passed",
                    "createdAt": "2026-08-25T09:14:22Z",
                    "direction": "outbound",
                    "disposition": "answered",
                    "durationSeconds": 45,
                    "endReason": "agent_ended",
                    "endedAt": "2026-08-25T09:15:11Z",
                    "environment": "live",
                    "evaluations": {},
                    "hasRecording": true,
                    "hasTranscript": true,
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "initiator": {
                      "id": "key_8f14a2c9",
                      "type": "api_key"
                    },
                    "number": {
                      "e164": "+918045678901",
                      "id": "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43"
                    },
                    "outputs": {
                      "confirmed": true,
                      "delivery_day": "Thursday"
                    },
                    "peer": "+919876543210",
                    "quality": {
                      "answerP50Ms": 480,
                      "perceivedP50Ms": 0,
                      "turns": 6
                    },
                    "ratePaisePerMinute": 600,
                    "startedAt": "2026-08-25T09:14:26Z",
                    "status": "ended",
                    "summary": "Customer confirmed the order and asked for Thursday delivery.",
                    "variables": {
                      "customer_name": "Priya",
                      "order_id": "AC-4417"
                    },
                    "verdict": "success"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CallResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Fetch a single call",
        "tags": [
          "calls"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/calls/{id}/evidence": {
      "get": {
        "description": "The tamper-evident evidence document for this call: the legal basis it was placed on (DNC, consent, carrier signal), how it was placed (DLT registration, A2P declaration, calling window, AI disclosure), the outcome, and the hash-chain seal. Available shortly after the call ends.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "calls.evidence",
        "parameters": [
          {
            "description": "The call's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "callId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "campaignId": null,
                    "chainSeq": "4211",
                    "content": {},
                    "contentHash": "a3f1…",
                    "e164": "+919876543210",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "kind": "completed_call",
                    "prevHash": "0000…",
                    "recordHash": "b7e2…",
                    "sealedAt": "2026-08-31T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/EvidenceRecordResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Fetch a call's sealed evidence record",
        "tags": [
          "calls"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/calls/{id}/evidence.pdf": {
      "get": {
        "description": "The same sealed record `GET /v1/calls/{id}/evidence` returns, rendered as a human-readable document with the hash-chain seal on page one.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "calls.evidencePdf",
        "parameters": [
          {
            "description": "The call's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Download a call's evidence record as a PDF",
        "tags": [
          "calls"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/calls/{id}/recording": {
      "get": {
        "description": "Streams the recording as `audio/wav`, in stereo: the caller on the left channel, the agent on the right. Not enveloped, and often several megabytes. Absent when recording is off for the number, or when the call never connected.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "calls.recording",
        "parameters": [
          {
            "description": "The call's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Fetch a call's audio recording (WAV)",
        "tags": [
          "calls"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/calls/{id}/transcript": {
      "get": {
        "description": "The turn-by-turn transcript, once the call has ended. A call with no audio — a sandbox call, an unanswered one — has no transcript.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "calls.transcript",
        "parameters": [
          {
            "description": "The call's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": null
                },
                "schema": {
                  "properties": {
                    "data": {
                      "description": "The resource, or an array of them on a list endpoint. Null for endpoints that return no body."
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Fetch a call's transcript",
        "tags": [
          "calls"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/campaigns": {
      "get": {
        "description": "Archived campaigns are hidden by default; pass `archived=true` to see only those. There is deliberately no way to ask for both at once.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.list",
        "parameters": [
          {
            "description": "How many results to return. 1-100, defaulting to 25.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "examples": [
                25
              ],
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Opaque page cursor — pass `meta.pagination.cursor` from the previous response to fetch the next page. Its contents are an implementation detail; do not parse or construct one.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "examples": [
                "eyJjIjoiMjAyNi0wOC0yNVQwOToxNDoyMi4xMTFaIiwiaSI6IjlmMWMyZDg0LTRlM2EtNGY2Yy1iOTAyLTdkMWU4YTMzYzQ1MSJ9"
              ],
              "minLength": 1,
              "type": "string"
            }
          },
          {
            "description": "Only campaigns in this state. Open set — handle an unrecognised value rather than throwing. Today: `draft`, `scheduled`, `running`, `paused`, `completed`, `stopped`, `failed`.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "draft",
                "scheduled",
                "running",
                "paused",
                "completed",
                "stopped",
                "failed"
              ],
              "examples": [
                "running"
              ],
              "type": "string"
            },
            "x-known-values": [
              "draft",
              "scheduled",
              "running",
              "paused",
              "completed",
              "stopped",
              "failed"
            ]
          },
          {
            "description": "Only campaigns running this agent.",
            "in": "query",
            "name": "agent_id",
            "required": false,
            "schema": {
              "examples": [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ],
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "description": "Ignored when you authenticate with an API key: the key prefix pins the environment.",
            "in": "query",
            "name": "environment",
            "required": false,
            "schema": {
              "enum": [
                "live",
                "test"
              ],
              "examples": [
                "live"
              ],
              "type": "string"
            }
          },
          {
            "description": "Inclusive lower bound on when the campaign was created.",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "examples": [
                "2026-08-01"
              ],
              "type": "string"
            }
          },
          {
            "description": "Exclusive upper bound on when the campaign was created.",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "examples": [
                "2026-09-01"
              ],
              "type": "string"
            }
          },
          {
            "description": "true returns ONLY archived campaigns; the default returns only unarchived ones. There is deliberately no way to ask for both.",
            "in": "query",
            "name": "archived",
            "required": false,
            "schema": {
              "enum": [
                "0",
                "1",
                "true",
                "false"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "agent": {
                        "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                        "name": "Order confirmation"
                      },
                      "archivedAt": null,
                      "autoPauseBelowPaise": 50000,
                      "completedAt": null,
                      "createdAt": "2026-08-25T09:14:22Z",
                      "environment": "live",
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "launchedAt": "2026-09-01T04:00:00Z",
                      "name": "COD confirmations — September",
                      "number": {
                        "e164": "+918045678901",
                        "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                      },
                      "pacing": {
                        "callsPerMinute": 10,
                        "maxConcurrent": 4
                      },
                      "pausedReason": "operator",
                      "preflight": {
                        "callable": 0,
                        "checks": [
                          {
                            "outcome": "pass",
                            "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                            "type": "time_window"
                          }
                        ],
                        "computedAt": "2026-09-01T03:58:12Z",
                        "estimatedCostPaise": {
                          "high": 480000,
                          "low": 120000
                        },
                        "excluded": "invalid_number",
                        "excludedE164s": {},
                        "total": 0,
                        "walletBalancePaise": 500000
                      },
                      "progress": {
                        "connected": 244,
                        "dialed": 320,
                        "excluded": 31,
                        "spentPaise": 146400,
                        "total": 500
                      },
                      "purpose": "transactional",
                      "retries": {
                        "attempts": 1,
                        "backoff": "linear",
                        "intervalMinutes": 60,
                        "on": [
                          "no_answer",
                          "busy"
                        ]
                      },
                      "schedule": {
                        "endsAt": "2026-09-07T14:00:00Z",
                        "startsAt": "2026-09-01T04:00:00Z",
                        "weekdays": 31,
                        "windowEndMinute": 1260,
                        "windowStartMinute": 540
                      },
                      "status": "running",
                      "updatedAt": "2026-08-25T09:14:22Z"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/CampaignResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "List campaigns, newest first (cursor-paginated)",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      },
      "post": {
        "description": "A campaign is a recipient list plus a pacing, retry and calling-window policy. It is created as a draft and dials nothing until you launch it. 🔴 `agentId` can never be changed afterwards — duplicate the campaign to use a different agent.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                "autoPauseBelowPaise": 50000,
                "callsPerMinute": 10,
                "endsAt": "2026-09-07T14:00:00Z",
                "maxConcurrent": 4,
                "name": "COD confirmations — September",
                "numberId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                "retryAttempts": 1,
                "retryBackoff": "fixed",
                "retryIntervalMinutes": 60,
                "retryOn": [
                  "no_answer",
                  "busy"
                ],
                "startsAt": "2026-09-01T04:00:00Z",
                "weekdays": 31,
                "windowEndMinute": 1260,
                "windowStartMinute": 540
              },
              "schema": {
                "$ref": "#/components/schemas/CreateCampaignDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "archivedAt": null,
                    "autoPauseBelowPaise": 50000,
                    "completedAt": null,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "environment": "live",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "launchedAt": "2026-09-01T04:00:00Z",
                    "name": "COD confirmations — September",
                    "number": {
                      "e164": "+918045678901",
                      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                    },
                    "pacing": {
                      "callsPerMinute": 10,
                      "maxConcurrent": 4
                    },
                    "pausedReason": "operator",
                    "preflight": {
                      "callable": 0,
                      "checks": [
                        {
                          "outcome": "pass",
                          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                          "type": "time_window"
                        }
                      ],
                      "computedAt": "2026-09-01T03:58:12Z",
                      "estimatedCostPaise": {
                        "high": 480000,
                        "low": 120000
                      },
                      "excluded": "invalid_number",
                      "excludedE164s": {},
                      "total": 0,
                      "walletBalancePaise": 500000
                    },
                    "progress": {
                      "connected": 244,
                      "dialed": 320,
                      "excluded": 31,
                      "spentPaise": 146400,
                      "total": 500
                    },
                    "purpose": "transactional",
                    "retries": {
                      "attempts": 1,
                      "backoff": "linear",
                      "intervalMinutes": 60,
                      "on": [
                        "no_answer",
                        "busy"
                      ]
                    },
                    "schedule": {
                      "endsAt": "2026-09-07T14:00:00Z",
                      "startsAt": "2026-09-01T04:00:00Z",
                      "weekdays": 31,
                      "windowEndMinute": 1260,
                      "windowStartMinute": 540
                    },
                    "status": "running",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Create a campaign (as a draft)",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/campaigns/{id}": {
      "delete": {
        "description": "The calls it already placed survive in the call log — deleting the campaign must not erase the record of what was dialled.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.remove",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "content": {
              "application/json": {
                "example": {
                  "data": null
                },
                "schema": {
                  "properties": {
                    "data": {
                      "description": "The resource, or an array of them on a list endpoint. Null for endpoints that return no body."
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Delete a campaign and its recipients",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      },
      "get": {
        "description": "Includes the snapshot taken at launch — the agent, the number and the sender classification the run actually used — which is evidence, not a live read of what those objects say today.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.findById",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "archivedAt": null,
                    "autoPauseBelowPaise": 50000,
                    "completedAt": null,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "environment": "live",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "launchedAt": "2026-09-01T04:00:00Z",
                    "name": "COD confirmations — September",
                    "number": {
                      "e164": "+918045678901",
                      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                    },
                    "pacing": {
                      "callsPerMinute": 10,
                      "maxConcurrent": 4
                    },
                    "pausedReason": "operator",
                    "preflight": {
                      "callable": 0,
                      "checks": [
                        {
                          "outcome": "pass",
                          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                          "type": "time_window"
                        }
                      ],
                      "computedAt": "2026-09-01T03:58:12Z",
                      "estimatedCostPaise": {
                        "high": 480000,
                        "low": 120000
                      },
                      "excluded": "invalid_number",
                      "excludedE164s": {},
                      "total": 0,
                      "walletBalancePaise": 500000
                    },
                    "progress": {
                      "connected": 244,
                      "dialed": 320,
                      "excluded": 31,
                      "spentPaise": 146400,
                      "total": 500
                    },
                    "purpose": "transactional",
                    "retries": {
                      "attempts": 1,
                      "backoff": "linear",
                      "intervalMinutes": 60,
                      "on": [
                        "no_answer",
                        "busy"
                      ]
                    },
                    "schedule": {
                      "endsAt": "2026-09-07T14:00:00Z",
                      "startsAt": "2026-09-01T04:00:00Z",
                      "weekdays": 31,
                      "windowEndMinute": 1260,
                      "windowStartMinute": 540
                    },
                    "status": "running",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Fetch a single campaign",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      },
      "patch": {
        "description": "Everything freezes once the campaign leaves draft: a running campaign is paused, edited and relaunched, not edited in place. `agentId` cannot be changed at any point.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.update",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "autoPauseBelowPaise": 50000,
                "callsPerMinute": 10,
                "endsAt": "2026-09-07T14:00:00Z",
                "maxConcurrent": 4,
                "name": "COD confirmations — September",
                "numberId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                "retryAttempts": 1,
                "retryBackoff": "fixed",
                "retryIntervalMinutes": 60,
                "retryOn": [
                  "no_answer",
                  "busy"
                ],
                "startsAt": "2026-09-01T04:00:00Z",
                "weekdays": 31,
                "windowEndMinute": 1260,
                "windowStartMinute": 540
              },
              "schema": {
                "$ref": "#/components/schemas/UpdateCampaignDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "archivedAt": null,
                    "autoPauseBelowPaise": 50000,
                    "completedAt": null,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "environment": "live",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "launchedAt": "2026-09-01T04:00:00Z",
                    "name": "COD confirmations — September",
                    "number": {
                      "e164": "+918045678901",
                      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                    },
                    "pacing": {
                      "callsPerMinute": 10,
                      "maxConcurrent": 4
                    },
                    "pausedReason": "operator",
                    "preflight": {
                      "callable": 0,
                      "checks": [
                        {
                          "outcome": "pass",
                          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                          "type": "time_window"
                        }
                      ],
                      "computedAt": "2026-09-01T03:58:12Z",
                      "estimatedCostPaise": {
                        "high": 480000,
                        "low": 120000
                      },
                      "excluded": "invalid_number",
                      "excludedE164s": {},
                      "total": 0,
                      "walletBalancePaise": 500000
                    },
                    "progress": {
                      "connected": 244,
                      "dialed": 320,
                      "excluded": 31,
                      "spentPaise": 146400,
                      "total": 500
                    },
                    "purpose": "transactional",
                    "retries": {
                      "attempts": 1,
                      "backoff": "linear",
                      "intervalMinutes": 60,
                      "on": [
                        "no_answer",
                        "busy"
                      ]
                    },
                    "schedule": {
                      "endsAt": "2026-09-07T14:00:00Z",
                      "startsAt": "2026-09-01T04:00:00Z",
                      "weekdays": 31,
                      "windowEndMinute": 1260,
                      "windowStartMinute": 540
                    },
                    "status": "running",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Update a campaign. Only while it is a draft or scheduled.",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/campaigns/{id}/archive": {
      "post": {
        "description": "Housekeeping for a finished run. Its calls, recipients and compliance record are all still there.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.archive",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "archivedAt": null,
                    "autoPauseBelowPaise": 50000,
                    "completedAt": null,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "environment": "live",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "launchedAt": "2026-09-01T04:00:00Z",
                    "name": "COD confirmations — September",
                    "number": {
                      "e164": "+918045678901",
                      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                    },
                    "pacing": {
                      "callsPerMinute": 10,
                      "maxConcurrent": 4
                    },
                    "pausedReason": "operator",
                    "preflight": {
                      "callable": 0,
                      "checks": [
                        {
                          "outcome": "pass",
                          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                          "type": "time_window"
                        }
                      ],
                      "computedAt": "2026-09-01T03:58:12Z",
                      "estimatedCostPaise": {
                        "high": 480000,
                        "low": 120000
                      },
                      "excluded": "invalid_number",
                      "excludedE164s": {},
                      "total": 0,
                      "walletBalancePaise": 500000
                    },
                    "progress": {
                      "connected": 244,
                      "dialed": 320,
                      "excluded": 31,
                      "spentPaise": 146400,
                      "total": 500
                    },
                    "purpose": "transactional",
                    "retries": {
                      "attempts": 1,
                      "backoff": "linear",
                      "intervalMinutes": 60,
                      "on": [
                        "no_answer",
                        "busy"
                      ]
                    },
                    "schedule": {
                      "endsAt": "2026-09-07T14:00:00Z",
                      "startsAt": "2026-09-01T04:00:00Z",
                      "weekdays": 31,
                      "windowEndMinute": 1260,
                      "windowStartMinute": 540
                    },
                    "status": "running",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Hide the campaign from the list. Nothing is deleted, and this route still serves it.",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/campaigns/{id}/compliance": {
      "get": {
        "description": "The audit trail for the whole run: every check that passed, warned or blocked, in the order it ran. This is what a complaint is answered with.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.compliance",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "callId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "checkType": "dnc",
                      "createdAt": "2026-08-25T09:14:22Z",
                      "detail": {},
                      "e164": "+919876543210",
                      "enforced": true,
                      "id": "8814",
                      "outcome": "pass",
                      "reason": "Asked to be removed during a call on 2026-08-20.",
                      "source": "internal"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/ComplianceCheckResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Every compliance check recorded for this campaign's calls",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/campaigns/{id}/duplicate": {
      "post": {
        "description": "The way to re-run a list, or to change the agent — which the original campaign will not let you do.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.duplicate",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "archivedAt": null,
                    "autoPauseBelowPaise": 50000,
                    "completedAt": null,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "environment": "live",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "launchedAt": "2026-09-01T04:00:00Z",
                    "name": "COD confirmations — September",
                    "number": {
                      "e164": "+918045678901",
                      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                    },
                    "pacing": {
                      "callsPerMinute": 10,
                      "maxConcurrent": 4
                    },
                    "pausedReason": "operator",
                    "preflight": {
                      "callable": 0,
                      "checks": [
                        {
                          "outcome": "pass",
                          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                          "type": "time_window"
                        }
                      ],
                      "computedAt": "2026-09-01T03:58:12Z",
                      "estimatedCostPaise": {
                        "high": 480000,
                        "low": 120000
                      },
                      "excluded": "invalid_number",
                      "excludedE164s": {},
                      "total": 0,
                      "walletBalancePaise": 500000
                    },
                    "progress": {
                      "connected": 244,
                      "dialed": 320,
                      "excluded": 31,
                      "spentPaise": 146400,
                      "total": 500
                    },
                    "purpose": "transactional",
                    "retries": {
                      "attempts": 1,
                      "backoff": "linear",
                      "intervalMinutes": 60,
                      "on": [
                        "no_answer",
                        "busy"
                      ]
                    },
                    "schedule": {
                      "endsAt": "2026-09-07T14:00:00Z",
                      "startsAt": "2026-09-01T04:00:00Z",
                      "weekdays": 31,
                      "windowEndMinute": 1260,
                      "windowStartMinute": 540
                    },
                    "status": "running",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Copy this campaign and its recipients to a draft",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/campaigns/{id}/export.csv": {
      "get": {
        "description": "Streams CSV rather than JSON, for the whole list rather than a page.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.exportCsv",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Export the recipient list, outcomes included",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/campaigns/{id}/launch": {
      "post": {
        "description": "🔴 `Idempotency-Key` is REQUIRED — without it this returns `400`. Launching twice would dial the whole list twice, which is exactly the complaint pattern TCCCPR punishes. Refused if the agent is still a draft, if the number routes to your own stack, or if any pre-flight check blocks. Scrubbing runs here and MUST succeed: a scrubber outage fails the launch rather than passing an unscrubbed list.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.launch",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "REQUIRED. A unique key of your choosing — a UUID is fine. Retrying with the same key replays the first response instead of acting twice, which is what makes a timeout safe to retry here. Reusing a key with a DIFFERENT body is `422 idempotency_key_reused_with_different_params`; retrying while the first is still running is `409 idempotency_key_in_use`. Keys are remembered for 24 hours.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "maxLength": 255,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "archivedAt": null,
                    "autoPauseBelowPaise": 50000,
                    "completedAt": null,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "environment": "live",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "launchedAt": "2026-09-01T04:00:00Z",
                    "name": "COD confirmations — September",
                    "number": {
                      "e164": "+918045678901",
                      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                    },
                    "pacing": {
                      "callsPerMinute": 10,
                      "maxConcurrent": 4
                    },
                    "pausedReason": "operator",
                    "preflight": {
                      "callable": 0,
                      "checks": [
                        {
                          "outcome": "pass",
                          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                          "type": "time_window"
                        }
                      ],
                      "computedAt": "2026-09-01T03:58:12Z",
                      "estimatedCostPaise": {
                        "high": 480000,
                        "low": 120000
                      },
                      "excluded": "invalid_number",
                      "excludedE164s": {},
                      "total": 0,
                      "walletBalancePaise": 500000
                    },
                    "progress": {
                      "connected": 244,
                      "dialed": 320,
                      "excluded": 31,
                      "spentPaise": 146400,
                      "total": 500
                    },
                    "purpose": "transactional",
                    "retries": {
                      "attempts": 1,
                      "backoff": "linear",
                      "intervalMinutes": 60,
                      "on": [
                        "no_answer",
                        "busy"
                      ]
                    },
                    "schedule": {
                      "endsAt": "2026-09-07T14:00:00Z",
                      "startsAt": "2026-09-01T04:00:00Z",
                      "weekdays": 31,
                      "windowEndMinute": 1260,
                      "windowStartMinute": 540
                    },
                    "status": "running",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "Idempotent-Replayed": {
                "description": "`true` when this response is a replay of an earlier request with the same `Idempotency-Key`, rather than fresh work.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Apply the pre-flight exclusions and start dialling (requires Idempotency-Key)",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/campaigns/{id}/outcomes": {
      "get": {
        "description": "Counts by disposition, plus the tallies of your declared output variables — how many said yes, how many rescheduled — which is usually the number the campaign existed to produce.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.outcomes",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentOutcome": {},
                    "disposition": "answered",
                    "excludedReason": "invalid_number",
                    "status": "running"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignOutcomesResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Outcome tallies for the campaign funnel",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/campaigns/{id}/pause": {
      "post": {
        "description": "Calls already in flight finish. The campaign also pauses itself if the wallet falls below `autoPauseBelowPaise`, with `pausedReason` saying so.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.pause",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "archivedAt": null,
                    "autoPauseBelowPaise": 50000,
                    "completedAt": null,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "environment": "live",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "launchedAt": "2026-09-01T04:00:00Z",
                    "name": "COD confirmations — September",
                    "number": {
                      "e164": "+918045678901",
                      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                    },
                    "pacing": {
                      "callsPerMinute": 10,
                      "maxConcurrent": 4
                    },
                    "pausedReason": "operator",
                    "preflight": {
                      "callable": 0,
                      "checks": [
                        {
                          "outcome": "pass",
                          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                          "type": "time_window"
                        }
                      ],
                      "computedAt": "2026-09-01T03:58:12Z",
                      "estimatedCostPaise": {
                        "high": 480000,
                        "low": 120000
                      },
                      "excluded": "invalid_number",
                      "excludedE164s": {},
                      "total": 0,
                      "walletBalancePaise": 500000
                    },
                    "progress": {
                      "connected": 244,
                      "dialed": 320,
                      "excluded": 31,
                      "spentPaise": 146400,
                      "total": 500
                    },
                    "purpose": "transactional",
                    "retries": {
                      "attempts": 1,
                      "backoff": "linear",
                      "intervalMinutes": 60,
                      "on": [
                        "no_answer",
                        "busy"
                      ]
                    },
                    "schedule": {
                      "endsAt": "2026-09-07T14:00:00Z",
                      "startsAt": "2026-09-01T04:00:00Z",
                      "weekdays": 31,
                      "windowEndMinute": 1260,
                      "windowStartMinute": 540
                    },
                    "status": "running",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Stop dialling; resumable",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/campaigns/{id}/preflight": {
      "post": {
        "description": "What launching would actually do, without doing it. Returns how many recipients would be excluded and why, each counted against exactly one reason; the compliance checks that would run; an estimated cost band; and your balance. A `block` verdict here makes launch a `422`; a `warn` does not. Changes nothing.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.preflight",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "archivedAt": null,
                    "autoPauseBelowPaise": 50000,
                    "completedAt": null,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "environment": "live",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "launchedAt": "2026-09-01T04:00:00Z",
                    "name": "COD confirmations — September",
                    "number": {
                      "e164": "+918045678901",
                      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                    },
                    "pacing": {
                      "callsPerMinute": 10,
                      "maxConcurrent": 4
                    },
                    "pausedReason": "operator",
                    "preflight": {
                      "callable": 0,
                      "checks": [
                        {
                          "outcome": "pass",
                          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                          "type": "time_window"
                        }
                      ],
                      "computedAt": "2026-09-01T03:58:12Z",
                      "estimatedCostPaise": {
                        "high": 480000,
                        "low": 120000
                      },
                      "excluded": "invalid_number",
                      "excludedE164s": {},
                      "total": 0,
                      "walletBalancePaise": 500000
                    },
                    "progress": {
                      "connected": 244,
                      "dialed": 320,
                      "excluded": 31,
                      "spentPaise": 146400,
                      "total": 500
                    },
                    "purpose": "transactional",
                    "retries": {
                      "attempts": 1,
                      "backoff": "linear",
                      "intervalMinutes": 60,
                      "on": [
                        "no_answer",
                        "busy"
                      ]
                    },
                    "schedule": {
                      "endsAt": "2026-09-07T14:00:00Z",
                      "startsAt": "2026-09-01T04:00:00Z",
                      "weekdays": 31,
                      "windowEndMinute": 1260,
                      "windowStartMinute": 540
                    },
                    "status": "running",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Compute the pre-flight funnel, compliance checks and cost band",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/campaigns/{id}/recipients": {
      "delete": {
        "description": "Clears the list so you can upload a different one. Only meaningful while the campaign is still a draft.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.clearRecipients",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "removed": 0
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ClearRecipientsResultResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Remove every recipient — replacing the list",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      },
      "get": {
        "description": "A recipient row names its LAST attempt. For every call the campaign placed, retries included, filter `GET /v1/calls` by `campaign_id` instead.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.listRecipients",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "How many results to return. 1-100, defaulting to 25.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "examples": [
                25
              ],
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Opaque page cursor — pass `meta.pagination.cursor` from the previous response to fetch the next page. Its contents are an implementation detail; do not parse or construct one.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "examples": [
                "eyJjIjoiMjAyNi0wOC0yNVQwOToxNDoyMi4xMTFaIiwiaSI6IjlmMWMyZDg0LTRlM2EtNGY2Yy1iOTAyLTdkMWU4YTMzYzQ1MSJ9"
              ],
              "minLength": 1,
              "type": "string"
            }
          },
          {
            "description": "Only recipients in this state. Open set — handle an unrecognised value rather than throwing. Today: `pending`, `dialing`, `done`, `excluded`, `failed`.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "pending",
                "dialing",
                "done",
                "excluded",
                "failed"
              ],
              "examples": [
                "completed"
              ],
              "type": "string"
            },
            "x-known-values": [
              "pending",
              "dialing",
              "done",
              "excluded",
              "failed"
            ]
          },
          {
            "description": "Only recipients whose LAST attempt ended this way. A recipient row names one attempt — for every call a campaign placed, retries included, filter GET /v1/calls by campaign_id instead. Open set — handle an unrecognised value rather than throwing. Today: `answered`, `no_answer`, `busy`, `failed`, `voicemail`, `unknown`.",
            "in": "query",
            "name": "disposition",
            "required": false,
            "schema": {
              "enum": [
                "answered",
                "no_answer",
                "busy",
                "failed",
                "voicemail",
                "unknown"
              ],
              "examples": [
                "answered"
              ],
              "type": "string"
            },
            "x-known-values": [
              "answered",
              "no_answer",
              "busy",
              "failed",
              "voicemail",
              "unknown"
            ]
          },
          {
            "description": "Only recipients excluded at launch for this reason. Each excluded recipient is counted against exactly one reason. Open set — handle an unrecognised value rather than throwing. Today: `invalid_number`, `duplicate`, `dnc`, `frequency_cap`, `dnd_scrub`, `blocked_by_gate`.",
            "in": "query",
            "name": "excluded_reason",
            "required": false,
            "schema": {
              "enum": [
                "invalid_number",
                "duplicate",
                "dnc",
                "frequency_cap",
                "dnd_scrub",
                "blocked_by_gate"
              ],
              "examples": [
                "dnc"
              ],
              "type": "string"
            },
            "x-known-values": [
              "invalid_number",
              "duplicate",
              "dnc",
              "frequency_cap",
              "dnd_scrub",
              "blocked_by_gate"
            ]
          },
          {
            "description": "Substring match on the recipient number.",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "examples": [
                "9876"
              ],
              "maxLength": 20,
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "attemptCount": 0,
                      "costPaise": 0,
                      "createdAt": "2026-08-25T09:14:22Z",
                      "disposition": "answered",
                      "e164": "+919876543210",
                      "excludedReason": "invalid_number",
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "lastCallId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "nextAttemptAt": "2026-08-25T09:14:22Z",
                      "outcome": {},
                      "status": "running",
                      "talkSeconds": 0,
                      "variables": {}
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/CampaignRecipientResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "List a campaign's recipients and their outcomes",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      },
      "post": {
        "description": "Duplicates are counted rather than rejected, so a request that timed out can simply be resent without double-dialling anyone. A campaign holds at most 20,000 recipients. Add them before launching; the list is fixed once dialling starts.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.addRecipients",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "recipients": [
                  {
                    "e164": "+919876543210",
                    "variables": {
                      "name": "Priya",
                      "order_id": "AC-4417"
                    }
                  }
                ]
              },
              "schema": {
                "$ref": "#/components/schemas/AddRecipientsDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "added": 0,
                    "duplicates": 0,
                    "total": 0
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AddRecipientsResultResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Add up to 500 recipients. Retrying a batch is safe.",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/campaigns/{id}/recipients/{recipientId}/redial": {
      "post": {
        "description": "For the one number you want to try again after the run finished — a wrong time of day, a handset that was off. It respects the campaign calling window and the compliance gate like any other dial.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.redialRecipient",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The recipient's id.",
            "in": "path",
            "name": "recipientId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "archivedAt": null,
                    "autoPauseBelowPaise": 50000,
                    "completedAt": null,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "environment": "live",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "launchedAt": "2026-09-01T04:00:00Z",
                    "name": "COD confirmations — September",
                    "number": {
                      "e164": "+918045678901",
                      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                    },
                    "pacing": {
                      "callsPerMinute": 10,
                      "maxConcurrent": 4
                    },
                    "pausedReason": "operator",
                    "preflight": {
                      "callable": 0,
                      "checks": [
                        {
                          "outcome": "pass",
                          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                          "type": "time_window"
                        }
                      ],
                      "computedAt": "2026-09-01T03:58:12Z",
                      "estimatedCostPaise": {
                        "high": 480000,
                        "low": 120000
                      },
                      "excluded": "invalid_number",
                      "excludedE164s": {},
                      "total": 0,
                      "walletBalancePaise": 500000
                    },
                    "progress": {
                      "connected": 244,
                      "dialed": 320,
                      "excluded": 31,
                      "spentPaise": 146400,
                      "total": 500
                    },
                    "purpose": "transactional",
                    "retries": {
                      "attempts": 1,
                      "backoff": "linear",
                      "intervalMinutes": 60,
                      "on": [
                        "no_answer",
                        "busy"
                      ]
                    },
                    "schedule": {
                      "endsAt": "2026-09-07T14:00:00Z",
                      "startsAt": "2026-09-01T04:00:00Z",
                      "weekdays": 31,
                      "windowEndMinute": 1260,
                      "windowStartMinute": 540
                    },
                    "status": "running",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Manually queue one settled recipient for another call. A completed campaign wakes up for it.",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/campaigns/{id}/resume": {
      "post": {
        "description": "Picks up where it stopped, on the version of the agent it launched with. Top the wallet up first if it paused for low balance, or it will pause again.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.resume",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "archivedAt": null,
                    "autoPauseBelowPaise": 50000,
                    "completedAt": null,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "environment": "live",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "launchedAt": "2026-09-01T04:00:00Z",
                    "name": "COD confirmations — September",
                    "number": {
                      "e164": "+918045678901",
                      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                    },
                    "pacing": {
                      "callsPerMinute": 10,
                      "maxConcurrent": 4
                    },
                    "pausedReason": "operator",
                    "preflight": {
                      "callable": 0,
                      "checks": [
                        {
                          "outcome": "pass",
                          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                          "type": "time_window"
                        }
                      ],
                      "computedAt": "2026-09-01T03:58:12Z",
                      "estimatedCostPaise": {
                        "high": 480000,
                        "low": 120000
                      },
                      "excluded": "invalid_number",
                      "excludedE164s": {},
                      "total": 0,
                      "walletBalancePaise": 500000
                    },
                    "progress": {
                      "connected": 244,
                      "dialed": 320,
                      "excluded": 31,
                      "spentPaise": 146400,
                      "total": 500
                    },
                    "purpose": "transactional",
                    "retries": {
                      "attempts": 1,
                      "backoff": "linear",
                      "intervalMinutes": 60,
                      "on": [
                        "no_answer",
                        "busy"
                      ]
                    },
                    "schedule": {
                      "endsAt": "2026-09-07T14:00:00Z",
                      "startsAt": "2026-09-01T04:00:00Z",
                      "weekdays": 31,
                      "windowEndMinute": 1260,
                      "windowStartMinute": 540
                    },
                    "status": "running",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Resume a paused campaign",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/campaigns/{id}/stop": {
      "post": {
        "description": "There is no resuming from here. Pause instead if you might want to continue.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.stop",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "archivedAt": null,
                    "autoPauseBelowPaise": 50000,
                    "completedAt": null,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "environment": "live",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "launchedAt": "2026-09-01T04:00:00Z",
                    "name": "COD confirmations — September",
                    "number": {
                      "e164": "+918045678901",
                      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                    },
                    "pacing": {
                      "callsPerMinute": 10,
                      "maxConcurrent": 4
                    },
                    "pausedReason": "operator",
                    "preflight": {
                      "callable": 0,
                      "checks": [
                        {
                          "outcome": "pass",
                          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                          "type": "time_window"
                        }
                      ],
                      "computedAt": "2026-09-01T03:58:12Z",
                      "estimatedCostPaise": {
                        "high": 480000,
                        "low": 120000
                      },
                      "excluded": "invalid_number",
                      "excludedE164s": {},
                      "total": 0,
                      "walletBalancePaise": 500000
                    },
                    "progress": {
                      "connected": 244,
                      "dialed": 320,
                      "excluded": 31,
                      "spentPaise": 146400,
                      "total": 500
                    },
                    "purpose": "transactional",
                    "retries": {
                      "attempts": 1,
                      "backoff": "linear",
                      "intervalMinutes": 60,
                      "on": [
                        "no_answer",
                        "busy"
                      ]
                    },
                    "schedule": {
                      "endsAt": "2026-09-07T14:00:00Z",
                      "startsAt": "2026-09-01T04:00:00Z",
                      "weekdays": 31,
                      "windowEndMinute": 1260,
                      "windowStartMinute": 540
                    },
                    "status": "running",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "End the campaign. Terminal — the remaining recipients are abandoned.",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/campaigns/{id}/unarchive": {
      "post": {
        "description": "The inverse of archiving. Nothing else changes.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "campaigns.unarchive",
        "parameters": [
          {
            "description": "The campaign's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agent": {
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Order confirmation"
                    },
                    "archivedAt": null,
                    "autoPauseBelowPaise": 50000,
                    "completedAt": null,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "environment": "live",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "launchedAt": "2026-09-01T04:00:00Z",
                    "name": "COD confirmations — September",
                    "number": {
                      "e164": "+918045678901",
                      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
                    },
                    "pacing": {
                      "callsPerMinute": 10,
                      "maxConcurrent": 4
                    },
                    "pausedReason": "operator",
                    "preflight": {
                      "callable": 0,
                      "checks": [
                        {
                          "outcome": "pass",
                          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
                          "type": "time_window"
                        }
                      ],
                      "computedAt": "2026-09-01T03:58:12Z",
                      "estimatedCostPaise": {
                        "high": 480000,
                        "low": 120000
                      },
                      "excluded": "invalid_number",
                      "excludedE164s": {},
                      "total": 0,
                      "walletBalancePaise": 500000
                    },
                    "progress": {
                      "connected": 244,
                      "dialed": 320,
                      "excluded": 31,
                      "spentPaise": 146400,
                      "total": 500
                    },
                    "purpose": "transactional",
                    "retries": {
                      "attempts": 1,
                      "backoff": "linear",
                      "intervalMinutes": 60,
                      "on": [
                        "no_answer",
                        "busy"
                      ]
                    },
                    "schedule": {
                      "endsAt": "2026-09-07T14:00:00Z",
                      "startsAt": "2026-09-01T04:00:00Z",
                      "weekdays": 31,
                      "windowEndMinute": 1260,
                      "windowStartMinute": 540
                    },
                    "status": "running",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CampaignResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Return an archived campaign to the list",
        "tags": [
          "campaigns"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/catalog/voice": {
      "get": {
        "description": "The legal values for an agent speech stack, fetched from the provider rather than hardcoded — so this changes without a deploy and every list here is an OPEN set. 🔴 A voice belongs to a specific model version: the `(ttsModel, ttsVoice)` pair is the constraint, not the voice name, and each speaker names the model it belongs to. A retired voice is marked deprecated rather than removed, so an agent already using one keeps working.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "catalog.voice",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "defaultAgentLanguages": [
                      "en-IN",
                      "hi-IN"
                    ],
                    "fetchedAt": "2026-08-25T04:00:00Z",
                    "languageNames": {},
                    "llm": {
                      "defaults": {
                        "model": "gemini-2.5-flash"
                      },
                      "models": [
                        {
                          "deprecated": true,
                          "description": "Latest speech model. Adds `temperature`; drops `pitch` and `loudness`.",
                          "id": "gemini-2.5-flash",
                          "label": "Bulbul v3",
                          "provider": "gemini"
                        }
                      ]
                    },
                    "previewSamples": {},
                    "source": "spec",
                    "stt": {
                      "autoDetect": "auto",
                      "defaults": {
                        "language": "auto",
                        "mode": "transcribe",
                        "model": "saaras:v3"
                      },
                      "languages": [
                        "en-IN",
                        "hi-IN",
                        "gu-IN",
                        "ta-IN"
                      ],
                      "models": [
                        {
                          "deprecated": true,
                          "description": "Latest speech model. Adds `temperature`; drops `pitch` and `loudness`.",
                          "id": "saaras:v3",
                          "label": "Bulbul v3",
                          "supportsModes": true
                        }
                      ],
                      "modes": [
                        {
                          "description": "Transcribes faithfully in the language spoken, without translating.",
                          "id": "transcribe",
                          "label": "Bulbul v3"
                        }
                      ]
                    },
                    "tts": {
                      "defaults": {
                        "model": "bulbul:v3",
                        "speaker": "anushka"
                      },
                      "languages": [
                        "en-IN",
                        "hi-IN",
                        "gu-IN"
                      ],
                      "models": [
                        {
                          "deprecated": true,
                          "description": "Latest speech model. Adds `temperature`; drops `pitch` and `loudness`.",
                          "id": "bulbul:v3",
                          "label": "Bulbul v3",
                          "options": [
                            {
                              "default": 1,
                              "description": "Latest speech model. Adds `temperature`; drops `pitch` and `loudness`.",
                              "key": "pace",
                              "label": "Bulbul v3",
                              "max": 2,
                              "min": 0.5,
                              "step": 0.1
                            }
                          ]
                        }
                      ],
                      "sampleRates": [
                        8000,
                        16000,
                        22050
                      ],
                      "speakers": [
                        {
                          "deprecated": true,
                          "gender": "female",
                          "id": "simran",
                          "label": "Bulbul v3",
                          "models": [
                            "bulbul:v3"
                          ]
                        }
                      ]
                    },
                    "version": "c7f2a9e1b4d6"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/VoiceCatalogResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Sarvam models, languages and voices available to an agent",
        "tags": [
          "catalog"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/compliance/call-outcomes": {
      "post": {
        "description": "Closes the audit loop on a verdict. `opt_out` revokes consents and suppresses the number for 90 days; `complaint` suppresses it permanently.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "complianceChecks.recordOutcome",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "callReference": "acme-crm-4417",
                "checkId": "8814",
                "durationSeconds": 45,
                "e164": "+919876543210",
                "notes": "Customer asked to be called after 6pm.",
                "occurredAt": "2026-08-25T09:14:22Z",
                "outcome": "connected"
              },
              "schema": {
                "$ref": "#/components/schemas/CallOutcomeDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "consentsRevoked": 0,
                    "e164": "+919876543210",
                    "id": "8814",
                    "outcome": "connected",
                    "suppressed": true
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CallOutcomeResultResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Report what happened to a call you placed yourself",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/compliance/check": {
      "post": {
        "description": "Runs the exact checks an outbound call runs (DLT, A2P declaration, calling window, DNC, carrier DND, consent) and records the same audit rows. Returns the verdict instead of enforcing it — use it to pre-flight a number you dial on your own infrastructure.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "complianceChecks.check",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "e164": "+919876543210",
                "purpose": "promotional"
              },
              "schema": {
                "$ref": "#/components/schemas/CheckComplianceDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "allowed": true,
                    "blockedBy": null,
                    "checks": [
                      {
                        "callId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                        "checkType": "dnc",
                        "createdAt": "2026-08-25T09:14:22Z",
                        "detail": {},
                        "e164": "+919876543210",
                        "enforced": true,
                        "id": "8814",
                        "outcome": "pass",
                        "reason": "Asked to be removed during a call on 2026-08-20.",
                        "source": "internal"
                      }
                    ],
                    "e164": "+919876543210",
                    "purpose": "promotional"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ComplianceVerdictResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Run the pre-dial compliance gate for one number, without dialling",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/compliance/check/batch": {
      "post": {
        "description": "Each number runs the full gate and is metered as its own verdict, so a batch of 100 costs 100 verdicts. A campaign-sized list belongs in a campaign, which has a pre-flight built for that scale.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "complianceChecks.checkBatch",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "e164s": [
                  "+919876543210",
                  "+919812345678"
                ],
                "purpose": "promotional"
              },
              "schema": {
                "$ref": "#/components/schemas/CheckComplianceBatchDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "allowed": true,
                      "blockedBy": null,
                      "checks": [
                        {
                          "callId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                          "checkType": "dnc",
                          "createdAt": "2026-08-25T09:14:22Z",
                          "detail": {},
                          "e164": "+919876543210",
                          "enforced": true,
                          "id": "8814",
                          "outcome": "pass",
                          "reason": "Asked to be removed during a call on 2026-08-20.",
                          "source": "internal"
                        }
                      ],
                      "e164": "+919876543210",
                      "purpose": "promotional"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/ComplianceVerdictResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Pre-flight up to 100 numbers in one call",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/compliance/checks": {
      "get": {
        "description": "Every check ever recorded, from dials and from standalone verdicts alike. Append-only at the database level — this is the audit trail, so nothing here can be edited or deleted after the fact.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "complianceChecks.list",
        "parameters": [
          {
            "description": "How many results to return. 1-100, defaulting to 25.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "examples": [
                25
              ],
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Opaque page cursor from the previous response.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "examples": [
                "8814"
              ],
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Only checks of this kind. The six that run before a dial are dlt, a2p, time_window, dnc, carrier_dnd and consent; the rest record changes you made. Open set — handle an unrecognised value rather than throwing. Today: `dlt`, `a2p`, `time_window`, `dnc`, `scrub`, `carrier_dnd`, `consent`, `enforcement_change`, `profile_change`, `call_outcome`, `suppression_change`.",
            "in": "query",
            "name": "check_type",
            "required": false,
            "schema": {
              "enum": [
                "dlt",
                "a2p",
                "time_window",
                "dnc",
                "scrub",
                "carrier_dnd",
                "consent",
                "enforcement_change",
                "profile_change",
                "call_outcome",
                "suppression_change"
              ],
              "examples": [
                "dnc"
              ],
              "type": "string"
            },
            "x-known-values": [
              "dlt",
              "a2p",
              "time_window",
              "dnc",
              "scrub",
              "carrier_dnd",
              "consent",
              "enforcement_change",
              "profile_change",
              "call_outcome",
              "suppression_change"
            ]
          },
          {
            "description": "Only checks that ended this way. Note that carrier_dnd can only ever warn — the authoritative register is not exposed to senders, so it is advisory by design. Open set — handle an unrecognised value rather than throwing. Today: `pass`, `warn`, `block`, `error`.",
            "in": "query",
            "name": "outcome",
            "required": false,
            "schema": {
              "enum": [
                "pass",
                "warn",
                "block",
                "error"
              ],
              "examples": [
                "block"
              ],
              "type": "string"
            },
            "x-known-values": [
              "pass",
              "warn",
              "block",
              "error"
            ]
          },
          {
            "description": "Only checks about this number.",
            "in": "query",
            "name": "e164",
            "required": false,
            "schema": {
              "examples": [
                "+919876543210"
              ],
              "pattern": "^\\+91\\d{10,11}$",
              "type": "string"
            }
          },
          {
            "description": "Only checks recorded for this call. A standalone verdict has no call id.",
            "in": "query",
            "name": "call_id",
            "required": false,
            "schema": {
              "examples": [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ],
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "description": "Inclusive lower bound on when the check ran.",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "examples": [
                "2026-08-01"
              ],
              "type": "string"
            }
          },
          {
            "description": "Exclusive upper bound on when the check ran.",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "examples": [
                "2026-09-01"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "callId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "checkType": "dnc",
                      "createdAt": "2026-08-25T09:14:22Z",
                      "detail": {},
                      "e164": "+919876543210",
                      "enforced": true,
                      "id": "8814",
                      "outcome": "pass",
                      "reason": "Asked to be removed during a call on 2026-08-20.",
                      "source": "internal"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/ComplianceCheckResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Pre-dial compliance checks, newest first",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/compliance/evidence": {
      "get": {
        "description": "Every check, consent record, outcome and suppression we hold for a number — the document to hand an access provider when a complaint lands.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "complianceChecks.evidence",
        "parameters": [
          {
            "description": "The number to assemble evidence for. Returns every check, consent record, suppression entry and reported outcome Tone holds about it.",
            "in": "query",
            "name": "e164",
            "required": true,
            "schema": {
              "examples": [
                "+919876543210"
              ],
              "pattern": "^\\+91\\d{10,11}$",
              "type": "string"
            }
          },
          {
            "description": "Inclusive lower bound. Omit for everything on record.",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "examples": [
                "2026-08-01"
              ],
              "type": "string"
            }
          },
          {
            "description": "Exclusive upper bound.",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "examples": [
                "2026-09-01"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "checks": [
                      {
                        "callId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                        "checkType": "dnc",
                        "createdAt": "2026-08-25T09:14:22Z",
                        "detail": {},
                        "e164": "+919876543210",
                        "enforced": true,
                        "id": "8814",
                        "outcome": "pass",
                        "reason": "Asked to be removed during a call on 2026-08-20.",
                        "source": "internal"
                      }
                    ],
                    "consents": [
                      {
                        "active": true,
                        "capturedAt": "2026-08-20T11:02:00Z",
                        "createdAt": "2026-08-25T09:14:22Z",
                        "e164": "+919876543210",
                        "evidenceRef": "form-sub-88213",
                        "expiresAt": "2026-11-23T09:14:22Z",
                        "id": "8814",
                        "kind": "explicit",
                        "purpose": "promotional",
                        "revokedAt": null,
                        "revokedReason": null,
                        "scope": "Order updates and delivery reminders.",
                        "source": "api"
                      }
                    ],
                    "e164": "+919876543210",
                    "generatedAt": "2026-08-25T09:14:22Z",
                    "outcomes": [
                      {
                        "callId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                        "checkType": "dnc",
                        "createdAt": "2026-08-25T09:14:22Z",
                        "detail": {},
                        "e164": "+919876543210",
                        "enforced": true,
                        "id": "8814",
                        "outcome": "pass",
                        "reason": "Asked to be removed during a call on 2026-08-20.",
                        "source": "internal"
                      }
                    ],
                    "suppression": {
                      "createdAt": "2026-08-25T09:14:22Z",
                      "e164": "+919876543210",
                      "expiresAt": "2026-11-23T09:14:22Z",
                      "id": "8814",
                      "reason": "Asked to be removed during a call on 2026-08-20.",
                      "removedAt": null,
                      "removedReason": null,
                      "source": "manual",
                      "sourceCallId": null
                    },
                    "truncated": true,
                    "window": {
                      "from": "2026-08-01T00:00:00Z",
                      "to": "2026-08-25T00:00:00Z"
                    }
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/EvidencePackResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "The evidence pack for one number",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/compliance/evidence-records": {
      "get": {
        "description": "One tamper-evident record per call attempt — completed calls AND refused dials. Each carries the full basis on which the attempt was allowed or refused, hashed and chained to its predecessor so any alteration, deletion or reordering is detectable.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "evidenceRecords.list",
        "parameters": [
          {
            "description": "How many results to return. 1-100, defaulting to 25.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "examples": [
                25
              ],
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Opaque page cursor from the previous response.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "examples": [
                "4210"
              ],
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Only records about this number.",
            "in": "query",
            "name": "e164",
            "required": false,
            "schema": {
              "examples": [
                "+919876543210"
              ],
              "pattern": "^\\+91\\d{10,11}$",
              "type": "string"
            }
          },
          {
            "description": "Only records of this kind. Refusals are evidence too — a ledger of only successes proves nothing about whether the rules were honoured when they bit. Open set — handle an unrecognised value rather than throwing. Today: `completed_call`, `blocked_dial`.",
            "in": "query",
            "name": "kind",
            "required": false,
            "schema": {
              "enum": [
                "completed_call",
                "blocked_dial"
              ],
              "examples": [
                "completed_call"
              ],
              "type": "string"
            },
            "x-known-values": [
              "completed_call",
              "blocked_dial"
            ]
          },
          {
            "description": "The record sealing this call.",
            "in": "query",
            "name": "call_id",
            "required": false,
            "schema": {
              "examples": [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ],
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "description": "Only records from this campaign, refusals included.",
            "in": "query",
            "name": "campaign_id",
            "required": false,
            "schema": {
              "examples": [
                "2b7c9e10-88d1-4f22-9c33-5a6b7c8d9e0f"
              ],
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "callId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "campaignId": null,
                      "chainSeq": "4211",
                      "content": {},
                      "contentHash": "a3f1…",
                      "e164": "+919876543210",
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "kind": "completed_call",
                      "prevHash": "0000…",
                      "recordHash": "b7e2…",
                      "sealedAt": "2026-08-31T09:14:22Z"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/EvidenceRecordResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Sealed evidence records, newest first",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/compliance/evidence-records/verify": {
      "get": {
        "description": "Re-hashes every record in the requested slice and re-checks every link. An edited record fails its content hash; a deleted or reordered one breaks the chain. Long chains verify in slices — when `complete` is false, continue from `throughSeq + 1`.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "evidenceRecords.verify",
        "parameters": [
          {
            "description": "Start of the slice to verify, inclusive. Defaults to 1 — the beginning of the chain.",
            "in": "query",
            "name": "from_seq",
            "required": false,
            "schema": {
              "examples": [
                "1"
              ],
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "End of the slice, inclusive. Defaults to the head of the chain.",
            "in": "query",
            "name": "to_seq",
            "required": false,
            "schema": {
              "examples": [
                "5000"
              ],
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "brokenReason": null,
                    "checked": 0,
                    "complete": true,
                    "firstBrokenSeq": null,
                    "fromSeq": "1",
                    "throughSeq": "5000",
                    "valid": true,
                    "verifiedAt": "2026-08-31T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ChainVerificationResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Verify the evidence chain's integrity",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/compliance/evidence-records/{id}": {
      "get": {
        "description": "The full evidence document plus its seal: the content hash, the previous record’s hash, and the chain position. Recompute sha256 over the canonical content to prove the document was not altered; walk the verify endpoint to prove the whole chain.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "evidenceRecords.get",
        "parameters": [
          {
            "description": "The evidence record's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "callId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "campaignId": null,
                    "chainSeq": "4211",
                    "content": {},
                    "contentHash": "a3f1…",
                    "e164": "+919876543210",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "kind": "completed_call",
                    "prevHash": "0000…",
                    "recordHash": "b7e2…",
                    "sealedAt": "2026-08-31T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/EvidenceRecordResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "One sealed evidence record",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/consent": {
      "get": {
        "description": "Consent is purpose-scoped, so a number can appear several times — once per purpose. `active=true` filters to the records that would satisfy the gate right now.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "consent.list",
        "parameters": [
          {
            "description": "How many records to return. 1-100.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "examples": [
                25
              ],
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Opaque page cursor from the previous response.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only records for this number.",
            "in": "query",
            "name": "e164",
            "required": false,
            "schema": {
              "examples": [
                "+919876543210"
              ],
              "pattern": "^\\+91\\d{10,11}$",
              "type": "string"
            }
          },
          {
            "description": "Only records covering this purpose. Open set — handle an unrecognised value rather than throwing. Today: `promotional`, `service`, `transactional`, `collections`.",
            "in": "query",
            "name": "purpose",
            "required": false,
            "schema": {
              "enum": [
                "promotional",
                "service",
                "transactional",
                "collections"
              ],
              "examples": [
                "promotional"
              ],
              "type": "string"
            },
            "x-known-values": [
              "promotional",
              "service",
              "transactional",
              "collections"
            ]
          },
          {
            "description": "Only records that would satisfy the gate right now — neither revoked nor expired.",
            "in": "query",
            "name": "active",
            "required": false,
            "schema": {
              "enum": [
                "true",
                "false"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "active": true,
                      "capturedAt": "2026-08-20T11:02:00Z",
                      "createdAt": "2026-08-25T09:14:22Z",
                      "e164": "+919876543210",
                      "evidenceRef": "form-sub-88213",
                      "expiresAt": "2026-11-23T09:14:22Z",
                      "id": "8814",
                      "kind": "explicit",
                      "purpose": "promotional",
                      "revokedAt": null,
                      "revokedReason": null,
                      "scope": "Order updates and delivery reminders.",
                      "source": "api"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/ConsentRecordResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Consent records, newest first",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      },
      "post": {
        "description": "Explicit transactional consent expires after 7 days by policy; inferred consent must carry its own expiry. Verified explicit consent is what lets a promotional call pass the gate.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "consent.record",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "capturedAt": "2026-08-20T11:02:00Z",
                "e164": "+919876543210",
                "evidenceRef": "form-sub-88213",
                "expiresAt": "2026-08-27T11:02:00Z",
                "kind": "explicit",
                "purpose": "promotional",
                "scope": "Order updates and delivery reminders for orders placed on acme.example.",
                "source": "web_form"
              },
              "schema": {
                "$ref": "#/components/schemas/RecordConsentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "active": true,
                    "capturedAt": "2026-08-20T11:02:00Z",
                    "createdAt": "2026-08-25T09:14:22Z",
                    "e164": "+919876543210",
                    "evidenceRef": "form-sub-88213",
                    "expiresAt": "2026-11-23T09:14:22Z",
                    "id": "8814",
                    "kind": "explicit",
                    "purpose": "promotional",
                    "revokedAt": null,
                    "revokedReason": null,
                    "scope": "Order updates and delivery reminders.",
                    "source": "api"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ConsentRecordResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Record a consent",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/consent/bulk": {
      "post": {
        "description": "Up to 1,000 per request. Rows are accepted INDIVIDUALLY: a record that violates policy (an inferred consent missing `expiresAt`, a number inside its 90-day opt-out lockout) is refused with its index and reason while the rest import — fix and resubmit only the rejected rows. 🔴 Set `capturedAt` on every imported record: it defaults to now, which dates your whole back catalogue to the day of the import.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "consent.recordMany",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "records": [
                  {
                    "capturedAt": "2026-08-20T11:02:00Z",
                    "e164": "+919876543210",
                    "evidenceRef": "form-sub-88213",
                    "expiresAt": "2026-08-27T11:02:00Z",
                    "kind": "explicit",
                    "purpose": "promotional",
                    "scope": "Order updates and delivery reminders for orders placed on acme.example.",
                    "source": "web_form"
                  }
                ]
              },
              "schema": {
                "$ref": "#/components/schemas/ConsentBulkDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "imported": 0,
                    "rejected": [
                      {
                        "code": "conflict",
                        "e164": "+919876543210",
                        "index": 0,
                        "message": "This number opted out and is inside the 90-day re-consent lockout."
                      }
                    ]
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ConsentBulkResultResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Import many consents at once (CSV upload, CRM export)",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/consent/opt-out": {
      "post": {
        "description": "Revokes every active consent for the number and suppresses it for the 90-day re-consent lockout, in one transaction.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "consent.optOut",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "e164": "+919876543210",
                "reason": "Said \"do not call me again\" during the call."
              },
              "schema": {
                "$ref": "#/components/schemas/OptOutDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "revoked": 0
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/OptOutResultResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "A recipient opted out",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/consent/{id}/revoke": {
      "post": {
        "description": "⚠️ Revoking consent does NOT stop calls on its own: the ledger passes or warns, it never blocks. Only the suppression list blocks. If the recipient asked not to be called, use the opt-out endpoint, which revokes and suppresses in one transaction.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "consent.revoke",
        "parameters": [
          {
            "description": "The consent record's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "reason": "Recipient asked to be removed by email."
              },
              "schema": {
                "$ref": "#/components/schemas/RevokeConsentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "active": true,
                    "capturedAt": "2026-08-20T11:02:00Z",
                    "createdAt": "2026-08-25T09:14:22Z",
                    "e164": "+919876543210",
                    "evidenceRef": "form-sub-88213",
                    "expiresAt": "2026-11-23T09:14:22Z",
                    "id": "8814",
                    "kind": "explicit",
                    "purpose": "promotional",
                    "revokedAt": null,
                    "revokedReason": null,
                    "scope": "Order updates and delivery reminders.",
                    "source": "api"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ConsentRecordResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Revoke one consent record",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/contact-sales": {
      "post": {
        "description": "The public enquiry form behind usetone.ai. No credential required.",
        "operationId": "contactSales.submit",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "building": [
                  "Order confirmations"
                ],
                "companyName": "Acme Retail",
                "companySize": "11-50",
                "companyWebsite": "https://acme.example",
                "details": "We place about 5,000 COD confirmation calls a week.",
                "email": "priya@example.com",
                "firstName": "Priya",
                "lastName": "Sharma",
                "lookingFor": [
                  "Outbound calling",
                  "TRAI compliance"
                ],
                "phone": "+919876543210"
              },
              "schema": {
                "$ref": "#/components/schemas/CreateContactSubmissionDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": null
                },
                "schema": {
                  "properties": {
                    "data": {
                      "description": "The resource, or an array of them on a list endpoint. Null for endpoints that return no body."
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [],
        "summary": "Submit a contact-sales enquiry",
        "tags": [
          "contact-sales"
        ],
        "x-tone-audience": "public",
        "x-tone-scopes": []
      }
    },
    "/v1/dnc": {
      "get": {
        "description": "Your own suppression list — the only list the gate hard-blocks on. Search accepts whatever someone types: `+91 98765 43210`, `09876543210` and `4321` all work.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "dnc.list",
        "parameters": [
          {
            "description": "How many results to return. 1-100, defaulting to 25.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "examples": [
                25
              ],
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Opaque page cursor — pass `meta.pagination.cursor` from the previous response to fetch the next page. Its contents are an implementation detail; do not parse or construct one.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "examples": [
                "eyJjIjoiMjAyNi0wOC0yNVQwOToxNDoyMi4xMTFaIiwiaSI6IjlmMWMyZDg0LTRlM2EtNGY2Yy1iOTAyLTdkMWU4YTMzYzQ1MSJ9"
              ],
              "minLength": 1,
              "type": "string"
            }
          },
          {
            "description": "Only entries added this way. Open set — handle an unrecognised value rather than throwing. Today: `manual`, `csv`, `api`, `caller_request`, `complaint`, `carrier_rejection`.",
            "in": "query",
            "name": "source",
            "required": false,
            "schema": {
              "enum": [
                "manual",
                "csv",
                "api",
                "caller_request",
                "complaint",
                "carrier_rejection"
              ],
              "examples": [
                "manual"
              ],
              "type": "string"
            },
            "x-known-values": [
              "manual",
              "csv",
              "api",
              "caller_request",
              "complaint",
              "carrier_rejection"
            ]
          },
          {
            "description": "Whether to include entries whose 90-day lockout has already elapsed. Open set — handle an unrecognised value rather than throwing. Today: `all`, `active`, `permanent`, `lockout`, `lapsed`, `removed`.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "default": "all",
              "enum": [
                "all",
                "active",
                "permanent",
                "lockout",
                "lapsed",
                "removed"
              ],
              "examples": [
                "all"
              ],
              "type": "string"
            },
            "x-known-values": [
              "all",
              "active",
              "permanent",
              "lockout",
              "lapsed",
              "removed"
            ]
          },
          {
            "description": "Digits to find. A full number matches exactly, a fragment matches anywhere in the number. Deliberately forgiving about formatting — +91 98765 43210, 09876543210 and 4321 all work.",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "examples": [
                "9876"
              ],
              "maxLength": 20,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "createdAt": "2026-08-25T09:14:22Z",
                      "e164": "+919876543210",
                      "expiresAt": "2026-11-23T09:14:22Z",
                      "id": "8814",
                      "reason": "Asked to be removed during a call on 2026-08-20.",
                      "removedAt": null,
                      "removedReason": null,
                      "source": "manual",
                      "sourceCallId": null
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/DncEntryResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Numbers on the Do-Not-Call list",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      },
      "post": {
        "description": "Adding a number already on the list is a no-op rather than an error, so a replayed webhook or a retried job cannot fail here. Use `lockout90d` for an opt-out, which becomes contactable again on a date, rather than a permanent suppression.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "dnc.add",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "e164": "+919876543210",
                "lockout90d": false,
                "reason": "Asked to be removed during a call on 2026-08-20.",
                "source": "manual"
              },
              "schema": {
                "$ref": "#/components/schemas/AddDncDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "createdAt": "2026-08-25T09:14:22Z",
                    "e164": "+919876543210",
                    "expiresAt": "2026-11-23T09:14:22Z",
                    "id": "8814",
                    "reason": "Asked to be removed during a call on 2026-08-20.",
                    "removedAt": null,
                    "removedReason": null,
                    "source": "manual",
                    "sourceCallId": null
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/DncEntryResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Suppress a number (idempotent)",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/dnc/bulk": {
      "post": {
        "description": "Up to 1,000 per request, as one transaction — it either all lands or none of it does. This is how you bring an existing suppression list with you.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "dnc.addMany",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "entries": [
                  {
                    "e164": "+919876543210",
                    "lockout90d": false,
                    "reason": "Asked to be removed during a call on 2026-08-20.",
                    "source": "manual"
                  }
                ]
              },
              "schema": {
                "$ref": "#/components/schemas/AddDncBulkDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "createdAt": "2026-08-25T09:14:22Z",
                      "e164": "+919876543210",
                      "expiresAt": "2026-11-23T09:14:22Z",
                      "id": "8814",
                      "reason": "Asked to be removed during a call on 2026-08-20.",
                      "removedAt": null,
                      "removedReason": null,
                      "source": "manual",
                      "sourceCallId": null
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/DncEntryResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Suppress many numbers at once (CSV upload)",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/dnc/{id}": {
      "delete": {
        "deprecated": true,
        "description": "⚠️ Always refuses. Lifting a suppression is a deliberate, reasoned act: it now requires a dashboard session and a written justification (`POST /v1/dnc/{id}/remove`, session-only), and is recorded in the audit trail. API keys can ADD suppressions — an opt-out must land within seconds — but can no longer silently make an opted-out number callable again.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "dnc.remove",
        "parameters": [
          {
            "description": "The suppression entry's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "content": {
              "application/json": {
                "example": {
                  "data": null
                },
                "schema": {
                  "properties": {
                    "data": {
                      "description": "The resource, or an array of them on a list endpoint. Null for endpoints that return no body."
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Deprecated — lifting a suppression now requires the dashboard",
        "tags": [
          "compliance"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/events": {
      "get": {
        "description": "The reconciliation path when a webhook delivery was missed, and the debugging path for \"what exactly did Tone send\". Deliveries are at-least-once and unordered, so dedupe on the event id.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "events.list",
        "parameters": [
          {
            "description": "How many results to return. 1-100, defaulting to 25.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "examples": [
                25
              ],
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Only events of this type, for example call.completed. Treat the set as open — new types are added without notice.",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "examples": [
                "call.completed"
              ],
              "maxLength": 64,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "createdAt": "2026-08-25T09:14:22Z",
                      "delivery": {
                        "attempts": 0,
                        "deliveredAt": "2026-08-25T09:14:03Z",
                        "endpointId": "2b7c1d90-4e5f-4a6b-8c9d-0e1f2a3b4c5d",
                        "lastStatus": 0,
                        "status": "pending"
                      },
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "subjectId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "subjectType": "call",
                      "type": "call.initiated"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/EventSummaryResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Recent events (newest first, 30-day retention)",
        "tags": [
          "events"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/events/{id}": {
      "get": {
        "description": "⚠️ The payload is RE-RENDERED from the resource as it stands now, not replayed from the signed bytes that were delivered. A transcript that landed after delivery will be present here and absent from what your endpoint received. Use it to understand an event, not to re-verify a signature.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "events.get",
        "parameters": [
          {
            "description": "The event's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "createdAt": "2026-08-25T09:14:22Z",
                    "delivery": {
                      "attempts": 0,
                      "deliveredAt": "2026-08-25T09:14:03Z",
                      "endpointId": "2b7c1d90-4e5f-4a6b-8c9d-0e1f2a3b4c5d",
                      "lastStatus": 0,
                      "status": "pending"
                    },
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "payload": {
                      "created_at": "2026-08-25T09:14:22Z",
                      "data": {},
                      "id": "evt_01J9Z2K3M4N5P6Q7R8S9T0",
                      "links": {
                        "recording": "/v1/calls/9f1c2d84-5b6a-4c3d-8e2f-1a0b9c8d7e6f/recording",
                        "self": "/v1/calls/9f1c2d84-5b6a-4c3d-8e2f-1a0b9c8d7e6f",
                        "transcript": "/v1/calls/9f1c2d84-5b6a-4c3d-8e2f-1a0b9c8d7e6f/transcript"
                      },
                      "type": "call.completed"
                    },
                    "subjectId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "subjectType": "call",
                    "type": "call.initiated"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/EventDetailResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "One event, with its payload re-rendered from current state",
        "tags": [
          "events"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/integrations/webhooks": {
      "get": {
        "description": "Every endpoint you have registered, with what it subscribes to and whether it is still enabled.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "integrations.listWebhooks",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "consecutiveFailures": 0,
                      "createdAt": "2026-08-25T09:14:22Z",
                      "description": "Production — order service",
                      "disabledReason": null,
                      "enabled": true,
                      "events": [
                        "call.completed",
                        "campaign.finished"
                      ],
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "url": "https://hooks.acme.example/tone"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/WebhookEndpointResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Webhook endpoints",
        "tags": [
          "integrations"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      },
      "post": {
        "description": "Must be a public `https://` URL — private and link-local addresses are refused at save time rather than discovered at delivery time. The signing secret is returned once, here. Subscribe only to what you consume: every delivery is retried up to 14 times over roughly a day.\n\n**Requires the `admin` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "integrations.createWebhook",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "description": "Production CRM sync",
                "enabled": true,
                "events": [
                  "call.completed",
                  "call.failed"
                ],
                "url": "https://hooks.example.com/tone"
              },
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookEndpointDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "consecutiveFailures": 0,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "description": "Production — order service",
                    "disabledReason": null,
                    "enabled": true,
                    "events": [
                      "call.completed",
                      "campaign.finished"
                    ],
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "secret": "whsec_3f1a7f6e2b4c4d1e9a8b5c6d7e8f9a0b",
                    "url": "https://hooks.acme.example/tone"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CreatedWebhookEndpointResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Add a webhook endpoint",
        "tags": [
          "integrations"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "admin"
        ]
      }
    },
    "/v1/integrations/webhooks/deliveries": {
      "get": {
        "description": "What was sent, what your endpoint answered and how many attempts it took. The place to look when an integration \"missed\" an event.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "integrations.deliveries",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "attempts": 0,
                      "callId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "createdAt": "2026-08-25T09:14:22Z",
                      "deliveredAt": "2026-08-25T09:14:22Z",
                      "endpointId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "eventType": "call.initiated",
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "lastError": "connection_timeout",
                      "lastStatus": 0,
                      "status": "pending",
                      "subjectId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "subjectType": "call"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/WebhookDeliveryResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Recent webhook deliveries",
        "tags": [
          "integrations"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/integrations/webhooks/deliveries/{id}/retry": {
      "post": {
        "description": "Re-sends immediately instead of waiting for the next backoff step. The event id is unchanged, so a correctly written consumer deduplicates it.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "integrations.retryDelivery",
        "parameters": [
          {
            "description": "The webhook delivery's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "example": {
                  "data": null
                },
                "schema": {
                  "properties": {
                    "data": {
                      "description": "The resource, or an array of them on a list endpoint. Null for endpoints that return no body."
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Send a delivery again now",
        "tags": [
          "integrations"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/integrations/webhooks/signing-secret": {
      "get": {
        "description": "Shown so you can configure a verifier. Compare `x-tone-signature` against an HMAC-SHA256 of `{timestamp}.{raw body}` — the RAW body, before any JSON parsing.\n\n**Requires the `admin` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "integrations.signingSecret",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "note": "Signs every delivery to this endpoint as x-tone-signature.",
                    "secret": "whsec_3f1a7f6e2b4c4d1e9a8b5c6d7e8f9a0b"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/SigningSecretResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "The secret webhook signatures are made with",
        "tags": [
          "integrations"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "admin"
        ]
      }
    },
    "/v1/integrations/webhooks/{id}": {
      "delete": {
        "description": "Deliveries stop immediately. The delivery history goes with it — disable it instead if you still need the record.\n\n**Requires the `admin` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "integrations.removeWebhook",
        "parameters": [
          {
            "description": "The webhook endpoint's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "content": {
              "application/json": {
                "example": {
                  "data": null
                },
                "schema": {
                  "properties": {
                    "data": {
                      "description": "The resource, or an array of them on a list endpoint. Null for endpoints that return no body."
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Remove a webhook endpoint",
        "tags": [
          "integrations"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "admin"
        ]
      },
      "patch": {
        "description": "Change the URL, the subscribed events, or disable it. Disabling stops delivery without losing the endpoint, its secret or its history.\n\n**Requires the `admin` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "integrations.updateWebhook",
        "parameters": [
          {
            "description": "The webhook endpoint's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "description": "Production CRM sync",
                "enabled": true,
                "events": [
                  "call.completed",
                  "call.failed"
                ],
                "url": "https://hooks.example.com/tone"
              },
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookEndpointDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "consecutiveFailures": 0,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "description": "Production — order service",
                    "disabledReason": null,
                    "enabled": true,
                    "events": [
                      "call.completed",
                      "campaign.finished"
                    ],
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "url": "https://hooks.acme.example/tone"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpointResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Update a webhook endpoint",
        "tags": [
          "integrations"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "admin"
        ]
      }
    },
    "/v1/integrations/webhooks/{id}/roll-secret": {
      "post": {
        "description": "🔴 During the overlap `x-tone-signature` carries SEVERAL space-delimited signatures, and a verifier that treats the header as one string starts rejecting everything. Accept the delivery if ANY of them matches. Deploy the new secret within the 24 hours.\n\n**Requires the `admin` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "integrations.rollSecret",
        "parameters": [
          {
            "description": "The webhook endpoint's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "previousValidUntil": "2026-08-25T09:14:22Z",
                    "secret": "whsec_8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/RolledSecretResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Rotate the signing secret (old one keeps verifying for 24h)",
        "tags": [
          "integrations"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "admin"
        ]
      }
    },
    "/v1/integrations/webhooks/{id}/secret": {
      "get": {
        "description": "Each endpoint has its own, so rotating one does not disturb the others.\n\n**Requires the `admin` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "integrations.endpointSecret",
        "parameters": [
          {
            "description": "The webhook endpoint's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "note": "Signs every delivery to this endpoint as x-tone-signature.",
                    "secret": "whsec_3f1a7f6e2b4c4d1e9a8b5c6d7e8f9a0b"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/SigningSecretResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "This endpoint's signing secret",
        "tags": [
          "integrations"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "admin"
        ]
      }
    },
    "/v1/knowledge-bases": {
      "get": {
        "description": "Each with its derived status, document count and size. Status is computed, not stored: a base is `empty`, `indexing`, `ready` or `error` based on what its last build did.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "knowledge.list",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "agentCount": 2,
                      "chunkCount": 187,
                      "compiledTokens": 0,
                      "createdAt": "2026-08-25T09:14:22Z",
                      "deliveryMode": "inline",
                      "description": "Delivery timelines, COD rules and the returns window.",
                      "docCount": 4,
                      "error": null,
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "name": "Shipping and returns policy",
                      "status": "empty",
                      "totalBytes": 248311,
                      "updatedAt": "2026-08-25T09:14:22Z"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/KnowledgeBaseResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "List the organization’s knowledge bases",
        "tags": [
          "knowledge"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      },
      "post": {
        "description": "Creates it empty. Add documents, wait for the build, then attach it to an agent.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "knowledge.create",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "description": "Delivery timelines, COD rules and the returns window.",
                "name": "Shipping and returns policy"
              },
              "schema": {
                "$ref": "#/components/schemas/CreateKnowledgeBaseDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentCount": 2,
                    "chunkCount": 187,
                    "compiledTokens": 0,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "deliveryMode": "inline",
                    "description": "Delivery timelines, COD rules and the returns window.",
                    "docCount": 4,
                    "error": null,
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "name": "Shipping and returns policy",
                    "status": "empty",
                    "totalBytes": 248311,
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KnowledgeBaseResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Create a knowledge base",
        "tags": [
          "knowledge"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/knowledge-bases/{id}": {
      "delete": {
        "description": "Documents and the built index go with it. Agents attached to it simply stop having it — they keep working.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "knowledge.remove",
        "parameters": [
          {
            "description": "The knowledge base's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "content": {
              "application/json": {
                "example": {
                  "data": null
                },
                "schema": {
                  "properties": {
                    "data": {
                      "description": "The resource, or an array of them on a list endpoint. Null for endpoints that return no body."
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Delete a knowledge base and everything in it",
        "tags": [
          "knowledge"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      },
      "get": {
        "description": "Includes the chunk count from the last successful build — the number of retrievable passages an agent can actually draw on.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "knowledge.findOne",
        "parameters": [
          {
            "description": "The knowledge base's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentCount": 2,
                    "chunkCount": 187,
                    "compiledTokens": 0,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "deliveryMode": "inline",
                    "description": "Delivery timelines, COD rules and the returns window.",
                    "docCount": 4,
                    "error": null,
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "name": "Shipping and returns policy",
                    "status": "empty",
                    "totalBytes": 248311,
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KnowledgeBaseResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Get a knowledge base",
        "tags": [
          "knowledge"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      },
      "patch": {
        "description": "`agentIds` is the COMPLETE attachment set, not a delta: send the full list every time, omit the key to leave attachments untouched, send an empty array to detach it from everything.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "knowledge.update",
        "parameters": [
          {
            "description": "The knowledge base's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "agentIds": [
                  "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                ],
                "description": "Delivery timelines, COD rules and the returns window.",
                "name": "Shipping and returns policy"
              },
              "schema": {
                "$ref": "#/components/schemas/UpdateKnowledgeBaseDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentCount": 2,
                    "chunkCount": 187,
                    "compiledTokens": 0,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "deliveryMode": "inline",
                    "description": "Delivery timelines, COD rules and the returns window.",
                    "docCount": 4,
                    "error": null,
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "name": "Shipping and returns policy",
                    "status": "empty",
                    "totalBytes": 248311,
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KnowledgeBaseResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Update a knowledge base or its attached agents",
        "tags": [
          "knowledge"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/knowledge-bases/{id}/agents": {
      "get": {
        "description": "The other end of the same join `PATCH /v1/agents/{id}` edits with `knowledgeBaseIds`.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "knowledge.listAgents",
        "parameters": [
          {
            "description": "The knowledge base's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentIds": [
                      "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
                    ]
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KnowledgeAgentsResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Agent ids attached to this knowledge base",
        "tags": [
          "knowledge"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/knowledge-bases/{id}/documents": {
      "get": {
        "description": "Each with its own indexing state, so you can tell one failing document from a failing base.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "knowledge.listDocuments",
        "parameters": [
          {
            "description": "The knowledge base's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "byteSize": 0,
                      "charCount": 0,
                      "createdAt": "2026-08-25T09:14:22Z",
                      "error": null,
                      "filename": "returns-policy.pdf",
                      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "kind": "pdf",
                      "mimeType": "application/pdf",
                      "status": "awaiting_upload",
                      "updatedAt": "2026-08-25T09:14:22Z"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/KnowledgeDocumentResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "List documents in a knowledge base",
        "tags": [
          "knowledge"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/knowledge-bases/{id}/documents/upload-url": {
      "post": {
        "description": "Phase one of a two-phase upload: declare the file, PUT the bytes to the URL you get back, then confirm. `contentLength` is signed into the URL and must match exactly — a presigned PUT that does not pin the length is an unbounded write.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "knowledge.createUploadUrl",
        "parameters": [
          {
            "description": "The knowledge base's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "contentLength": 248311,
                "contentType": "application/pdf",
                "filename": "returns-policy.pdf",
                "kind": "file"
              },
              "schema": {
                "$ref": "#/components/schemas/CreateUploadUrlDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "documentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "expiresInSeconds": 0,
                    "headers": {},
                    "url": "https://uploads.usetone.ai/kb/9f1c2d84…?signature=…"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/UploadTargetResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Get a presigned URL to upload a document",
        "tags": [
          "knowledge"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/knowledge-bases/{id}/documents/url": {
      "post": {
        "description": "Fetches and indexes a URL rather than a file. Must be reachable from the open internet; private and link-local addresses are refused, and refused again after DNS resolution.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "knowledge.addUrl",
        "parameters": [
          {
            "description": "The knowledge base's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "url": "https://example.com/help/returns"
              },
              "schema": {
                "$ref": "#/components/schemas/AddUrlDocumentDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "byteSize": 0,
                    "charCount": 0,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "error": null,
                    "filename": "returns-policy.pdf",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "kind": "pdf",
                    "mimeType": "application/pdf",
                    "status": "awaiting_upload",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KnowledgeDocumentResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Import a public web page into a knowledge base",
        "tags": [
          "knowledge"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/knowledge-bases/{id}/documents/{documentId}": {
      "delete": {
        "description": "The index is rebuilt without it. Until that build succeeds, the old index keeps serving.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "knowledge.removeDocument",
        "parameters": [
          {
            "description": "The knowledge base's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The document's id.",
            "in": "path",
            "name": "documentId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "content": {
              "application/json": {
                "example": {
                  "data": null
                },
                "schema": {
                  "properties": {
                    "data": {
                      "description": "The resource, or an array of them on a list endpoint. Null for endpoints that return no body."
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Remove a document from a knowledge base",
        "tags": [
          "knowledge"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/knowledge-bases/{id}/documents/{documentId}/confirm": {
      "post": {
        "description": "Phase two. Nothing is trusted until here: the object is re-read and its real size and type checked against what you declared. Indexing is asynchronous — wait for `knowledge.build.completed` rather than polling.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "knowledge.confirmUpload",
        "parameters": [
          {
            "description": "The knowledge base's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The document's id.",
            "in": "path",
            "name": "documentId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "byteSize": 0,
                    "charCount": 0,
                    "createdAt": "2026-08-25T09:14:22Z",
                    "error": null,
                    "filename": "returns-policy.pdf",
                    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "kind": "pdf",
                    "mimeType": "application/pdf",
                    "status": "awaiting_upload",
                    "updatedAt": "2026-08-25T09:14:22Z"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KnowledgeDocumentResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Confirm an upload finished and queue it for indexing",
        "tags": [
          "knowledge"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/knowledge-bases/{id}/search": {
      "post": {
        "description": "Runs the SAME retrieval a live turn runs, so what you see here is what the agent would get. Optionally generates the answer a caller would hear. `degraded: true` means embeddings were unavailable and this fell back to keyword search alone — the results are real, just weaker.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "knowledge.search",
        "parameters": [
          {
            "description": "The knowledge base's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "answer": true,
                "limit": 3,
                "query": "How long do I have to return an item?"
              },
              "schema": {
                "$ref": "#/components/schemas/SearchKnowledgeDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "answer": "You can return unopened items within 30 days for a full refund.",
                    "answerScope": "inline",
                    "answerStatus": "ok",
                    "degraded": true,
                    "results": [
                      {
                        "documentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                        "headingPath": "Returns > Timeframe",
                        "matchedText": true,
                        "matchedVector": true,
                        "score": 0,
                        "text": "Unopened items may be returned within 30 days of delivery for a full refund."
                      }
                    ]
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KnowledgeSearchResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Preview what an agent would retrieve, and answer, for a question",
        "tags": [
          "knowledge"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/limits": {
      "get": {
        "description": "Two budgets that fail in different ways for different reasons. Exceeding the request budget is a `429 rate_limited` with a `Retry-After` — slow down. Exceeding a concurrency pool is a `429 concurrent_call_limit_reached`, which slowing down does not fix: you have to wait for calls to end. Live and test have separate budgets, and this answers for whichever key you asked with.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "limits.get",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "concurrency": {
                      "agentCalls": {
                        "inUse": 0,
                        "limit": 0
                      },
                      "byoCalls": {
                        "inUse": 0,
                        "limit": 0
                      }
                    },
                    "environment": "live",
                    "requests": {
                      "limitPerMinute": 0,
                      "remaining": 0
                    }
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/LimitsResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "This organization's rate limits and concurrent-call quotas",
        "tags": [
          "limits"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/numbers": {
      "get": {
        "description": "Every number you hold, in any state. A `suspended` number still counts: suspension is unpaid rent, not a release, and it keeps your claim on the line.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "numbers.list",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "capabilities": {
                        "sms": false,
                        "voice": true
                      },
                      "createdAt": "2026-08-25T09:14:22Z",
                      "currency": "INR",
                      "e164": "+918045678901",
                      "environment": "live",
                      "id": "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43",
                      "inbound": "ready",
                      "label": "Support line — Bengaluru",
                      "mediaEndpoint": {
                        "authSecretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                        "customParameters": {
                          "tenant": "acme"
                        },
                        "format": "linear16",
                        "sampleRate": 16000,
                        "type": "static",
                        "url": "wss://media.acme.example/tone"
                      },
                      "nextRentalAt": "2026-09-01T06:30:00Z",
                      "numberType": "landline",
                      "provider": "exotel",
                      "purchasedAt": "2026-08-01T06:30:00Z",
                      "recordCalls": true,
                      "region": "KA",
                      "releasedAt": null,
                      "rentalPaise": 50000,
                      "routed": true,
                      "routingMode": "tone_agent",
                      "series": "regular",
                      "setupPaise": 50000,
                      "sipTrunk": {
                        "credentialId": "cred_5a1b",
                        "inboundTrunkId": "tin_2c7d",
                        "originationSipUri": "sip:acme@sip.livekit.cloud",
                        "originationUriId": "ouri_9f2c",
                        "outboundTrunkId": "tout_8e3f",
                        "provider": "vobiz",
                        "terminationDomain": "acme.sip.vobiz.example",
                        "terminationRealm": "vobiz.example",
                        "terminationUsername": "acme-out",
                        "transport": "tls"
                      },
                      "status": "pending"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/NumberResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "List the organization’s numbers",
        "tags": [
          "numbers"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      },
      "post": {
        "description": "Allocates a free number from the sandbox pool. No carrier is contacted and nothing is charged — this is the number you build against before any paperwork exists.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "numbers.assign",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                "series": "regular"
              },
              "schema": {
                "$ref": "#/components/schemas/AssignNumberDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "capabilities": {
                      "sms": false,
                      "voice": true
                    },
                    "createdAt": "2026-08-25T09:14:22Z",
                    "currency": "INR",
                    "e164": "+918045678901",
                    "environment": "live",
                    "id": "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43",
                    "inbound": "ready",
                    "label": "Support line — Bengaluru",
                    "mediaEndpoint": {
                      "authSecretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                      "customParameters": {
                        "tenant": "acme"
                      },
                      "format": "linear16",
                      "sampleRate": 16000,
                      "type": "static",
                      "url": "wss://media.acme.example/tone"
                    },
                    "nextRentalAt": "2026-09-01T06:30:00Z",
                    "numberType": "landline",
                    "provider": "exotel",
                    "purchasedAt": "2026-08-01T06:30:00Z",
                    "recordCalls": true,
                    "region": "KA",
                    "releasedAt": null,
                    "rentalPaise": 50000,
                    "routed": true,
                    "routingMode": "tone_agent",
                    "series": "regular",
                    "setupPaise": 50000,
                    "sipTrunk": {
                      "credentialId": "cred_5a1b",
                      "inboundTrunkId": "tin_2c7d",
                      "originationSipUri": "sip:acme@sip.livekit.cloud",
                      "originationUriId": "ouri_9f2c",
                      "outboundTrunkId": "tout_8e3f",
                      "provider": "vobiz",
                      "terminationDomain": "acme.sip.vobiz.example",
                      "terminationRealm": "vobiz.example",
                      "terminationUsername": "acme-out",
                      "transport": "tls"
                    },
                    "status": "pending"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/NumberResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Assign a sandbox number — 140/160 require an approved DLT PE ID",
        "tags": [
          "numbers"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/numbers/available": {
      "get": {
        "description": "Live carrier inventory, so results go stale — a number can be taken between this call and your purchase, which is a `409 number_unavailable`. Only regular numbers are offered: the 140 and 160 series are not purchasable through any carrier API.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "numbers.available",
        "parameters": [
          {
            "description": "Which kind of number to search for. Open set — handle an unrecognised value rather than throwing. Today: `landline`, `mobile`, `tollfree`.",
            "in": "query",
            "name": "number_type",
            "required": false,
            "schema": {
              "default": "landline",
              "enum": [
                "landline",
                "mobile",
                "tollfree"
              ],
              "examples": [
                "landline"
              ],
              "type": "string"
            },
            "x-known-values": [
              "landline",
              "mobile",
              "tollfree"
            ]
          },
          {
            "description": "Telecom circle code, uppercase — list them with GET /v1/numbers/regions. Omit to search the carrier default pool.",
            "in": "query",
            "name": "region",
            "required": false,
            "schema": {
              "examples": [
                "KA"
              ],
              "maxLength": 4,
              "minLength": 2,
              "pattern": "^[A-Z]+$",
              "type": "string"
            }
          },
          {
            "description": "Digits the number must contain. Digits only — carriers treat other characters inconsistently.",
            "in": "query",
            "name": "contains",
            "required": false,
            "schema": {
              "examples": [
                "4567"
              ],
              "pattern": "^\\d{1,10}$",
              "type": "string"
            }
          },
          {
            "description": "Only numbers that can also send SMS. Note that SMS itself additionally requires DLT registration.",
            "in": "query",
            "name": "sms",
            "required": false,
            "schema": {
              "enum": [
                "0",
                "1",
                "true",
                "false"
              ],
              "type": "string"
            }
          },
          {
            "description": "How many results to return. 1-50, defaulting to 20.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "examples": [
                20
              ],
              "maximum": 50,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "capabilities": {
                        "sms": false,
                        "voice": true
                      },
                      "e164": "+918045678901",
                      "numberType": "landline",
                      "region": "KA",
                      "rentalPaise": 0,
                      "setupPaise": 0,
                      "totalPaise": 0
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/NumberOfferResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Search the carrier for numbers available to buy",
        "tags": [
          "numbers"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/numbers/eligibility": {
      "get": {
        "description": "Answers before you try: whether business verification is complete and whether the wallet covers a purchase. Cheaper than a `403` and easier to show in a UI.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "numbers.eligibility",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "balancePaise": 0,
                    "verified": true
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PurchaseEligibilityResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Whether this organization can buy a number right now",
        "tags": [
          "numbers"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/numbers/purchase": {
      "post": {
        "description": "🔴 `Idempotency-Key` is REQUIRED — without it this returns `400`. A duplicate purchase buys a second number and starts a second monthly rental, and a timeout is indistinguishable from a purchase that never happened, so retry with the SAME key. The number arrives unrouted; bind it to an agent with a PATCH. Setup and the first month are debited immediately.\n\n**Requires the `admin` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "numbers.purchase",
        "parameters": [
          {
            "description": "REQUIRED. A unique key of your choosing — a UUID is fine. Retrying with the same key replays the first response instead of acting twice, which is what makes a timeout safe to retry here. Reusing a key with a DIFFERENT body is `422 idempotency_key_reused_with_different_params`; retrying while the first is still running is `409 idempotency_key_in_use`. Keys are remembered for 24 hours.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "maxLength": 255,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                "e164": "+918045678901",
                "label": "Support line — Bengaluru"
              },
              "schema": {
                "$ref": "#/components/schemas/PurchaseNumberDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "capabilities": {
                      "sms": false,
                      "voice": true
                    },
                    "createdAt": "2026-08-25T09:14:22Z",
                    "currency": "INR",
                    "e164": "+918045678901",
                    "environment": "live",
                    "id": "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43",
                    "inbound": "ready",
                    "label": "Support line — Bengaluru",
                    "mediaEndpoint": {
                      "authSecretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                      "customParameters": {
                        "tenant": "acme"
                      },
                      "format": "linear16",
                      "sampleRate": 16000,
                      "type": "static",
                      "url": "wss://media.acme.example/tone"
                    },
                    "nextRentalAt": "2026-09-01T06:30:00Z",
                    "numberType": "landline",
                    "provider": "exotel",
                    "purchasedAt": "2026-08-01T06:30:00Z",
                    "recordCalls": true,
                    "region": "KA",
                    "releasedAt": null,
                    "rentalPaise": 50000,
                    "routed": true,
                    "routingMode": "tone_agent",
                    "series": "regular",
                    "setupPaise": 50000,
                    "sipTrunk": {
                      "credentialId": "cred_5a1b",
                      "inboundTrunkId": "tin_2c7d",
                      "originationSipUri": "sip:acme@sip.livekit.cloud",
                      "originationUriId": "ouri_9f2c",
                      "outboundTrunkId": "tout_8e3f",
                      "provider": "vobiz",
                      "terminationDomain": "acme.sip.vobiz.example",
                      "terminationRealm": "vobiz.example",
                      "terminationUsername": "acme-out",
                      "transport": "tls"
                    },
                    "status": "pending"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/NumberResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "Idempotent-Replayed": {
                "description": "`true` when this response is a replay of an earlier request with the same `Idempotency-Key`, rather than fresh work.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Buy a number — requires completed business verification and an Idempotency-Key",
        "tags": [
          "numbers"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "admin"
        ]
      }
    },
    "/v1/numbers/regions": {
      "get": {
        "description": "The circle codes to pass as the `region` filter when searching.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "numbers.regions",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "code": "KA",
                      "label": "Karnataka"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/NumberRegionResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Telecom circles that can be searched",
        "tags": [
          "numbers"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/numbers/{id}": {
      "delete": {
        "description": "🔴 There is no undo. The number returns to general inventory and can be bought by anyone. Rental stops. If you are only trying to stop paying, note that an unpaid number suspends rather than releases, and reactivates on its own once the wallet can cover it.\n\n**Requires the `admin` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "numbers.release",
        "parameters": [
          {
            "description": "The number's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "capabilities": {
                      "sms": false,
                      "voice": true
                    },
                    "createdAt": "2026-08-25T09:14:22Z",
                    "currency": "INR",
                    "e164": "+918045678901",
                    "environment": "live",
                    "id": "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43",
                    "inbound": "ready",
                    "label": "Support line — Bengaluru",
                    "mediaEndpoint": {
                      "authSecretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                      "customParameters": {
                        "tenant": "acme"
                      },
                      "format": "linear16",
                      "sampleRate": 16000,
                      "type": "static",
                      "url": "wss://media.acme.example/tone"
                    },
                    "nextRentalAt": "2026-09-01T06:30:00Z",
                    "numberType": "landline",
                    "provider": "exotel",
                    "purchasedAt": "2026-08-01T06:30:00Z",
                    "recordCalls": true,
                    "region": "KA",
                    "releasedAt": null,
                    "rentalPaise": 50000,
                    "routed": true,
                    "routingMode": "tone_agent",
                    "series": "regular",
                    "setupPaise": 50000,
                    "sipTrunk": {
                      "credentialId": "cred_5a1b",
                      "inboundTrunkId": "tin_2c7d",
                      "originationSipUri": "sip:acme@sip.livekit.cloud",
                      "originationUriId": "ouri_9f2c",
                      "outboundTrunkId": "tout_8e3f",
                      "provider": "vobiz",
                      "terminationDomain": "acme.sip.vobiz.example",
                      "terminationRealm": "vobiz.example",
                      "terminationUsername": "acme-out",
                      "transport": "tls"
                    },
                    "status": "pending"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/NumberResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Release a number back to the carrier — permanent",
        "tags": [
          "numbers"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "admin"
        ]
      },
      "patch": {
        "description": "Also where you switch who answers it. Send `null` to clear a field; omit the key to leave it alone. Switching to a BYO routing mode KEEPS the bound agent — it is ignored while BYO and restored when you switch back.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "numbers.update",
        "parameters": [
          {
            "description": "The number's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                "label": "Support line — Bengaluru",
                "mediaEndpoint": {
                  "authSecretId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                  "customParameters": {
                    "tenant": "acme"
                  },
                  "format": "linear16",
                  "sampleRate": 16000,
                  "type": "static",
                  "url": "wss://media.example.com/tone"
                },
                "recordCalls": true,
                "routingMode": "tone_agent"
              },
              "schema": {
                "$ref": "#/components/schemas/UpdateNumberDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "capabilities": {
                      "sms": false,
                      "voice": true
                    },
                    "createdAt": "2026-08-25T09:14:22Z",
                    "currency": "INR",
                    "e164": "+918045678901",
                    "environment": "live",
                    "id": "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43",
                    "inbound": "ready",
                    "label": "Support line — Bengaluru",
                    "mediaEndpoint": {
                      "authSecretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                      "customParameters": {
                        "tenant": "acme"
                      },
                      "format": "linear16",
                      "sampleRate": 16000,
                      "type": "static",
                      "url": "wss://media.acme.example/tone"
                    },
                    "nextRentalAt": "2026-09-01T06:30:00Z",
                    "numberType": "landline",
                    "provider": "exotel",
                    "purchasedAt": "2026-08-01T06:30:00Z",
                    "recordCalls": true,
                    "region": "KA",
                    "releasedAt": null,
                    "rentalPaise": 50000,
                    "routed": true,
                    "routingMode": "tone_agent",
                    "series": "regular",
                    "setupPaise": 50000,
                    "sipTrunk": {
                      "credentialId": "cred_5a1b",
                      "inboundTrunkId": "tin_2c7d",
                      "originationSipUri": "sip:acme@sip.livekit.cloud",
                      "originationUriId": "ouri_9f2c",
                      "outboundTrunkId": "tout_8e3f",
                      "provider": "vobiz",
                      "terminationDomain": "acme.sip.vobiz.example",
                      "terminationRealm": "vobiz.example",
                      "terminationUsername": "acme-out",
                      "transport": "tls"
                    },
                    "status": "pending"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/NumberResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Rename a number or bind it to an agent",
        "tags": [
          "numbers"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/numbers/{id}/routing": {
      "post": {
        "description": "Repairs routing for numbers bought before inbound existed, or after a dev tunnel changed hostname. Talks to the carrier, so it is a POST rather than part of PATCH — rebinding an agent must not fail during a carrier outage.\n\n**Requires the `write` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "numbers.setRouting",
        "parameters": [
          {
            "description": "The number's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "enabled": true
              },
              "schema": {
                "$ref": "#/components/schemas/SetRoutingDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "capabilities": {
                      "sms": false,
                      "voice": true
                    },
                    "createdAt": "2026-08-25T09:14:22Z",
                    "currency": "INR",
                    "e164": "+918045678901",
                    "environment": "live",
                    "id": "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43",
                    "inbound": "ready",
                    "label": "Support line — Bengaluru",
                    "mediaEndpoint": {
                      "authSecretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                      "customParameters": {
                        "tenant": "acme"
                      },
                      "format": "linear16",
                      "sampleRate": 16000,
                      "type": "static",
                      "url": "wss://media.acme.example/tone"
                    },
                    "nextRentalAt": "2026-09-01T06:30:00Z",
                    "numberType": "landline",
                    "provider": "exotel",
                    "purchasedAt": "2026-08-01T06:30:00Z",
                    "recordCalls": true,
                    "region": "KA",
                    "releasedAt": null,
                    "rentalPaise": 50000,
                    "routed": true,
                    "routingMode": "tone_agent",
                    "series": "regular",
                    "setupPaise": 50000,
                    "sipTrunk": {
                      "credentialId": "cred_5a1b",
                      "inboundTrunkId": "tin_2c7d",
                      "originationSipUri": "sip:acme@sip.livekit.cloud",
                      "originationUriId": "ouri_9f2c",
                      "outboundTrunkId": "tout_8e3f",
                      "provider": "vobiz",
                      "terminationDomain": "acme.sip.vobiz.example",
                      "terminationRealm": "vobiz.example",
                      "terminationUsername": "acme-out",
                      "transport": "tls"
                    },
                    "status": "pending"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/NumberResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Point a number at the inbound flow, or unroute it",
        "tags": [
          "numbers"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "write"
        ]
      }
    },
    "/v1/numbers/{id}/sip": {
      "delete": {
        "description": "Tears down the trunk. The number itself is kept — this is not a release.\n\n**Requires the `admin` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "numbers.deprovisionSip",
        "parameters": [
          {
            "description": "The number's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "capabilities": {
                      "sms": false,
                      "voice": true
                    },
                    "createdAt": "2026-08-25T09:14:22Z",
                    "currency": "INR",
                    "e164": "+918045678901",
                    "environment": "live",
                    "id": "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43",
                    "inbound": "ready",
                    "label": "Support line — Bengaluru",
                    "mediaEndpoint": {
                      "authSecretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                      "customParameters": {
                        "tenant": "acme"
                      },
                      "format": "linear16",
                      "sampleRate": 16000,
                      "type": "static",
                      "url": "wss://media.acme.example/tone"
                    },
                    "nextRentalAt": "2026-09-01T06:30:00Z",
                    "numberType": "landline",
                    "provider": "exotel",
                    "purchasedAt": "2026-08-01T06:30:00Z",
                    "recordCalls": true,
                    "region": "KA",
                    "releasedAt": null,
                    "rentalPaise": 50000,
                    "routed": true,
                    "routingMode": "tone_agent",
                    "series": "regular",
                    "setupPaise": 50000,
                    "sipTrunk": {
                      "credentialId": "cred_5a1b",
                      "inboundTrunkId": "tin_2c7d",
                      "originationSipUri": "sip:acme@sip.livekit.cloud",
                      "originationUriId": "ouri_9f2c",
                      "outboundTrunkId": "tout_8e3f",
                      "provider": "vobiz",
                      "terminationDomain": "acme.sip.vobiz.example",
                      "terminationRealm": "vobiz.example",
                      "terminationUsername": "acme-out",
                      "transport": "tls"
                    },
                    "status": "pending"
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/NumberResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Remove the SIP trunk pair and return the number to tone_agent mode",
        "tags": [
          "numbers"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "admin"
        ]
      },
      "post": {
        "description": "Vobiz numbers only. Inbound calls are sent to `sipUri`; outbound termination credentials are returned ONCE in this response and never stored. The number switches to byo_sip.\n\n**Requires the `admin` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "numbers.provisionSip",
        "parameters": [
          {
            "description": "The number's id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "sipUri": "sip:agent@sip.example.com;transport=tls",
                "transport": "tls"
              },
              "schema": {
                "$ref": "#/components/schemas/ProvisionSipDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "number": {
                      "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                      "capabilities": {
                        "sms": false,
                        "voice": true
                      },
                      "createdAt": "2026-08-25T09:14:22Z",
                      "currency": "INR",
                      "e164": "+918045678901",
                      "environment": "live",
                      "id": "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43",
                      "inbound": "ready",
                      "label": "Support line — Bengaluru",
                      "mediaEndpoint": {
                        "authSecretId": "3f1a7f6e-2b4c-4d1e-9a8b-5c6d7e8f9a0b",
                        "customParameters": {
                          "tenant": "acme"
                        },
                        "format": "linear16",
                        "sampleRate": 16000,
                        "type": "static",
                        "url": "wss://media.acme.example/tone"
                      },
                      "nextRentalAt": "2026-09-01T06:30:00Z",
                      "numberType": "landline",
                      "provider": "exotel",
                      "purchasedAt": "2026-08-01T06:30:00Z",
                      "recordCalls": true,
                      "region": "KA",
                      "releasedAt": null,
                      "rentalPaise": 50000,
                      "routed": true,
                      "routingMode": "tone_agent",
                      "series": "regular",
                      "setupPaise": 50000,
                      "sipTrunk": {
                        "credentialId": "cred_5a1b",
                        "inboundTrunkId": "tin_2c7d",
                        "originationSipUri": "sip:acme@sip.livekit.cloud",
                        "originationUriId": "ouri_9f2c",
                        "outboundTrunkId": "tout_8e3f",
                        "provider": "vobiz",
                        "terminationDomain": "acme.sip.vobiz.example",
                        "terminationRealm": "vobiz.example",
                        "terminationUsername": "acme-out",
                        "transport": "tls"
                      },
                      "status": "pending"
                    },
                    "termination": {
                      "domain": "acme.sip.vobiz.example",
                      "password": "K7x2QpL9vR4nT1cW",
                      "realm": "vobiz.example",
                      "username": "acme-out"
                    }
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ProvisionedSipResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource, or it belongs to another organization."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Provision a SIP trunk pair for the customer's voice platform",
        "tags": [
          "numbers"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "admin"
        ]
      }
    },
    "/v1/signup/email-available": {
      "post": {
        "description": "Sign-up itself answers GENERICALLY when an address is already registered, because telling callers which addresses exist is an account-enumeration oracle. This endpoint exists so the sign-up form can show an honest \"already registered\" message instead; it is deliberately the only place that distinction is made.",
        "operationId": "emailAvailability.check",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "email": "priya@example.com"
              },
              "schema": {
                "$ref": "#/components/schemas/EmailAvailabilityDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": null
                },
                "schema": {
                  "properties": {
                    "data": {
                      "description": "The resource, or an array of them on a list endpoint. Null for endpoints that return no body."
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [],
        "summary": "Check whether an email is available for signup",
        "tags": [
          "auth"
        ],
        "x-tone-audience": "public",
        "x-tone-scopes": []
      }
    },
    "/v1/wallet": {
      "get": {
        "description": "Everything is prepaid and in paise. The estimate divides the balance by your per-minute rate, so it is a guide, not a quota. Subscribe to `wallet.balance.low` rather than polling this.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "wallet.get",
        "parameters": [],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "balancePaise": 0,
                    "currency": "INR",
                    "estimatedMinutesRemaining": 0,
                    "lowBalanceThresholdPaise": 0,
                    "ratePaisePerMinute": 0
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WalletResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Prepaid balance and estimated talk time remaining",
        "tags": [
          "wallet"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/wallet/transactions": {
      "get": {
        "description": "The ledger behind the balance, and the source of truth for it: every top-up, call, number purchase, monthly rental and compliance verdict. Append-only — a correction is a new compensating row, never an edit.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "wallet.transactions",
        "parameters": [
          {
            "description": "How many results to return. 1-100, defaulting to 25.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "examples": [
                25
              ],
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Opaque page cursor from the previous response.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "examples": [
                "48213"
              ],
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "amountPaise": 0,
                      "balanceAfterPaise": 0,
                      "createdAt": "2026-08-25T09:14:22Z",
                      "description": "Call to +919876543210 (45s)",
                      "entryType": "topup",
                      "id": "1043827"
                    }
                  ]
                },
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/TransactionResponse"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Wallet transactions, newest first",
        "tags": [
          "wallet"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    },
    "/v1/wallet/usage": {
      "get": {
        "description": "Calls, numbers and adjustments, each as a single figure. A purchase and its reversal fall in the same bucket, so the numbers show what something actually cost rather than a gross figure beside a credit that cancels it.\n\n**Requires the `read` scope.** A key with less gets `403 insufficient_scope`.",
        "operationId": "wallet.usage",
        "parameters": [
          {
            "description": "How far back to look. A closed set rather than an arbitrary window — this is a billing summary, not a reporting API. Open set — handle an unrecognised value rather than throwing. Today: `7d`, `30d`, `all`.",
            "in": "query",
            "name": "period",
            "required": false,
            "schema": {
              "default": "30d",
              "enum": [
                "7d",
                "30d",
                "all"
              ],
              "examples": [
                "30d"
              ],
              "type": "string"
            },
            "x-known-values": [
              "7d",
              "30d",
              "all"
            ]
          },
          {
            "description": "Narrow the breakdown to one agent calls.",
            "in": "query",
            "name": "agent_id",
            "required": false,
            "schema": {
              "examples": [
                "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451"
              ],
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "addedPaise": 0,
                    "agentId": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
                    "categories": [
                      {
                        "category": "calls",
                        "entries": 0,
                        "spentPaise": 0
                      }
                    ],
                    "from": "2026-08-25T09:14:22Z",
                    "period": "7d",
                    "to": "2026-08-25T09:14:22Z",
                    "totalSpentPaise": 0
                  }
                },
                "schema": {
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WalletUsageResponse"
                    },
                    "meta": {
                      "properties": {
                        "pagination": {
                          "properties": {
                            "cursor": {
                              "description": "Opaque. Pass as `cursor` for the next page; null on the last.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "limit": {
                              "type": "integer"
                            },
                            "total": {
                              "description": "Only on endpoints that opt in (e.g. the suppression list).",
                              "type": "integer"
                            }
                          },
                          "required": [
                            "cursor",
                            "hasMore",
                            "limit"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed request — `validation_error` names the offending fields."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Missing, malformed, revoked or expired credential."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted — `insufficient_scope`, a session-only route reached with a key, or a compliance `blocked_*` refusal."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Well-formed but not valid against current state."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limited — see `Retry-After`. `rate_limited`, or `concurrent_call_limit_reached` on a dial.",
            "headers": {
              "RateLimit": {
                "description": "What is left of it, as `\"org\";r=<remaining>;t=<seconds until reset>`.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "The budget in force, as `\"org\";q=<limit>;w=<window seconds>`.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Limit": {
                "description": "Requests allowed per minute for this organization and environment.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix seconds at which the window resets.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Retry with backoff."
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "session": []
          }
        ],
        "summary": "Spend by category over the selected period",
        "tags": [
          "wallet"
        ],
        "x-tone-audience": "key",
        "x-tone-scopes": [
          "read"
        ]
      }
    }
  },
  "servers": [
    {
      "description": "Beta",
      "url": "https://apibeta.usetone.ai"
    }
  ],
  "tags": [
    {
      "description": "Service metadata and the API root.",
      "name": "meta"
    },
    {
      "description": "Liveness and readiness probes. No credential required.",
      "name": "health"
    },
    {
      "description": "Your request budget and concurrent-call quotas, per environment.",
      "name": "limits"
    },
    {
      "description": "The thing that talks: prompt, voice, languages, variables and tools. Published versions are immutable and a call pins the one that ran it.",
      "name": "agents"
    },
    {
      "description": "Which speech models, voices and languages an agent may be set to. Fetched from the provider, so treat every value as an open set.",
      "name": "catalog"
    },
    {
      "description": "Knowledge bases an agent answers from. Builds are asynchronous — wait for the webhook rather than polling.",
      "name": "knowledge"
    },
    {
      "description": "Search, buy, route and release +91 numbers. Routing mode decides whether a Tone agent answers or your own stack does.",
      "name": "numbers"
    },
    {
      "description": "Place a call, then read its outcome, transcript and recording.",
      "name": "calls"
    },
    {
      "description": "Dial a list at a controlled rate, inside the legal calling window, with retries and a wallet floor.",
      "name": "campaigns"
    },
    {
      "description": "The pre-dial gate, standalone verdicts, consent records, suppression lists and the evidence pack behind any of them.",
      "name": "compliance"
    },
    {
      "description": "Recent events, re-readable for 30 days. The replay path when a webhook delivery was missed.",
      "name": "events"
    },
    {
      "description": "Webhook endpoints, their signing secrets and delivery history.",
      "name": "integrations"
    },
    {
      "description": "Prepaid balance, the ledger behind it, and spend by category.",
      "name": "wallet"
    },
    {
      "description": "Sign-up pre-checks. The rest of the identity surface is mounted separately.",
      "name": "auth"
    },
    {
      "description": "Public enquiry form.",
      "name": "contact-sales"
    }
  ],
  "webhooks": {
    "call.answered": {
      "post": {
        "description": "Delivered to every enabled endpoint subscribed to this event. Verify `x-tone-signature` before trusting the body, respond 2xx within 10 seconds, and deduplicate on `id`.",
        "operationId": "webhook.call_answered",
        "parameters": [
          {
            "description": "One or more space-delimited `v1=<hex>` HMAC-SHA256 signatures over `{x-tone-timestamp}.{raw body}`. More than one only during a secret rotation; accept the message if ANY matches.",
            "in": "header",
            "name": "x-tone-signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds, covered by the signature. Reject anything outside your tolerance.",
            "in": "header",
            "name": "x-tone-timestamp",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tone-event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable across retries — this is your deduplication key.",
            "in": "header",
            "name": "x-tone-event-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 on the first send; up to 14 over roughly a day.",
            "in": "header",
            "name": "x-tone-delivery-attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "created_at": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "description": "Keyed by subject: `call`, `campaign`, `number`, `check`, `wallet`, or `knowledgeBase` + `build`. Each object is what that resource's own GET returns.",
                    "type": "object"
                  },
                  "id": {
                    "description": "Event id, identical to `x-tone-event-id`.",
                    "type": "string"
                  },
                  "links": {
                    "description": "Present only when there is something behind them — branch on presence, not on a 404.",
                    "properties": {
                      "recording": {
                        "format": "uri",
                        "type": "string"
                      },
                      "self": {
                        "format": "uri",
                        "type": "string"
                      },
                      "transcript": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "OPEN SET — log and ignore a type you do not recognise.",
                    "type": "string",
                    "x-known-values": [
                      "call.initiated",
                      "call.answered",
                      "call.completed",
                      "call.failed",
                      "campaign.completed",
                      "campaign.paused",
                      "compliance.check.blocked",
                      "wallet.balance.low",
                      "number.suspended",
                      "number.reactivated",
                      "knowledge.build.completed",
                      "knowledge.build.failed"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Any 2xx marks the delivery handled. The body is not read."
          },
          "4XX": {
            "description": "Understood and refused — NOT retried (except 408 and 429). 20 consecutive failures disable the endpoint and email your owners and admins."
          },
          "5XX": {
            "description": "Retried with exponential backoff and jitter, up to 14 attempts over roughly a day."
          }
        },
        "summary": "call.answered"
      }
    },
    "call.completed": {
      "post": {
        "description": "Delivered to every enabled endpoint subscribed to this event. Verify `x-tone-signature` before trusting the body, respond 2xx within 10 seconds, and deduplicate on `id`.",
        "operationId": "webhook.call_completed",
        "parameters": [
          {
            "description": "One or more space-delimited `v1=<hex>` HMAC-SHA256 signatures over `{x-tone-timestamp}.{raw body}`. More than one only during a secret rotation; accept the message if ANY matches.",
            "in": "header",
            "name": "x-tone-signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds, covered by the signature. Reject anything outside your tolerance.",
            "in": "header",
            "name": "x-tone-timestamp",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tone-event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable across retries — this is your deduplication key.",
            "in": "header",
            "name": "x-tone-event-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 on the first send; up to 14 over roughly a day.",
            "in": "header",
            "name": "x-tone-delivery-attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "created_at": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "description": "Keyed by subject: `call`, `campaign`, `number`, `check`, `wallet`, or `knowledgeBase` + `build`. Each object is what that resource's own GET returns.",
                    "type": "object"
                  },
                  "id": {
                    "description": "Event id, identical to `x-tone-event-id`.",
                    "type": "string"
                  },
                  "links": {
                    "description": "Present only when there is something behind them — branch on presence, not on a 404.",
                    "properties": {
                      "recording": {
                        "format": "uri",
                        "type": "string"
                      },
                      "self": {
                        "format": "uri",
                        "type": "string"
                      },
                      "transcript": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "OPEN SET — log and ignore a type you do not recognise.",
                    "type": "string",
                    "x-known-values": [
                      "call.initiated",
                      "call.answered",
                      "call.completed",
                      "call.failed",
                      "campaign.completed",
                      "campaign.paused",
                      "compliance.check.blocked",
                      "wallet.balance.low",
                      "number.suspended",
                      "number.reactivated",
                      "knowledge.build.completed",
                      "knowledge.build.failed"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Any 2xx marks the delivery handled. The body is not read."
          },
          "4XX": {
            "description": "Understood and refused — NOT retried (except 408 and 429). 20 consecutive failures disable the endpoint and email your owners and admins."
          },
          "5XX": {
            "description": "Retried with exponential backoff and jitter, up to 14 attempts over roughly a day."
          }
        },
        "summary": "call.completed"
      }
    },
    "call.failed": {
      "post": {
        "description": "Delivered to every enabled endpoint subscribed to this event. Verify `x-tone-signature` before trusting the body, respond 2xx within 10 seconds, and deduplicate on `id`.",
        "operationId": "webhook.call_failed",
        "parameters": [
          {
            "description": "One or more space-delimited `v1=<hex>` HMAC-SHA256 signatures over `{x-tone-timestamp}.{raw body}`. More than one only during a secret rotation; accept the message if ANY matches.",
            "in": "header",
            "name": "x-tone-signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds, covered by the signature. Reject anything outside your tolerance.",
            "in": "header",
            "name": "x-tone-timestamp",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tone-event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable across retries — this is your deduplication key.",
            "in": "header",
            "name": "x-tone-event-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 on the first send; up to 14 over roughly a day.",
            "in": "header",
            "name": "x-tone-delivery-attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "created_at": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "description": "Keyed by subject: `call`, `campaign`, `number`, `check`, `wallet`, or `knowledgeBase` + `build`. Each object is what that resource's own GET returns.",
                    "type": "object"
                  },
                  "id": {
                    "description": "Event id, identical to `x-tone-event-id`.",
                    "type": "string"
                  },
                  "links": {
                    "description": "Present only when there is something behind them — branch on presence, not on a 404.",
                    "properties": {
                      "recording": {
                        "format": "uri",
                        "type": "string"
                      },
                      "self": {
                        "format": "uri",
                        "type": "string"
                      },
                      "transcript": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "OPEN SET — log and ignore a type you do not recognise.",
                    "type": "string",
                    "x-known-values": [
                      "call.initiated",
                      "call.answered",
                      "call.completed",
                      "call.failed",
                      "campaign.completed",
                      "campaign.paused",
                      "compliance.check.blocked",
                      "wallet.balance.low",
                      "number.suspended",
                      "number.reactivated",
                      "knowledge.build.completed",
                      "knowledge.build.failed"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Any 2xx marks the delivery handled. The body is not read."
          },
          "4XX": {
            "description": "Understood and refused — NOT retried (except 408 and 429). 20 consecutive failures disable the endpoint and email your owners and admins."
          },
          "5XX": {
            "description": "Retried with exponential backoff and jitter, up to 14 attempts over roughly a day."
          }
        },
        "summary": "call.failed"
      }
    },
    "call.initiated": {
      "post": {
        "description": "Delivered to every enabled endpoint subscribed to this event. Verify `x-tone-signature` before trusting the body, respond 2xx within 10 seconds, and deduplicate on `id`.",
        "operationId": "webhook.call_initiated",
        "parameters": [
          {
            "description": "One or more space-delimited `v1=<hex>` HMAC-SHA256 signatures over `{x-tone-timestamp}.{raw body}`. More than one only during a secret rotation; accept the message if ANY matches.",
            "in": "header",
            "name": "x-tone-signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds, covered by the signature. Reject anything outside your tolerance.",
            "in": "header",
            "name": "x-tone-timestamp",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tone-event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable across retries — this is your deduplication key.",
            "in": "header",
            "name": "x-tone-event-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 on the first send; up to 14 over roughly a day.",
            "in": "header",
            "name": "x-tone-delivery-attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "created_at": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "description": "Keyed by subject: `call`, `campaign`, `number`, `check`, `wallet`, or `knowledgeBase` + `build`. Each object is what that resource's own GET returns.",
                    "type": "object"
                  },
                  "id": {
                    "description": "Event id, identical to `x-tone-event-id`.",
                    "type": "string"
                  },
                  "links": {
                    "description": "Present only when there is something behind them — branch on presence, not on a 404.",
                    "properties": {
                      "recording": {
                        "format": "uri",
                        "type": "string"
                      },
                      "self": {
                        "format": "uri",
                        "type": "string"
                      },
                      "transcript": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "OPEN SET — log and ignore a type you do not recognise.",
                    "type": "string",
                    "x-known-values": [
                      "call.initiated",
                      "call.answered",
                      "call.completed",
                      "call.failed",
                      "campaign.completed",
                      "campaign.paused",
                      "compliance.check.blocked",
                      "wallet.balance.low",
                      "number.suspended",
                      "number.reactivated",
                      "knowledge.build.completed",
                      "knowledge.build.failed"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Any 2xx marks the delivery handled. The body is not read."
          },
          "4XX": {
            "description": "Understood and refused — NOT retried (except 408 and 429). 20 consecutive failures disable the endpoint and email your owners and admins."
          },
          "5XX": {
            "description": "Retried with exponential backoff and jitter, up to 14 attempts over roughly a day."
          }
        },
        "summary": "call.initiated"
      }
    },
    "campaign.completed": {
      "post": {
        "description": "Delivered to every enabled endpoint subscribed to this event. Verify `x-tone-signature` before trusting the body, respond 2xx within 10 seconds, and deduplicate on `id`.",
        "operationId": "webhook.campaign_completed",
        "parameters": [
          {
            "description": "One or more space-delimited `v1=<hex>` HMAC-SHA256 signatures over `{x-tone-timestamp}.{raw body}`. More than one only during a secret rotation; accept the message if ANY matches.",
            "in": "header",
            "name": "x-tone-signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds, covered by the signature. Reject anything outside your tolerance.",
            "in": "header",
            "name": "x-tone-timestamp",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tone-event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable across retries — this is your deduplication key.",
            "in": "header",
            "name": "x-tone-event-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 on the first send; up to 14 over roughly a day.",
            "in": "header",
            "name": "x-tone-delivery-attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "created_at": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "description": "Keyed by subject: `call`, `campaign`, `number`, `check`, `wallet`, or `knowledgeBase` + `build`. Each object is what that resource's own GET returns.",
                    "type": "object"
                  },
                  "id": {
                    "description": "Event id, identical to `x-tone-event-id`.",
                    "type": "string"
                  },
                  "links": {
                    "description": "Present only when there is something behind them — branch on presence, not on a 404.",
                    "properties": {
                      "recording": {
                        "format": "uri",
                        "type": "string"
                      },
                      "self": {
                        "format": "uri",
                        "type": "string"
                      },
                      "transcript": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "OPEN SET — log and ignore a type you do not recognise.",
                    "type": "string",
                    "x-known-values": [
                      "call.initiated",
                      "call.answered",
                      "call.completed",
                      "call.failed",
                      "campaign.completed",
                      "campaign.paused",
                      "compliance.check.blocked",
                      "wallet.balance.low",
                      "number.suspended",
                      "number.reactivated",
                      "knowledge.build.completed",
                      "knowledge.build.failed"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Any 2xx marks the delivery handled. The body is not read."
          },
          "4XX": {
            "description": "Understood and refused — NOT retried (except 408 and 429). 20 consecutive failures disable the endpoint and email your owners and admins."
          },
          "5XX": {
            "description": "Retried with exponential backoff and jitter, up to 14 attempts over roughly a day."
          }
        },
        "summary": "campaign.completed"
      }
    },
    "campaign.paused": {
      "post": {
        "description": "Delivered to every enabled endpoint subscribed to this event. Verify `x-tone-signature` before trusting the body, respond 2xx within 10 seconds, and deduplicate on `id`.",
        "operationId": "webhook.campaign_paused",
        "parameters": [
          {
            "description": "One or more space-delimited `v1=<hex>` HMAC-SHA256 signatures over `{x-tone-timestamp}.{raw body}`. More than one only during a secret rotation; accept the message if ANY matches.",
            "in": "header",
            "name": "x-tone-signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds, covered by the signature. Reject anything outside your tolerance.",
            "in": "header",
            "name": "x-tone-timestamp",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tone-event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable across retries — this is your deduplication key.",
            "in": "header",
            "name": "x-tone-event-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 on the first send; up to 14 over roughly a day.",
            "in": "header",
            "name": "x-tone-delivery-attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "created_at": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "description": "Keyed by subject: `call`, `campaign`, `number`, `check`, `wallet`, or `knowledgeBase` + `build`. Each object is what that resource's own GET returns.",
                    "type": "object"
                  },
                  "id": {
                    "description": "Event id, identical to `x-tone-event-id`.",
                    "type": "string"
                  },
                  "links": {
                    "description": "Present only when there is something behind them — branch on presence, not on a 404.",
                    "properties": {
                      "recording": {
                        "format": "uri",
                        "type": "string"
                      },
                      "self": {
                        "format": "uri",
                        "type": "string"
                      },
                      "transcript": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "OPEN SET — log and ignore a type you do not recognise.",
                    "type": "string",
                    "x-known-values": [
                      "call.initiated",
                      "call.answered",
                      "call.completed",
                      "call.failed",
                      "campaign.completed",
                      "campaign.paused",
                      "compliance.check.blocked",
                      "wallet.balance.low",
                      "number.suspended",
                      "number.reactivated",
                      "knowledge.build.completed",
                      "knowledge.build.failed"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Any 2xx marks the delivery handled. The body is not read."
          },
          "4XX": {
            "description": "Understood and refused — NOT retried (except 408 and 429). 20 consecutive failures disable the endpoint and email your owners and admins."
          },
          "5XX": {
            "description": "Retried with exponential backoff and jitter, up to 14 attempts over roughly a day."
          }
        },
        "summary": "campaign.paused"
      }
    },
    "compliance.check.blocked": {
      "post": {
        "description": "Delivered to every enabled endpoint subscribed to this event. Verify `x-tone-signature` before trusting the body, respond 2xx within 10 seconds, and deduplicate on `id`.",
        "operationId": "webhook.compliance_check_blocked",
        "parameters": [
          {
            "description": "One or more space-delimited `v1=<hex>` HMAC-SHA256 signatures over `{x-tone-timestamp}.{raw body}`. More than one only during a secret rotation; accept the message if ANY matches.",
            "in": "header",
            "name": "x-tone-signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds, covered by the signature. Reject anything outside your tolerance.",
            "in": "header",
            "name": "x-tone-timestamp",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tone-event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable across retries — this is your deduplication key.",
            "in": "header",
            "name": "x-tone-event-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 on the first send; up to 14 over roughly a day.",
            "in": "header",
            "name": "x-tone-delivery-attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "created_at": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "description": "Keyed by subject: `call`, `campaign`, `number`, `check`, `wallet`, or `knowledgeBase` + `build`. Each object is what that resource's own GET returns.",
                    "type": "object"
                  },
                  "id": {
                    "description": "Event id, identical to `x-tone-event-id`.",
                    "type": "string"
                  },
                  "links": {
                    "description": "Present only when there is something behind them — branch on presence, not on a 404.",
                    "properties": {
                      "recording": {
                        "format": "uri",
                        "type": "string"
                      },
                      "self": {
                        "format": "uri",
                        "type": "string"
                      },
                      "transcript": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "OPEN SET — log and ignore a type you do not recognise.",
                    "type": "string",
                    "x-known-values": [
                      "call.initiated",
                      "call.answered",
                      "call.completed",
                      "call.failed",
                      "campaign.completed",
                      "campaign.paused",
                      "compliance.check.blocked",
                      "wallet.balance.low",
                      "number.suspended",
                      "number.reactivated",
                      "knowledge.build.completed",
                      "knowledge.build.failed"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Any 2xx marks the delivery handled. The body is not read."
          },
          "4XX": {
            "description": "Understood and refused — NOT retried (except 408 and 429). 20 consecutive failures disable the endpoint and email your owners and admins."
          },
          "5XX": {
            "description": "Retried with exponential backoff and jitter, up to 14 attempts over roughly a day."
          }
        },
        "summary": "compliance.check.blocked"
      }
    },
    "knowledge.build.completed": {
      "post": {
        "description": "Delivered to every enabled endpoint subscribed to this event. Verify `x-tone-signature` before trusting the body, respond 2xx within 10 seconds, and deduplicate on `id`.",
        "operationId": "webhook.knowledge_build_completed",
        "parameters": [
          {
            "description": "One or more space-delimited `v1=<hex>` HMAC-SHA256 signatures over `{x-tone-timestamp}.{raw body}`. More than one only during a secret rotation; accept the message if ANY matches.",
            "in": "header",
            "name": "x-tone-signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds, covered by the signature. Reject anything outside your tolerance.",
            "in": "header",
            "name": "x-tone-timestamp",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tone-event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable across retries — this is your deduplication key.",
            "in": "header",
            "name": "x-tone-event-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 on the first send; up to 14 over roughly a day.",
            "in": "header",
            "name": "x-tone-delivery-attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "created_at": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "description": "Keyed by subject: `call`, `campaign`, `number`, `check`, `wallet`, or `knowledgeBase` + `build`. Each object is what that resource's own GET returns.",
                    "type": "object"
                  },
                  "id": {
                    "description": "Event id, identical to `x-tone-event-id`.",
                    "type": "string"
                  },
                  "links": {
                    "description": "Present only when there is something behind them — branch on presence, not on a 404.",
                    "properties": {
                      "recording": {
                        "format": "uri",
                        "type": "string"
                      },
                      "self": {
                        "format": "uri",
                        "type": "string"
                      },
                      "transcript": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "OPEN SET — log and ignore a type you do not recognise.",
                    "type": "string",
                    "x-known-values": [
                      "call.initiated",
                      "call.answered",
                      "call.completed",
                      "call.failed",
                      "campaign.completed",
                      "campaign.paused",
                      "compliance.check.blocked",
                      "wallet.balance.low",
                      "number.suspended",
                      "number.reactivated",
                      "knowledge.build.completed",
                      "knowledge.build.failed"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Any 2xx marks the delivery handled. The body is not read."
          },
          "4XX": {
            "description": "Understood and refused — NOT retried (except 408 and 429). 20 consecutive failures disable the endpoint and email your owners and admins."
          },
          "5XX": {
            "description": "Retried with exponential backoff and jitter, up to 14 attempts over roughly a day."
          }
        },
        "summary": "knowledge.build.completed"
      }
    },
    "knowledge.build.failed": {
      "post": {
        "description": "Delivered to every enabled endpoint subscribed to this event. Verify `x-tone-signature` before trusting the body, respond 2xx within 10 seconds, and deduplicate on `id`.",
        "operationId": "webhook.knowledge_build_failed",
        "parameters": [
          {
            "description": "One or more space-delimited `v1=<hex>` HMAC-SHA256 signatures over `{x-tone-timestamp}.{raw body}`. More than one only during a secret rotation; accept the message if ANY matches.",
            "in": "header",
            "name": "x-tone-signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds, covered by the signature. Reject anything outside your tolerance.",
            "in": "header",
            "name": "x-tone-timestamp",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tone-event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable across retries — this is your deduplication key.",
            "in": "header",
            "name": "x-tone-event-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 on the first send; up to 14 over roughly a day.",
            "in": "header",
            "name": "x-tone-delivery-attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "created_at": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "description": "Keyed by subject: `call`, `campaign`, `number`, `check`, `wallet`, or `knowledgeBase` + `build`. Each object is what that resource's own GET returns.",
                    "type": "object"
                  },
                  "id": {
                    "description": "Event id, identical to `x-tone-event-id`.",
                    "type": "string"
                  },
                  "links": {
                    "description": "Present only when there is something behind them — branch on presence, not on a 404.",
                    "properties": {
                      "recording": {
                        "format": "uri",
                        "type": "string"
                      },
                      "self": {
                        "format": "uri",
                        "type": "string"
                      },
                      "transcript": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "OPEN SET — log and ignore a type you do not recognise.",
                    "type": "string",
                    "x-known-values": [
                      "call.initiated",
                      "call.answered",
                      "call.completed",
                      "call.failed",
                      "campaign.completed",
                      "campaign.paused",
                      "compliance.check.blocked",
                      "wallet.balance.low",
                      "number.suspended",
                      "number.reactivated",
                      "knowledge.build.completed",
                      "knowledge.build.failed"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Any 2xx marks the delivery handled. The body is not read."
          },
          "4XX": {
            "description": "Understood and refused — NOT retried (except 408 and 429). 20 consecutive failures disable the endpoint and email your owners and admins."
          },
          "5XX": {
            "description": "Retried with exponential backoff and jitter, up to 14 attempts over roughly a day."
          }
        },
        "summary": "knowledge.build.failed"
      }
    },
    "number.reactivated": {
      "post": {
        "description": "Delivered to every enabled endpoint subscribed to this event. Verify `x-tone-signature` before trusting the body, respond 2xx within 10 seconds, and deduplicate on `id`.",
        "operationId": "webhook.number_reactivated",
        "parameters": [
          {
            "description": "One or more space-delimited `v1=<hex>` HMAC-SHA256 signatures over `{x-tone-timestamp}.{raw body}`. More than one only during a secret rotation; accept the message if ANY matches.",
            "in": "header",
            "name": "x-tone-signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds, covered by the signature. Reject anything outside your tolerance.",
            "in": "header",
            "name": "x-tone-timestamp",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tone-event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable across retries — this is your deduplication key.",
            "in": "header",
            "name": "x-tone-event-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 on the first send; up to 14 over roughly a day.",
            "in": "header",
            "name": "x-tone-delivery-attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "created_at": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "description": "Keyed by subject: `call`, `campaign`, `number`, `check`, `wallet`, or `knowledgeBase` + `build`. Each object is what that resource's own GET returns.",
                    "type": "object"
                  },
                  "id": {
                    "description": "Event id, identical to `x-tone-event-id`.",
                    "type": "string"
                  },
                  "links": {
                    "description": "Present only when there is something behind them — branch on presence, not on a 404.",
                    "properties": {
                      "recording": {
                        "format": "uri",
                        "type": "string"
                      },
                      "self": {
                        "format": "uri",
                        "type": "string"
                      },
                      "transcript": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "OPEN SET — log and ignore a type you do not recognise.",
                    "type": "string",
                    "x-known-values": [
                      "call.initiated",
                      "call.answered",
                      "call.completed",
                      "call.failed",
                      "campaign.completed",
                      "campaign.paused",
                      "compliance.check.blocked",
                      "wallet.balance.low",
                      "number.suspended",
                      "number.reactivated",
                      "knowledge.build.completed",
                      "knowledge.build.failed"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Any 2xx marks the delivery handled. The body is not read."
          },
          "4XX": {
            "description": "Understood and refused — NOT retried (except 408 and 429). 20 consecutive failures disable the endpoint and email your owners and admins."
          },
          "5XX": {
            "description": "Retried with exponential backoff and jitter, up to 14 attempts over roughly a day."
          }
        },
        "summary": "number.reactivated"
      }
    },
    "number.suspended": {
      "post": {
        "description": "Delivered to every enabled endpoint subscribed to this event. Verify `x-tone-signature` before trusting the body, respond 2xx within 10 seconds, and deduplicate on `id`.",
        "operationId": "webhook.number_suspended",
        "parameters": [
          {
            "description": "One or more space-delimited `v1=<hex>` HMAC-SHA256 signatures over `{x-tone-timestamp}.{raw body}`. More than one only during a secret rotation; accept the message if ANY matches.",
            "in": "header",
            "name": "x-tone-signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds, covered by the signature. Reject anything outside your tolerance.",
            "in": "header",
            "name": "x-tone-timestamp",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tone-event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable across retries — this is your deduplication key.",
            "in": "header",
            "name": "x-tone-event-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 on the first send; up to 14 over roughly a day.",
            "in": "header",
            "name": "x-tone-delivery-attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "created_at": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "description": "Keyed by subject: `call`, `campaign`, `number`, `check`, `wallet`, or `knowledgeBase` + `build`. Each object is what that resource's own GET returns.",
                    "type": "object"
                  },
                  "id": {
                    "description": "Event id, identical to `x-tone-event-id`.",
                    "type": "string"
                  },
                  "links": {
                    "description": "Present only when there is something behind them — branch on presence, not on a 404.",
                    "properties": {
                      "recording": {
                        "format": "uri",
                        "type": "string"
                      },
                      "self": {
                        "format": "uri",
                        "type": "string"
                      },
                      "transcript": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "OPEN SET — log and ignore a type you do not recognise.",
                    "type": "string",
                    "x-known-values": [
                      "call.initiated",
                      "call.answered",
                      "call.completed",
                      "call.failed",
                      "campaign.completed",
                      "campaign.paused",
                      "compliance.check.blocked",
                      "wallet.balance.low",
                      "number.suspended",
                      "number.reactivated",
                      "knowledge.build.completed",
                      "knowledge.build.failed"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Any 2xx marks the delivery handled. The body is not read."
          },
          "4XX": {
            "description": "Understood and refused — NOT retried (except 408 and 429). 20 consecutive failures disable the endpoint and email your owners and admins."
          },
          "5XX": {
            "description": "Retried with exponential backoff and jitter, up to 14 attempts over roughly a day."
          }
        },
        "summary": "number.suspended"
      }
    },
    "wallet.balance.low": {
      "post": {
        "description": "Delivered to every enabled endpoint subscribed to this event. Verify `x-tone-signature` before trusting the body, respond 2xx within 10 seconds, and deduplicate on `id`.",
        "operationId": "webhook.wallet_balance_low",
        "parameters": [
          {
            "description": "One or more space-delimited `v1=<hex>` HMAC-SHA256 signatures over `{x-tone-timestamp}.{raw body}`. More than one only during a secret rotation; accept the message if ANY matches.",
            "in": "header",
            "name": "x-tone-signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds, covered by the signature. Reject anything outside your tolerance.",
            "in": "header",
            "name": "x-tone-timestamp",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-tone-event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable across retries — this is your deduplication key.",
            "in": "header",
            "name": "x-tone-event-id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 on the first send; up to 14 over roughly a day.",
            "in": "header",
            "name": "x-tone-delivery-attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "created_at": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "description": "Keyed by subject: `call`, `campaign`, `number`, `check`, `wallet`, or `knowledgeBase` + `build`. Each object is what that resource's own GET returns.",
                    "type": "object"
                  },
                  "id": {
                    "description": "Event id, identical to `x-tone-event-id`.",
                    "type": "string"
                  },
                  "links": {
                    "description": "Present only when there is something behind them — branch on presence, not on a 404.",
                    "properties": {
                      "recording": {
                        "format": "uri",
                        "type": "string"
                      },
                      "self": {
                        "format": "uri",
                        "type": "string"
                      },
                      "transcript": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": {
                    "description": "OPEN SET — log and ignore a type you do not recognise.",
                    "type": "string",
                    "x-known-values": [
                      "call.initiated",
                      "call.answered",
                      "call.completed",
                      "call.failed",
                      "campaign.completed",
                      "campaign.paused",
                      "compliance.check.blocked",
                      "wallet.balance.low",
                      "number.suspended",
                      "number.reactivated",
                      "knowledge.build.completed",
                      "knowledge.build.failed"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "created_at",
                  "data",
                  "links"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Any 2xx marks the delivery handled. The body is not read."
          },
          "4XX": {
            "description": "Understood and refused — NOT retried (except 408 and 429). 20 consecutive failures disable the endpoint and email your owners and admins."
          },
          "5XX": {
            "description": "Retried with exponential backoff and jitter, up to 14 attempts over roughly a day."
          }
        },
        "summary": "wallet.balance.low"
      }
    }
  }
}
