{
  "components": {
    "schemas": {
      "BatchCallRequest": {
        "description": "`POST /api/v1/public/outbound-calls/batch`.",
        "properties": {
          "assistant_id": {
            "default": "outbound",
            "maxLength": 190,
            "title": "Assistant Id",
            "type": "string"
          },
          "concurrency": {
            "default": 0,
            "maximum": 1000.0,
            "minimum": 0.0,
            "title": "Concurrency",
            "type": "integer"
          },
          "contacts": {
            "items": {
              "$ref": "#/components/schemas/BatchContact"
            },
            "title": "Contacts",
            "type": "array"
          },
          "from_numbers": {
            "items": {
              "type": "string"
            },
            "title": "From Numbers",
            "type": "array"
          },
          "purpose": {
            "default": "",
            "maxLength": 500,
            "title": "Purpose",
            "type": "string"
          },
          "record": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Record"
          },
          "webhook_events": {
            "items": {
              "type": "string"
            },
            "title": "Webhook Events",
            "type": "array"
          },
          "webhook_secret": {
            "default": "",
            "maxLength": 512,
            "title": "Webhook Secret",
            "type": "string"
          },
          "webhook_url": {
            "default": "",
            "maxLength": 2048,
            "title": "Webhook Url",
            "type": "string"
          }
        },
        "title": "BatchCallRequest",
        "type": "object"
      },
      "BatchContact": {
        "description": "One recipient. `to_number` + `variables`, the same two names a single call\nuses, so nothing has to be spelled differently in a batch.",
        "properties": {
          "booking_ref": {
            "default": "",
            "pattern": "^$|^[A-Za-z0-9_-]{8,128}$",
            "title": "Booking Ref",
            "type": "string"
          },
          "to_number": {
            "maxLength": 32,
            "minLength": 1,
            "title": "To Number",
            "type": "string"
          },
          "variables": {
            "additionalProperties": true,
            "title": "Variables",
            "type": "object"
          }
        },
        "required": [
          "to_number"
        ],
        "title": "BatchContact",
        "type": "object"
      },
      "BrowserCallRequest": {
        "description": "`POST /api/v1/public/browser-calls`.\n\nReturns a short-lived, single-use grant your web page uses to open a voice\ncall to an assistant. Your SERVER calls this; the grant goes to the browser,\nso your API key never does.",
        "properties": {
          "assistant_id": {
            "maxLength": 190,
            "minLength": 1,
            "title": "Assistant Id",
            "type": "string"
          },
          "ip": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ip"
          },
          "limit": {
            "anyOf": [
              {
                "maximum": 100000.0,
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Limit"
          },
          "ttl_s": {
            "default": 120,
            "maximum": 600.0,
            "minimum": 1.0,
            "title": "Ttl S",
            "type": "integer"
          }
        },
        "required": [
          "assistant_id"
        ],
        "title": "BrowserCallRequest",
        "type": "object"
      },
      "ChatMessageRequest": {
        "description": "`POST /api/v1/public/chats/{chat_id}/messages`.",
        "properties": {
          "text": {
            "maxLength": 4000,
            "minLength": 1,
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "text"
        ],
        "title": "ChatMessageRequest",
        "type": "object"
      },
      "ContactBulkRequest": {
        "description": "`POST /api/v1/public/contacts/bulk`: build or refresh a contact list.",
        "properties": {
          "contacts": {
            "items": {
              "$ref": "#/components/schemas/ContactFields"
            },
            "maxItems": 1000,
            "minItems": 1,
            "title": "Contacts",
            "type": "array"
          },
          "default_country": {
            "default": "",
            "maxLength": 8,
            "title": "Default Country",
            "type": "string"
          },
          "groups": {
            "items": {
              "type": "string"
            },
            "maxItems": 20,
            "title": "Groups",
            "type": "array"
          }
        },
        "required": [
          "contacts"
        ],
        "title": "ContactBulkRequest",
        "type": "object"
      },
      "ContactCreateRequest": {
        "description": "`POST /api/v1/public/contacts`.",
        "properties": {
          "company": {
            "default": "",
            "maxLength": 200,
            "title": "Company",
            "type": "string"
          },
          "country": {
            "default": "",
            "maxLength": 8,
            "title": "Country",
            "type": "string"
          },
          "email": {
            "default": "",
            "maxLength": 200,
            "title": "Email",
            "type": "string"
          },
          "fields": {
            "additionalProperties": true,
            "title": "Fields",
            "type": "object"
          },
          "groups": {
            "items": {
              "type": "string"
            },
            "maxItems": 20,
            "title": "Groups",
            "type": "array"
          },
          "local_number": {
            "default": "",
            "maxLength": 64,
            "title": "Local Number",
            "type": "string"
          },
          "name": {
            "default": "",
            "maxLength": 200,
            "title": "Name",
            "type": "string"
          },
          "notes": {
            "default": "",
            "maxLength": 2000,
            "title": "Notes",
            "type": "string"
          },
          "phone": {
            "default": "",
            "maxLength": 64,
            "title": "Phone",
            "type": "string"
          }
        },
        "title": "ContactCreateRequest",
        "type": "object"
      },
      "ContactFields": {
        "description": "The fields one contact carries. `phone` in E.164, or `local_number` with\n`country` (ISO alpha-2), the same two shapes the dashboard accepts.",
        "properties": {
          "company": {
            "default": "",
            "maxLength": 200,
            "title": "Company",
            "type": "string"
          },
          "country": {
            "default": "",
            "maxLength": 8,
            "title": "Country",
            "type": "string"
          },
          "email": {
            "default": "",
            "maxLength": 200,
            "title": "Email",
            "type": "string"
          },
          "fields": {
            "additionalProperties": true,
            "title": "Fields",
            "type": "object"
          },
          "local_number": {
            "default": "",
            "maxLength": 64,
            "title": "Local Number",
            "type": "string"
          },
          "name": {
            "default": "",
            "maxLength": 200,
            "title": "Name",
            "type": "string"
          },
          "notes": {
            "default": "",
            "maxLength": 2000,
            "title": "Notes",
            "type": "string"
          },
          "phone": {
            "default": "",
            "maxLength": 64,
            "title": "Phone",
            "type": "string"
          }
        },
        "title": "ContactFields",
        "type": "object"
      },
      "ContactUpdateRequest": {
        "description": "`PATCH /api/v1/public/contacts/{contact_id}`. Omitted means unchanged;\n`fields` merges into what is there.",
        "properties": {
          "company": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Company"
          },
          "country": {
            "anyOf": [
              {
                "maxLength": 8,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country"
          },
          "email": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email"
          },
          "fields": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fields"
          },
          "local_number": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Local Number"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "notes": {
            "anyOf": [
              {
                "maxLength": 2000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "phone": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone"
          }
        },
        "title": "ContactUpdateRequest",
        "type": "object"
      },
      "EmbedMessage": {
        "properties": {
          "text": {
            "maxLength": 4000,
            "minLength": 1,
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "text"
        ],
        "title": "EmbedMessage",
        "type": "object"
      },
      "EmbedStartChat": {
        "description": "`POST /api/v1/public/embed/chats`. The assistant and visitor come from\nthe session token, not from here.",
        "properties": {
          "greet": {
            "default": false,
            "title": "Greet",
            "type": "boolean"
          },
          "language": {
            "default": "en",
            "maxLength": 16,
            "minLength": 2,
            "title": "Language",
            "type": "string"
          }
        },
        "title": "EmbedStartChat",
        "type": "object"
      },
      "Error": {
        "properties": {
          "error": {
            "properties": {
              "code": {
                "description": "Stable machine-readable code. Branch on this, never on the message.",
                "examples": [
                  "INVALID_API_KEY"
                ],
                "type": "string"
              },
              "details": {
                "additionalProperties": true,
                "description": "Present when there is something structured to say. Validation failures carry `fields`.",
                "type": "object"
              },
              "message": {
                "description": "Human-readable sentence. May be reworded.",
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ],
            "type": "object"
          }
        },
        "required": [
          "error"
        ],
        "type": "object"
      },
      "GroupCreateRequest": {
        "description": "`POST /api/v1/public/contacts/groups`.",
        "properties": {
          "name": {
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "title": "GroupCreateRequest",
        "type": "object"
      },
      "GroupMembersRequest": {
        "description": "`POST /contacts/groups/{group_id}/members` and `.../members/remove`.",
        "properties": {
          "contact_ids": {
            "items": {
              "type": "string"
            },
            "maxItems": 1000,
            "minItems": 1,
            "title": "Contact Ids",
            "type": "array"
          }
        },
        "required": [
          "contact_ids"
        ],
        "title": "GroupMembersRequest",
        "type": "object"
      },
      "OutboundCallRequest": {
        "description": "`POST /api/v1/public/outbound-calls` \u2014 one outbound call.\n\nA deliberate SUBSET of `service.app.OutboundCallBody`. `contact` is omitted\nbecause it is the deprecated pre-`variables` field and a new contract should\nnot carry one whose replacement already shipped.",
        "properties": {
          "assistant_id": {
            "default": "outbound",
            "maxLength": 190,
            "title": "Assistant Id",
            "type": "string"
          },
          "booking_ref": {
            "default": "",
            "pattern": "^$|^[A-Za-z0-9_-]{8,128}$",
            "title": "Booking Ref",
            "type": "string"
          },
          "context": {
            "default": "",
            "maxLength": 2000,
            "title": "Context",
            "type": "string"
          },
          "from_number": {
            "anyOf": [
              {
                "maxLength": 32,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "From Number"
          },
          "max_attempts": {
            "default": 1,
            "maximum": 5.0,
            "minimum": 1.0,
            "title": "Max Attempts",
            "type": "integer"
          },
          "purpose": {
            "default": "",
            "maxLength": 500,
            "title": "Purpose",
            "type": "string"
          },
          "record": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Record"
          },
          "to_number": {
            "maxLength": 32,
            "minLength": 1,
            "title": "To Number",
            "type": "string"
          },
          "variables": {
            "additionalProperties": true,
            "title": "Variables",
            "type": "object"
          },
          "webhook_events": {
            "items": {
              "type": "string"
            },
            "title": "Webhook Events",
            "type": "array"
          },
          "webhook_secret": {
            "default": "",
            "maxLength": 512,
            "title": "Webhook Secret",
            "type": "string"
          },
          "webhook_url": {
            "default": "",
            "maxLength": 2048,
            "title": "Webhook Url",
            "type": "string"
          }
        },
        "required": [
          "to_number"
        ],
        "title": "OutboundCallRequest",
        "type": "object"
      },
      "StartChatRequest": {
        "description": "`POST /api/v1/public/chats`.",
        "properties": {
          "assistant_id": {
            "maxLength": 190,
            "minLength": 1,
            "title": "Assistant Id",
            "type": "string"
          },
          "greet": {
            "default": true,
            "title": "Greet",
            "type": "boolean"
          },
          "language": {
            "default": "en",
            "maxLength": 16,
            "minLength": 2,
            "title": "Language",
            "type": "string"
          },
          "visitor_id": {
            "default": "anonymous",
            "maxLength": 190,
            "minLength": 1,
            "title": "Visitor Id",
            "type": "string"
          }
        },
        "required": [
          "assistant_id"
        ],
        "title": "StartChatRequest",
        "type": "object"
      },
      "WidgetSessionRequest": {
        "description": "`POST /api/v1/public/widget/sessions`.",
        "properties": {
          "assistant_id": {
            "default": "",
            "maxLength": 190,
            "title": "Assistant Id",
            "type": "string"
          },
          "ttl_s": {
            "default": 3600,
            "maximum": 86400.0,
            "minimum": 60.0,
            "title": "Ttl S",
            "type": "integer"
          },
          "visitor_id": {
            "default": "",
            "maxLength": 190,
            "title": "Visitor Id",
            "type": "string"
          }
        },
        "title": "WidgetSessionRequest",
        "type": "object"
      },
      "WidgetSettingsUpdate": {
        "additionalProperties": false,
        "description": "`PATCH /api/v1/public/widget`. Every field optional; only the ones sent\nchange. Unknown fields are refused, so a misspelt setting is an error rather\nthan a request that \"worked\" and changed nothing.",
        "properties": {
          "allowed_origins": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Allowed Origins"
          },
          "assistant_id": {
            "anyOf": [
              {
                "maxLength": 190,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Assistant Id"
          },
          "default_mode": {
            "anyOf": [
              {
                "pattern": "^(chat|call|phone)$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Default Mode"
          },
          "enable_chat": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Enable Chat"
          },
          "enable_phone": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Enable Phone"
          },
          "enable_web_call": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Enable Web Call"
          },
          "enabled": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Enabled"
          },
          "greeting": {
            "anyOf": [
              {
                "maxLength": 500,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Greeting"
          },
          "launcher_text": {
            "anyOf": [
              {
                "maxLength": 80,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Launcher Text"
          },
          "position": {
            "anyOf": [
              {
                "pattern": "^bottom-(right|left)$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Position"
          },
          "primary_color": {
            "anyOf": [
              {
                "pattern": "^#[0-9a-fA-F]{6}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Primary Color"
          },
          "subtitle": {
            "anyOf": [
              {
                "maxLength": 160,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtitle"
          },
          "title": {
            "anyOf": [
              {
                "maxLength": 80,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title"
          },
          "voice": {
            "anyOf": [
              {
                "maxLength": 120,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Voice"
          },
          "web_call_hourly_limit": {
            "anyOf": [
              {
                "maximum": 100000.0,
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Web Call Hourly Limit"
          }
        },
        "title": "WidgetSettingsUpdate",
        "type": "object"
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "description": "An organization API key from the Ciao dashboard (Developer -> API Keys). Format: `sk_live_...`. Keep it server-side; never ship it in browser code.",
        "scheme": "bearer",
        "type": "http"
      },
      "WidgetSessionAuth": {
        "description": "A widget session token, minted by YOUR server with its API key through `POST /widget/sessions` and handed to the page. Used ONLY by the `/embed/*` routes the widget calls from a visitor's browser. Bound to that API key, one assistant and one visitor; expires in an hour by default.",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "description": "The Ciao public developer API: start calls and text chats from your own\napplication, read their transcripts, and read the assistants your organization\nowns.\n\nAuthenticate with an organization API key created in the Ciao dashboard, sent as\n`Authorization: Bearer <API_KEY>`. The organization is taken from the key, so no\nrequest carries an account or tenant field.\n\nIntegrations can also keep the organization's contact book in step: add and\nupdate contacts one at a time or up to 1,000 per request, and file them into\ngroups (contact lists) that the dashboard and batch calling can then use\n(`/contacts`). This needs a key created with \"Manage contacts\".\n\nThe web widget is the one exception to the next paragraph: its settings can be\nread and changed here (`/widget`). The widget itself calls the `/embed/*` routes\nfrom a visitor's browser with a session token your server mints with its API\nkey (`POST /widget/sessions`), never with the API key.\n\nConfiguration stays in the dashboard. Creating and configuring assistants,\nconnecting telephony, managing phone numbers and knowledge bases are not part of\nthis API, and a public key does not hold the permissions those operations\nrequire.\n\nFull guide, including error codes and integration examples: `PUBLIC_API.md`.\n",
    "title": "Ciao Public Developer API",
    "version": "1.0.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/api/v1/public/assistants": {
      "get": {
        "description": "Every assistant this organization owns that this key may drive.\n\nReuses `service.app.list_agents`, so the filtering, the publish status and\nthe per-key assistant allowlist are that handler's. Assistants are created\nand configured in the Ciao dashboard; this rail is read-only, and there is\ndeliberately no create, update or delete.\n\nPaginated in this layer rather than in the reused handler: `GET /v1/agents`\nreturns a tenant's whole registry in one response and has no pagination to\ndelegate to. The list is small (an organization has tens of assistants, not\nthousands), so slicing here is honest and cheap.",
        "operationId": "public_list_assistants_api_v1_public_assistants_get",
        "parameters": [
          {
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "default": "",
              "title": "Type",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "callable_only",
            "required": false,
            "schema": {
              "default": false,
              "title": "Callable Only",
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public List Assistants Api V1 Public Assistants Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public List Assistants",
        "tags": [
          "public"
        ]
      }
    },
    "/api/v1/public/assistants/{assistant_id}": {
      "get": {
        "description": "One assistant and its published contract.\n\nReuses `service.app.get_published_contract`. An assistant this key may not\ndrive answers **404, not 403** \u2014 the same answer an unknown id gets, so a\nleaked key cannot enumerate what else the organization runs. That behaviour\nis the reused handler's and is preserved rather than re-implemented.",
        "operationId": "public_get_assistant_api_v1_public_assistants__assistant_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "assistant_id",
            "required": true,
            "schema": {
              "title": "Assistant Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Get Assistant Api V1 Public Assistants  Assistant Id  Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource for this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Get Assistant",
        "tags": [
          "public"
        ]
      }
    },
    "/api/v1/public/browser-calls": {
      "post": {
        "description": "Start a browser call: mint a grant your web page uses to open the socket.\n\nReuses `service.app.mint_agent_token` entirely, so the assistant allowlist,\nthe resolved-agent check and the token minting are the code already in\nproduction. Nothing about the browser call path itself is duplicated.\n\nThe returned `token` is single-use, bound to one assistant and one\norganization, and expires in `expires_in` seconds. Hand it to the browser;\nnever the API key.",
        "operationId": "public_browser_call_api_v1_public_browser_calls_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BrowserCallRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Browser Call Api V1 Public Browser Calls Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource for this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Browser Call",
        "tags": [
          "public"
        ]
      }
    },
    "/api/v1/public/calls/{call_id}/transcript": {
      "get": {
        "description": "The conversation, oldest line first. Works for phone and browser calls.\n\nReuses `service.app.get_call_transcript`, so the source chain, the tenant\nscoping and the redaction against the call's pinned contract are the code\nalready serving the dashboard.\n\n**`final` tells you whether more is coming.** Read this route while the call\nis still up and you get what has been said SO FAR with `final: false`; after\nhangup it is `true` and the transcript is complete. That is what makes\npolling safe \u2014 without it there is no way to tell a short call from an\nunfinished read.\n\n**A 404 is often not an error.** The call may not have been answered, may\nhave ended before anyone spoke, or the organization may store no conversation\ncontent (zero retention). Check the call's status before concluding anything\nfrom it.\n\n`source` names which copy answered \u2014 `frozen`, `call_result`, `turns` or\n`live`. It is reported rather than hidden because \"which copy is this\" is\nexactly what decides whether an empty answer means \"nothing was said\" or\n\"not written yet\".",
        "operationId": "public_call_transcript_api_v1_public_calls__call_id__transcript_get",
        "parameters": [
          {
            "in": "path",
            "name": "call_id",
            "required": true,
            "schema": {
              "title": "Call Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Call Transcript Api V1 Public Calls  Call Id  Transcript Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource for this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Call Transcript",
        "tags": [
          "public"
        ]
      }
    },
    "/api/v1/public/calls/{call_id}/transcript/stream": {
      "get": {
        "description": "The live transcript, as Server-Sent Events, while the call is happening.\n\nReuses `service.app.live_call_transcript` \u2014 the same stream the dashboard's\nown call console watches.\n\n**This route does not use the `{\"data\": ...}` envelope**, and cannot: the\nresponse is an open `text/event-stream`, not a document. It is the one\nexception on this rail, and it is the same exception every SSE endpoint makes.\n\nEach event's `data` is one line, `{\"role\", \"text\"}`, with `role` normalised\nto `user` / `assistant` exactly as the read-back route above normalises it.\nLines already spoken before you attached are replayed first, so connecting\nmid-call does not lose the beginning. A `: keep-alive` comment every 15\nseconds holds the connection open through idle proxies; ignore it. The\nterminal event is `event: end`, which is the call ending \u2014 not an error, and\nnot something to reconnect through.\n\nAttach with the CallSid the moment `POST /outbound-calls` returns it: a call\nis attributable from the instant it is planned, so there is no race between\nplacing a call and watching it.",
        "operationId": "public_call_transcript_stream_api_v1_public_calls__call_id__transcript_stream_get",
        "parameters": [
          {
            "in": "path",
            "name": "call_id",
            "required": true,
            "schema": {
              "title": "Call Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource for this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Call Transcript Stream",
        "tags": [
          "public"
        ]
      }
    },
    "/api/v1/public/chats": {
      "get": {
        "description": "List this organization's chats, newest first.\n\nReuses `service.app.list_conversations` with `channel` pinned to `chat`, so\nevery filter is applied in the index rather than over a page that has already\nbeen fetched \u2014 and voice conversations never appear here, whatever is asked\nfor.\n\n`from` and `to` are dates or ISO timestamps; a bare date in `to` covers the\nwhole of that day. `q` searches the summary text.",
        "operationId": "public_list_chats_api_v1_public_chats_get",
        "parameters": [
          {
            "in": "query",
            "name": "assistant_id",
            "required": false,
            "schema": {
              "default": "",
              "maxLength": 190,
              "title": "Assistant Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "default": "",
              "title": "From",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "default": "",
              "title": "To",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "default": "",
              "maxLength": 200,
              "title": "Q",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public List Chats Api V1 Public Chats Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public List Chats",
        "tags": [
          "public"
        ]
      },
      "post": {
        "description": "Start a chat with one of your assistants.\n\nReuses `ConversationOrchestrator.start_call` with `channel=\"chat\"` \u2014 the same\ncall `POST /v1/calls` makes \u2014 so the retention decision, the capture pipeline\nand the idle-close registration are the production ones.\n\nThe chat is registered for the idle sweep that closes and summarises it, so\nan integrator that never calls `/end` still gets a complete, summarised row\nrather than a conversation stuck at `live` forever. That sweep runs on\n`CONVERSATION_IDLE_CLOSE_S`, 15 minutes by default.\n\nWith `greet: true` the opening line is generated here, returned as `message`\nand written to the transcript as its first line (see `_capture_opening`,\nwhich exists because `open_call` does not do that itself).",
        "operationId": "public_start_chat_api_v1_public_chats_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartChatRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Start Chat Api V1 Public Chats Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource for this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Start Chat",
        "tags": [
          "public"
        ]
      }
    },
    "/api/v1/public/chats/{chat_id}": {
      "get": {
        "description": "One chat: its metadata and its full transcript, oldest message first.\n\nReuses `service.app.get_conversation`, the same handler the Conversations\nscreen reads. Works while the chat is live and after it has ended; `status`\nsays which.\n\nA conversation that is not a CHAT answers 404 \u2014 the reused handler does not\nfilter by channel, and this rail must not become a way to read a phone\ntranscript through a chat-shaped response.\n\nAn empty `messages` list on a real chat is a normal answer, not a bug: the\norganization may have zero retention configured, the turns may still be in\nthe write-behind queue, or they may have been captured by another worker.",
        "operationId": "public_get_chat_api_v1_public_chats__chat_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "title": "Chat Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Get Chat Api V1 Public Chats  Chat Id  Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource for this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Get Chat",
        "tags": [
          "public"
        ]
      }
    },
    "/api/v1/public/chats/{chat_id}/end": {
      "post": {
        "description": "End a chat and get its summary.\n\nOptional. A chat you simply stop posting to is closed and summarised by the\nidle sweep, producing an identical row \u2014 calling this only makes it happen\nnow instead of in fifteen minutes, which is what you want when the user has\nclosed the chat window.\n\nReuses `AppState.close_chat_conversation`, the same function the sweep and\nthe console's \"New conversation\" button reach, so an explicitly ended chat\nand an idle-closed one are the same record.\n\nEnding a chat that has already ended is a 404 rather than a second close:\nsummarising twice would pay for two summaries and overwrite the first.",
        "operationId": "public_end_chat_api_v1_public_chats__chat_id__end_post",
        "parameters": [
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "title": "Chat Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public End Chat Api V1 Public Chats  Chat Id  End Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource for this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public End Chat",
        "tags": [
          "public"
        ]
      }
    },
    "/api/v1/public/chats/{chat_id}/messages": {
      "post": {
        "description": "Send one message and get the assistant's reply.\n\nSynchronous and complete: the reply comes back in this response, already\nfinished. There is no streaming variant, because\n`ConversationOrchestrator.handle_turn` \u2014 the coroutine `POST\n/v1/calls/{id}/turn` runs, and the one this calls \u2014 produces a whole turn\nbefore it returns. A token-streaming endpoint would be a second\nimplementation of the turn path, which this rail does not do.\n\nEach message resets the inactivity clock on the session, on this rail's\nsession map, and on the idle-close sweep.",
        "operationId": "public_send_message_api_v1_public_chats__chat_id__messages_post",
        "parameters": [
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "title": "Chat Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatMessageRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Send Message Api V1 Public Chats  Chat Id  Messages Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Plan or credits exhausted. Code: PAYMENT_REQUIRED."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource for this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Send Message",
        "tags": [
          "public"
        ]
      }
    },
    "/api/v1/public/client-ip": {
      "get": {
        "description": "The address we observe this request coming from.\n\n**Called by the browser, not by your server.** That is the whole point: your\nserver sees its own address, and a page that asks its server \"who is my\nvisitor\" gets an answer only as good as whatever proxy chain sits in front of\nit. This route answers with the address THIS service observed, resolved the\nsame way the API key IP allowlist resolves it (`config.client_ip`, which\nhonours `X-Forwarded-For` only from a configured trusted proxy).\n\nHand the value to your server and pass it as `ip` when you request a\nbrowser-call grant, so per-visitor limits count the visitor rather than your\nserver.\n\n**Unauthenticated, and CORS-open, both deliberately.** It is called from the\ncustomer's own web page, which holds no API key (that is the entire security\nmodel of browser calling) and is served from their origin, not ours. What it\ndiscloses is the caller's own address, which the caller already knows: there\nis nothing here that is not in the request that asked for it.\n\nIt is still gated by `PUBLIC_API_ENABLED`, and it is deliberately NOT rate\nlimited per organization like the authenticated routes, because it has no\norganization \u2014 the global limiter still applies.",
        "operationId": "public_client_ip_api_v1_public_client_ip_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "security": [],
        "summary": "Public Client Ip",
        "tags": [
          "public"
        ]
      }
    },
    "/api/v1/public/contacts": {
      "get": {
        "description": "One page of contacts, newest first, with the total behind it.\n\n`q` searches name, phone, email and company. `group_id` lists one group's\nmembers; `ungrouped=true` lists contacts in no group. Reuses\n`service.app.list_contacts`.",
        "operationId": "public_list_contacts_api_v1_public_contacts_get",
        "parameters": [
          {
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "default": "",
              "maxLength": 200,
              "title": "Q",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "group_id",
            "required": false,
            "schema": {
              "default": "",
              "maxLength": 200,
              "title": "Group Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "ungrouped",
            "required": false,
            "schema": {
              "default": false,
              "title": "Ungrouped",
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "do_not_call",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Do Not Call"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public List Contacts Api V1 Public Contacts Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted: the key lacks contacts:read / contacts:write, or the caller's IP is not allowed. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public List Contacts",
        "tags": [
          "contacts"
        ]
      },
      "post": {
        "description": "Add one contact, optionally into groups. Reuses `service.app.create_contact`.\n\n**409 `CONTACT_ALREADY_EXISTS`** when the organization already has the\nnumber; `details.contact_id` is the existing contact, so the next request\ncan be a PATCH. To add-or-update without branching, use `POST /contacts/bulk`.",
        "operationId": "public_create_contact_api_v1_public_contacts_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactCreateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Create Contact Api V1 Public Contacts Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A number that cannot be read as a phone number, a local number with no country, or a request with nothing to do. Code: INVALID_REQUEST."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted: the key lacks contacts:read / contacts:write, or the caller's IP is not allowed. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "This organization already has a contact with that number. `details.contact_id` names it. Code: CONTACT_ALREADY_EXISTS."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Create Contact",
        "tags": [
          "contacts"
        ]
      }
    },
    "/api/v1/public/contacts/bulk": {
      "post": {
        "description": "Add or update up to 1,000 contacts in one request, and file them into groups.\n\nThis is how an integration builds a contact list: name a group in `groups`\nand every saved contact joins it (the group is created if needed). Contacts\nare matched on their normalised number, so re-sending a list updates the\npeople already in it rather than duplicating them, and a field you leave\nblank does not erase what is stored.\n\nRows that cannot be saved (an unreadable number, a number with no country,\na number repeated within the request) come back in `rejected`, indexed\nagainst the `contacts` array you sent (0-based). The rest are saved.\n\nReuses `service.app.bulk_upsert_contacts`, the JSON twin of the dashboard's\nfile import.",
        "operationId": "public_bulk_contacts_api_v1_public_contacts_bulk_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactBulkRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Bulk Contacts Api V1 Public Contacts Bulk Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A number that cannot be read as a phone number, a local number with no country, or a request with nothing to do. Code: INVALID_REQUEST."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted: the key lacks contacts:read / contacts:write, or the caller's IP is not allowed. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Bulk Contacts",
        "tags": [
          "contacts"
        ]
      }
    },
    "/api/v1/public/contacts/groups": {
      "get": {
        "description": "Every group this organization has, by name, with how many contacts are in\neach. Reuses `service.app.list_contact_groups`. The members of a group are\n`GET /contacts?group_id=...`, which pages.",
        "operationId": "public_list_contact_groups_api_v1_public_contacts_groups_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public List Contact Groups Api V1 Public Contacts Groups Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted: the key lacks contacts:read / contacts:write, or the caller's IP is not allowed. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public List Contact Groups",
        "tags": [
          "contacts"
        ]
      },
      "post": {
        "description": "Create an empty group (a contact list).\n\nIdempotent on the name, ignoring case: creating \"Webinar Leads\" when\n\"webinar leads\" exists returns the existing group unchanged. Reuses\n`service.app.create_contact_group`.",
        "operationId": "public_create_contact_group_api_v1_public_contacts_groups_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GroupCreateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Create Contact Group Api V1 Public Contacts Groups Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A number that cannot be read as a phone number, a local number with no country, or a request with nothing to do. Code: INVALID_REQUEST."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted: the key lacks contacts:read / contacts:write, or the caller's IP is not allowed. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Create Contact Group",
        "tags": [
          "contacts"
        ]
      }
    },
    "/api/v1/public/contacts/groups/{group_id}": {
      "get": {
        "description": "One group and its size. Reuses `service.app.get_contact_group`.",
        "operationId": "public_get_contact_group_api_v1_public_contacts_groups__group_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "group_id",
            "required": true,
            "schema": {
              "title": "Group Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Get Contact Group Api V1 Public Contacts Groups  Group Id  Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted: the key lacks contacts:read / contacts:write, or the caller's IP is not allowed. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such contact or group in this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Get Contact Group",
        "tags": [
          "contacts"
        ]
      }
    },
    "/api/v1/public/contacts/groups/{group_id}/members": {
      "post": {
        "description": "Put existing contacts into a group. A contact already in it is left as\nit is, so sending the same ids twice is safe.",
        "operationId": "public_add_group_members_api_v1_public_contacts_groups__group_id__members_post",
        "parameters": [
          {
            "in": "path",
            "name": "group_id",
            "required": true,
            "schema": {
              "title": "Group Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GroupMembersRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Add Group Members Api V1 Public Contacts Groups  Group Id  Members Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted: the key lacks contacts:read / contacts:write, or the caller's IP is not allowed. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such contact or group in this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Add Group Members",
        "tags": [
          "contacts"
        ]
      }
    },
    "/api/v1/public/contacts/groups/{group_id}/members/remove": {
      "post": {
        "description": "Take contacts out of a group. The contacts themselves are not deleted.",
        "operationId": "public_remove_group_members_api_v1_public_contacts_groups__group_id__members_remove_post",
        "parameters": [
          {
            "in": "path",
            "name": "group_id",
            "required": true,
            "schema": {
              "title": "Group Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GroupMembersRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Remove Group Members Api V1 Public Contacts Groups  Group Id  Members Remove Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted: the key lacks contacts:read / contacts:write, or the caller's IP is not allowed. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such contact or group in this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Remove Group Members",
        "tags": [
          "contacts"
        ]
      }
    },
    "/api/v1/public/contacts/{contact_id}": {
      "get": {
        "description": "One contact. Another organization's id is a 404, the same as an unknown\none. Reuses `service.app.get_contact`.",
        "operationId": "public_get_contact_api_v1_public_contacts__contact_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Get Contact Api V1 Public Contacts  Contact Id  Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted: the key lacks contacts:read / contacts:write, or the caller's IP is not allowed. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such contact or group in this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Get Contact",
        "tags": [
          "contacts"
        ]
      },
      "patch": {
        "description": "Edit one contact. Omitted fields are unchanged and `fields` merges.\nReuses `service.app.update_contact`.\n\nChanging the number to one another contact already has is **409\n`CONTACT_ALREADY_EXISTS`**, checked here first: the store's unique index\nwould otherwise refuse it as a server error.",
        "operationId": "public_update_contact_api_v1_public_contacts__contact_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactUpdateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Update Contact Api V1 Public Contacts  Contact Id  Patch",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A number that cannot be read as a phone number, a local number with no country, or a request with nothing to do. Code: INVALID_REQUEST."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted: the key lacks contacts:read / contacts:write, or the caller's IP is not allowed. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such contact or group in this organization. Code: RESOURCE_NOT_FOUND."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "This organization already has a contact with that number. `details.contact_id` names it. Code: CONTACT_ALREADY_EXISTS."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Update Contact",
        "tags": [
          "contacts"
        ]
      }
    },
    "/api/v1/public/embed/browser-calls": {
      "post": {
        "description": "A short-lived grant for a web (microphone) call with this session's\nassistant, bound to this session's visitor. Open the socket with it in both\n`agent_token` and `token` (see `POST /browser-calls`).",
        "operationId": "embed_browser_call_api_v1_public_embed_browser_calls_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Embed Browser Call Api V1 Public Embed Browser Calls Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No widget session token, an invalid or expired one, or the API key behind it has been revoked, regenerated or has expired. Codes: MISSING_WIDGET_TOKEN, INVALID_WIDGET_TOKEN, EXPIRED_WIDGET_TOKEN, REVOKED_API_KEY, EXPIRED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The widget, or this channel of it, is switched off; this site is not in the widget's allowed_origins; or the API key behind the session can no longer start conversations. Codes: WIDGET_DISABLED, ORIGIN_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The session's assistant is gone or no longer allowed for its API key, or a chat that is unknown, expired, or was not started by this widget session's visitor. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "security": [
          {
            "WidgetSessionAuth": []
          }
        ],
        "summary": "Embed Browser Call",
        "tags": [
          "widget"
        ]
      }
    },
    "/api/v1/public/embed/chats": {
      "post": {
        "description": "Start a chat with this session's assistant.",
        "operationId": "embed_start_chat_api_v1_public_embed_chats_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmbedStartChat"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Embed Start Chat Api V1 Public Embed Chats Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No widget session token, an invalid or expired one, or the API key behind it has been revoked, regenerated or has expired. Codes: MISSING_WIDGET_TOKEN, INVALID_WIDGET_TOKEN, EXPIRED_WIDGET_TOKEN, REVOKED_API_KEY, EXPIRED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The widget, or this channel of it, is switched off; this site is not in the widget's allowed_origins; or the API key behind the session can no longer start conversations. Codes: WIDGET_DISABLED, ORIGIN_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The session's assistant is gone or no longer allowed for its API key, or a chat that is unknown, expired, or was not started by this widget session's visitor. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "security": [
          {
            "WidgetSessionAuth": []
          }
        ],
        "summary": "Embed Start Chat",
        "tags": [
          "widget"
        ]
      }
    },
    "/api/v1/public/embed/chats/{chat_id}/end": {
      "post": {
        "description": "End the chat now (the widget calls this on \"New conversation\"). Optional:\na chat left alone is closed and summarised by the idle sweep.",
        "operationId": "embed_end_chat_api_v1_public_embed_chats__chat_id__end_post",
        "parameters": [
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "title": "Chat Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Embed End Chat Api V1 Public Embed Chats  Chat Id  End Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No widget session token, an invalid or expired one, or the API key behind it has been revoked, regenerated or has expired. Codes: MISSING_WIDGET_TOKEN, INVALID_WIDGET_TOKEN, EXPIRED_WIDGET_TOKEN, REVOKED_API_KEY, EXPIRED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The widget, or this channel of it, is switched off; this site is not in the widget's allowed_origins; or the API key behind the session can no longer start conversations. Codes: WIDGET_DISABLED, ORIGIN_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The session's assistant is gone or no longer allowed for its API key, or a chat that is unknown, expired, or was not started by this widget session's visitor. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "security": [
          {
            "WidgetSessionAuth": []
          }
        ],
        "summary": "Embed End Chat",
        "tags": [
          "widget"
        ]
      }
    },
    "/api/v1/public/embed/chats/{chat_id}/messages": {
      "post": {
        "description": "Send one message and get the assistant's reply.",
        "operationId": "embed_send_message_api_v1_public_embed_chats__chat_id__messages_post",
        "parameters": [
          {
            "in": "path",
            "name": "chat_id",
            "required": true,
            "schema": {
              "title": "Chat Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmbedMessage"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Embed Send Message Api V1 Public Embed Chats  Chat Id  Messages Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No widget session token, an invalid or expired one, or the API key behind it has been revoked, regenerated or has expired. Codes: MISSING_WIDGET_TOKEN, INVALID_WIDGET_TOKEN, EXPIRED_WIDGET_TOKEN, REVOKED_API_KEY, EXPIRED_API_KEY."
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Plan or credits exhausted. Code: PAYMENT_REQUIRED."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The widget, or this channel of it, is switched off; this site is not in the widget's allowed_origins; or the API key behind the session can no longer start conversations. Codes: WIDGET_DISABLED, ORIGIN_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The session's assistant is gone or no longer allowed for its API key, or a chat that is unknown, expired, or was not started by this widget session's visitor. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "security": [
          {
            "WidgetSessionAuth": []
          }
        ],
        "summary": "Embed Send Message",
        "tags": [
          "widget"
        ]
      }
    },
    "/api/v1/public/embed/config": {
      "get": {
        "description": "What the widget needs to draw itself, and the assistant this session\ntalks to. `enable_phone` is always false here (see the module docstring).",
        "operationId": "embed_config_api_v1_public_embed_config_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Embed Config Api V1 Public Embed Config Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No widget session token, an invalid or expired one, or the API key behind it has been revoked, regenerated or has expired. Codes: MISSING_WIDGET_TOKEN, INVALID_WIDGET_TOKEN, EXPIRED_WIDGET_TOKEN, REVOKED_API_KEY, EXPIRED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The widget, or this channel of it, is switched off; this site is not in the widget's allowed_origins; or the API key behind the session can no longer start conversations. Codes: WIDGET_DISABLED, ORIGIN_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The session's assistant is gone or no longer allowed for its API key, or a chat that is unknown, expired, or was not started by this widget session's visitor. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "security": [
          {
            "WidgetSessionAuth": []
          }
        ],
        "summary": "Embed Config",
        "tags": [
          "widget"
        ]
      }
    },
    "/api/v1/public/outbound-calls": {
      "post": {
        "description": "Place one outbound call. Reuses `service.app.outbound_call` entirely.\n\nEverything downstream \u2014 E.164 validation, contract validation of\n`variables`, the per-key assistant allowlist, carrier resolution, the\nrecording opt-in, plan enforcement and the `calls` row \u2014 is that handler's,\nunchanged.\n\n**Send `Idempotency-Key`.** A retry with the same key returns the original\nresult instead of dialing a second time, which is the one guarantee that\nmakes a network timeout safe on a route that rings a real phone.",
        "operationId": "public_outbound_call_api_v1_public_outbound_calls_post",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OutboundCallRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Outbound Call Api V1 Public Outbound Calls Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed in a way the schema cannot express, such as a number that is not E.164, or no telephony carrier connected. Code: INVALID_REQUEST."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Plan or credits exhausted. Code: PAYMENT_REQUIRED."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource for this organization. Code: RESOURCE_NOT_FOUND."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The assistant exists but is not in a usable state. Code: ASSISTANT_NOT_PUBLISHED. On a single outbound placement it can also mean a request with the same Idempotency-Key is still being placed; retry shortly to get its result. Code: IN_PROGRESS."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "501": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The resolved carrier does not support live calling here. Code: FEATURE_NOT_CONFIGURED."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "A provider we depend on failed. Code: UPSTREAM_ERROR."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Outbound Call",
        "tags": [
          "public"
        ]
      }
    },
    "/api/v1/public/outbound-calls/batch": {
      "post": {
        "description": "Queue a batch of outbound calls and start dialing.\n\n**Retries never dial twice** (2026-10-15). A retry with the same\n`Idempotency-Key` returns the original batch; the same key with a different\nrequest is refused (`IDEMPOTENCY_KEY_REUSED`). Without a key, the same\nrequest sent again while that batch is still running (a timeout retry, a\ndouble submit) returns the running batch instead of starting a second one.\nOnce it has finished, sending the same request again is a deliberate new\nrun and dials again.",
        "operationId": "public_outbound_batch_api_v1_public_outbound_calls_batch_post",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchCallRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Outbound Batch Api V1 Public Outbound Calls Batch Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Malformed in a way the schema cannot express, such as a number that is not E.164, or no telephony carrier connected. Code: INVALID_REQUEST."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Plan or credits exhausted. Code: PAYMENT_REQUIRED."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource for this organization. Code: RESOURCE_NOT_FOUND."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The assistant exists but is not in a usable state. Code: ASSISTANT_NOT_PUBLISHED. On a single outbound placement it can also mean a request with the same Idempotency-Key is still being placed; retry shortly to get its result. Code: IN_PROGRESS."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Outbound Batch",
        "tags": [
          "public"
        ]
      }
    },
    "/api/v1/public/widget": {
      "get": {
        "description": "The organization's web widget settings and its embed snippet.",
        "operationId": "public_get_widget_api_v1_public_widget_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Get Widget Api V1 Public Widget Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Get Widget",
        "tags": [
          "widget"
        ]
      },
      "patch": {
        "description": "Change the widget's settings. Applies to every embed at once.",
        "operationId": "public_update_widget_api_v1_public_widget_patch",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WidgetSettingsUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Update Widget Api V1 Public Widget Patch",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Update Widget",
        "tags": [
          "widget"
        ]
      }
    },
    "/api/v1/public/widget/sessions": {
      "post": {
        "description": "Mint a widget session token for one visitor, bound to this API key.\n\nCall it from your server when you render a page with the widget, and hand\nthe `token` to the page. Never hand the page the API key.",
        "operationId": "public_create_widget_session_api_v1_public_widget_sessions_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WidgetSessionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Public Create Widget Session Api V1 Public Widget Sessions Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No API key, an invalid one, or one that is expired or revoked. Codes: MISSING_API_KEY, INVALID_API_KEY, EXPIRED_API_KEY, REVOKED_API_KEY."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Authenticated but not permitted. Codes: IP_NOT_ALLOWED, INSUFFICIENT_PERMISSION."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "No such resource for this organization. Code: RESOURCE_NOT_FOUND."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The request body or query failed validation. Code: VALIDATION_ERROR, with `details.fields` naming each field and why."
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Rate limit or call limit exceeded; honor Retry-After. Codes: RATE_LIMIT_EXCEEDED, CALL_LIMIT_REACHED."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "Something failed on our side. Codes: INTERNAL_ERROR, BATCH_CREATION_FAILED."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "description": "The API, or a feature of it, is not available on this deployment (code: NOT_CONFIGURED), or authentication is temporarily unavailable; honor Retry-After (code: SERVICE_UNAVAILABLE)."
          }
        },
        "summary": "Public Create Widget Session",
        "tags": [
          "widget"
        ]
      }
    }
  },
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "servers": [
    {
      "description": "production",
      "url": "https://api-ciao.worksbuddy.ai"
    },
    {
      "description": "demo",
      "url": "https://api-voice-agent.lbmdemo.com"
    }
  ],
  "tags": [
    {
      "description": "Calling and chat operations, plus read-only assistant access.",
      "name": "public"
    },
    {
      "description": "The organization's contact book: contacts, bulk saves into groups (contact lists), and group membership. Needs the contacts:read / contacts:write permissions on the key.",
      "name": "contacts"
    },
    {
      "description": "The web widget: its settings and session tokens for your server (API key), and the embed routes the widget calls from a visitor's browser (session token).",
      "name": "widget"
    }
  ]
}
