{
  "openapi": "3.0.3",
  "info": {
    "title": "Speak AI API",
    "version": "v1",
    "description": "Welcome to the Speak Ai API.\n\n_Documentation is a work in progress and subject to change._\n\n# Requirements\n\nThe Speak Ai API is made available to all paying subscribers. With the API you can programmatically upload your media files for insights extraction, transcription, download the resulting insights and transcript in various formats and create an embed iframe and a page.\n\n# API Key\n\nIf you are subscribed to Speak Ai (paid subscription), you can access your API key in your Speak account and going to the [developer page](https://app.speakai.co/developer).\n\n## Base URL and Versioning\n\nThe base URL for the API is `https://api.speakai.co/[version]`. The current version is **v1**, so the base URL for the current API version is `https://api.speakai.co/v1`.\n\n# Supported Languages\n\nSpeak Ai supports 100+ languages for transcription and analysis.\n\nFor the full list of supported languages, see: [What languages do you support?](https://docs.speakai.co/help/transcription/languages/)\n\n---\n\n# MCP (Model Context Protocol) Integration\n\nSpeak Ai provides an MCP server that enables AI models and agents to interact with the Speak Ai API programmatically.\n\n**GitHub Repository:** [https://github.com/speakai/speakai-mcp](https://github.com/speakai/speakai-mcp)\n\n## MCP Server URL\n\nUse the following Streamable HTTP endpoint to connect to the Speak Ai MCP server:\n\n```\nhttps://api.speakai.co/v1/mcp\n\n ```\n\n## NPX Package\n\nYou can run the Speak Ai MCP server locally using the `speakai-mcp` npm package via npx:\n\n``` bash\nnpx speakai-mcp\n\n ```\n\nOr install it globally:\n\n``` bash\nnpm install -g speakai-mcp\n\n ```\n\n## CLI Usage\n\nAfter installation, you can use the CLI to start the MCP server locally:\n\n``` bash\nspeakai-mcp --api-key YOUR_API_KEY\n\n ```\n\n---\n\n# Security & Privacy\n\nFor information about Speak Ai's security practices and privacy policies, visit our [Security &amp; Privacy documentation](https://docs.speakai.co/help/security/).\n\n---\n\n# Support\n\nIf you have any questions, please write to us at [accounts@speakai.co](mailto:accounts@speakai.co). We'd love to hear from you!\n\n---\n\n# How this specification is maintained\n\nThis specification is hand-maintained in the speak-docs repository at `openapi/speak-api.json`. It is the source of truth for the Speak AI API reference and it is no longer exported from the Speak AI Postman collection.\n\nPaths, parameters, and response shapes are verified against the Speak AI API server source before they are added. To correct the reference, edit this file and re-run `node scripts/generate-api-docs.mjs`.",
    "contact": {
      "name": "Speak AI support",
      "email": "accounts@speakai.co"
    }
  },
  "servers": [
    {
      "url": "https://api.speakai.co/v1",
      "description": "Speak AI API v1"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": [],
      "AccessTokenAuth": []
    }
  ],
  "tags": [
    {
      "name": "Authentication",
      "description": "All Speak AI API operations require two headers:\n\n`x-speakai-key: your_speak_ai_api_key_here`\n\n`x-access-token: generated_access_token`\n\n---\n\n### Authentication Flow\n\n1. **Get Access Token**: Call `POST /v1/auth/accessToken` with your `x-speakai-key` and `Content-Type: application/json` headers. The request body should be `{}` (empty JSON) when using API key authentication.\nOn success, the response returns your `accessToken` and `refreshToken` inside the `data` object.\n\n2. **Use Access Token**: Include the access token in the `x-access-token` header for all subsequent API calls, alongside your `x-speakai-key`.\n\n3. **Refresh Token**: When the access token expires, call `POST /v1/auth/refreshToken` with both `x-speakai-key` and `x-access-token` headers (include the expired access token), and pass `{\"refreshToken\": \"...\"}` in the request body. You will receive a new `accessToken` and `refreshToken` pair.\n\n**Example Response**\n\n```json\n{\n  \"data\": {\n    \"email\": \"you@example.com\",\n    \"accessToken\": \"eyJhbG...\",\n    \"refreshToken\": \"eyJhbG...\"\n  }\n}\n```\n\n---\n\n### Token Expiry\n\n| Token | Expiry | Action on Expiry |\n|---|---|---|\n| Access Token | 80 minutes | Call Refresh Token endpoint |\n| Refresh Token | 24 hours | Re-authenticate via Get Access Token |\n\n---\n\n### Rate Limits\n\nBoth `/v1/auth/accessToken` and `/v1/auth/refreshToken` are limited to **5 requests per 60 seconds**. Exceeding this returns `429 Too Many Requests`.\n\n---\n\n### Error Handling\n\n- **Expired Access Token**: Returns `401 Unauthorized`. Use the Refresh Token endpoint to obtain a new token pair.\n- **Expired Refresh Token**: Returns an error response. Re-authenticate from scratch via the Get Access Token endpoint.\n- **Rate Limited**: Returns `429`. Wait and retry \u2014 implement exponential backoff for automated clients."
    },
    {
      "name": "Media (Audio/Video)",
      "description": "This media collection of endpoints enables operation of list, insights, transcript and export.\n\n## Uploading audio or video\n\nWhen uploading a file, a media file URL (accessible to our servers) must be provided.\n\nThis can be a publicly accessible URL hosted by yourselves or a third-party. \n\nYou can upload files directly to our storage (AWS S3 bucket) and upload the file using the returned URL.\n\n### Step 2, PUT the file to the presigned URL\n\nThis step targets the storage host returned in `preSignedUrl`, not `api.speakai.co`, so it is described here rather than as a Speak AI endpoint.\n\n### PUT Request to Upload Audio File\n\nThis endpoint allows you to upload an audio file (in this case, an MP3 file) to an Amazon S3 bucket. The request is made using the HTTP PUT method, which is commonly used for updating resources.\n\n#### Request URL\n\n```\nhttps://xs3.amazonaws.com/video/1622234682034-medianame.mp3?AWSAccessKeyId=x&Content-Type=audio/mp3&Expires=1622245482&Signature=nQWU4yxBuUjQJD1yTr92qblQx6s=&x-amz-acl=public-read\n\n ```\n\n#### Query Parameters\n\n- `AWSAccessKeyId`: Your AWS access key ID, used for authentication.\n    \n- `Content-Type`: Specifies the media type of the resource being uploaded (in this case, `audio/mp3`).\n    \n- `Expires`: A timestamp indicating when the URL will expire.\n    \n- `Signature`: A signature for authentication, ensuring the request is valid.\n    \n- `x-amz-acl`: Sets the access control list (ACL) for the uploaded file. Here, it is set to `public-read`, allowing public access to the file.\n    \n\n#### Request Body\n\nThe request does not specify a body type, indicating that the audio file is uploaded directly to the specified URL.\n\n#### Expected Response\n\nThe response from a successful upload typically includes:\n\n- A confirmation of the upload status (e.g., HTTP status code 200 OK).\n    \n- Metadata about the uploaded file, such as its URL and size.\n    \n\nEnsure that the audio file being uploaded adheres to the specified content type and that all required parameters are included in the request."
    },
    {
      "name": "Text",
      "description": "Text notes are operable as well, complete listing of media can be requested, insight to particular analyzed media, analytics on top of our analysis, and of course, you can delete your note !\n\nAttention:\n`id` is the required parameter here instead of `mediaId` as in Media functionalities\n\nRe-analyzing a text note runs through `GET /media/reanalyze/{mediaId}`, which covers text notes and uploaded files alike. It is documented on the [Media](/api/media/) page."
    },
    {
      "name": "Exports",
      "description": "Export collection enables export of media (audio, video + text) details: transcript, analytics and insights."
    },
    {
      "name": "Folder",
      "description": "Manage Folder workflow. Create, Update, Delete folders."
    },
    {
      "name": "Recorder/Survey",
      "description": "Suvery endpoints serve the purpose of operating an surveys: listing the files, getting info, creating\\\\updating\\\\deleting a recorder, generating embeddable URL for it.\n\nEmbeddable supports checking it's status,uploading of the recordings directly and verification of password to access the recorder as a user."
    },
    {
      "name": "Media Embed",
      "description": "Embed Individual Media Player or the Folder (as repository) to make the insights, transcription and insights publicly visible or share with others."
    },
    {
      "name": "AI Chat",
      "description": "Fetch all your Speak AI Chat Responses."
    },
    {
      "name": "Meeting Assistant Events",
      "description": "Manage Meeting Assistant Events.\n\nFetch all your scheduled, complete or pending meeting assistant events."
    },
    {
      "name": "Fields",
      "description": "Manage Fields."
    },
    {
      "name": "Labels",
      "description": "Labels mark passages of a transcript, such as an objection on a sales call or a quote for a report. Your company keeps one list of labels, with one level of groups, and anyone with the **Labels: Assign** permission can put them on any transcript they can open.\n\n### Permissions\n\nAdmins set these per person in Team management. Owners pass every check. Reading labels needs no permission.\n\n| Permission | Allows | Admin default | Member default |\n| --- | --- | --- | --- |\n| Labels: Create | Create labels and groups, add Speak label sets | Yes | Yes |\n| Labels: Update | Rename, recolour, describe, regroup, reorder; merge with Delete | Yes | Yes |\n| Labels: Delete | Archive and restore; merge with Update | Yes | No |\n| Labels: Assign | Apply, change and remove labels on transcripts | Yes | Yes |\n\nA missing permission returns `403` with `{\"status\": \"failed\", \"message\": \"You do not have permission to perform this action\"}`.\n\n### Transcript revisions\n\nEvery saved change to a transcript increases the media's `transcriptRevision`. Passages are addressed by word position on a given revision, so labelling and commenting send `expectedTranscriptRevision` and get 409 when it is stale. When a transcript is edited, labelled passages move with their words; a passage whose words changed too much is marked `needs_review` with a suggested new position, and nothing is deleted.\n\n### Notifications\n\nEvery label change, in the library or on a transcript, is listed for the person who made it under the `label` category of [GET /v1/notification](/api/notifications/)."
    },
    {
      "name": "Comments",
      "description": "Comment threads on a passage of a transcript or on the whole file, with one level of replies, resolve and reopen. Comments on passages follow their words when the transcript is edited, the same way labels do.\n\n### Permissions\n\nAdmins set these per person in Team management. Owners pass every check. Reading comments needs no permission, and you can always edit and delete your own comments.\n\n| Permission | Allows | Admin default | Member default |\n| --- | --- | --- | --- |\n| Comments: Create | Start a thread and reply | Yes | Yes |\n| Comments: Update | Resolve and reopen threads | Yes | Yes |\n| Comments: Delete | Delete other people's comments | Yes | No |\n\n### Notifications\n\nEvery comment change is listed for the person who made it under the `comment` category of [GET /v1/notification](/api/notifications/). The person who started a thread is also told when someone else replies to it, resolves it or reopens it."
    },
    {
      "name": "Notifications",
      "description": "The in-app notifications the Speak app lists under **Notifications**: uploads and analysis, payments, team changes, and label and comment activity. Read them a page at a time with filters, and mark your own as read."
    },
    {
      "name": "Dashboards",
      "description": "Create and update analytics dashboards, including the viewer settings that decide what a dashboard's share link shows: custom fields, the Feedback button, labels, comments, and, through the feedback submitter names, who a viewer may write as.\n\n### Labels and comments on a share link\n\n| Setting | Shape | Rule |\n| --- | --- | --- |\n| `labels` | `{ isEnabled, mode: \"view\" \\| \"apply\", labelGroupIds }` | `labelGroupIds` (at most 100) must be active label groups of your company (400 on save). Empty means every active label. |\n| `comments` | `{ isEnabled, mode: \"view\" \\| \"reply\" }` | |\n\nEach section replaces itself when sent and keeps its stored value when left out. Everything is off and read-only until you turn it on. Viewers use the [shared link](/api/shared-links/) routes."
    },
    {
      "name": "Shared Links",
      "description": "The routes a dashboard's share link uses to read and write labels and comments on its media, and that a media or folder embed uses to read them. There is no signed-in user: the link token in `?token=` is the only credential, so these routes take no API key or access token.\n\n### Embeds\n\nMedia and folder embeds have `meta.isLabels` and `meta.isComments`, both off by default and set with `PUT /embed/{embedId}`. Embeds are read-only: the two GET routes answer an embed token only while its flag is on, for the embed's own media or media in its folders, and every write route refuses an embed token.\n\n### Refusals\n\nEvery refusal (unknown or revoked token, expired subscription, the setting off, view mode on a write, media outside the dashboard's folders, a name that is not allowed, someone else's entry) returns the same `404 {\"message\": \"Not found.\"}`, so a link holder cannot tell which check failed. Validation errors still return 400 and a stale transcript revision 409. Reads allow 120 requests a minute per IP address and writes 30; past that the routes return 429.\n\n### Writing as a reviewer\n\nWrites need `labels.mode` set to `apply` or `comments.mode` set to `reply` on the dashboard, and send a `reviewerName` from `annotationSettings.reviewers`, the dashboard's feedback submitter names. When `allowOtherReviewer` is true (the dashboard's `feedback.allowOtherSubmitter` is on), a name that is not listed is also accepted. With no names listed and other names off, nobody can write. Link writes are not authenticated: the link holder chooses the name, and Speak AI records the entry under it without checking who sent it, the same as feedback. Only the dashboard's feedback names are accepted, plus any other name when other names are allowed. Speak AI accepts this by design. Every entry is shown as made via the dashboard under the chosen name, a name can change or delete only the entries written under it from that dashboard, and revoking the link stops everything at once. Link responses carry the author's display name only. Linking a comment to a passage, moving passages and resolving threads stay in the app."
    },
    {
      "name": "Automations",
      "description": "Best way to automate your workflow with Automations."
    },
    {
      "name": "Admin",
      "description": "Manage your team."
    },
    {
      "name": "Webhook",
      "description": "Receive Webhooks from Speak to your platform. Manage webhook workflows and select events."
    },
    {
      "name": "Live Transcription",
      "description": "Live transcription turns a running audio or video session into a transcript while the session is still going. The three REST endpoints below open the session, feed it, and close it.\n\nA session runs in three steps. Create the media record with `POST /live-transcription/create`, mint a handshake token with `POST /live-transcription/token`, then send transcribed words to `POST /live-transcription/update/{mediaId}` as they arrive.\n\nWhen the session ends, send the finished recording to the same update endpoint. Speak Ai transcodes it and runs the full analysis, so a live session ends up with the same transcript, speakers, and insights as an uploaded file.\n\nThe audio itself streams over a separate WebSocket connection that the handshake token authorizes. That connection is not part of the REST API and its host is not documented here.\n\n### Supported languages\n\nPass one of these codes as `sourceLanguage` when you create the session.\n\n| value | name |\n| --- | --- |\n| en-US | English (US) |\n| en-AU | English (Australia) |\n| en-GB | English (British) |\n| en-IN | English (Indian) |\n| en-IE | English (Irish) |\n| en-NZ | English (New Zealand) |\n| en-AB | English (Scottish) |\n| en-ZA | English (South African) |\n| en-ES | English + Spanish (Multiple) |\n| fr-FR | French |\n| fr-CA | French (Canada) |\n| es-ES | Spanish |\n| es-MX | Spanish (Mexico) |\n| bg-BG | Bulgarian |\n| ca-ES | Catalan |\n| zh-CN | Chinese (Simplified) |\n| zh-TW | Chinese (Traditional) |\n| zh-HK | Chinese (Cantonese, Traditional) |\n| cs-CZ | Czech |\n| da-DK | Danish |\n| nl-NL | Dutch |\n| et-EE | Estonian |\n| nl-BE | Flemish |\n| fi-FI | Finnish |\n| de-CH | German (Swiss) |\n| de-DE | German |\n| el-GR | Greek |\n| hi-IN | Hindi |\n| hi-Latn | Hindi (Latin) |\n| hu-HU | Hungarian |\n| id-ID | Indonesian |\n| it-IT | Italian |\n| ja-JP | Japanese |\n| ko-KR | Korean |\n| lt-LT | Lithuanian |\n| lv-LV | Latvian |\n| ms-MY | Malay |\n| nb-NO | Norwegian |\n| pl-PL | Polish |\n| pt-BR | Portuguese (Brazilian) |\n| pt-PT | Portuguese (Portugal) |\n| ro-RO | Romanian |\n| ru-RU | Russian |\n| sk-SK | Slovak |\n| sv-SE | Swedish |\n| taq | Tamasheq |\n| th-TH | Thai |\n| tr-TR | Turkish |\n| uk-UA | Ukrainian |\n| vi-VN | Vietnamese |"
    },
    {
      "name": "Voice Agents",
      "description": "Create and manage voice agents. Mutations (create/update/delete) require the OWNER or ADMIN role."
    },
    {
      "name": "Voice Agent Avatars",
      "description": "The avatar catalog voice agents attach for video calls: the shared system catalog plus your company's own uploads. Mutations require the OWNER or ADMIN role and only ever apply to your company's own uploads, never the shared catalog."
    },
    {
      "name": "Voice Agent Testing",
      "description": "Scripted test scenarios and run history for a voice agent. The run lifecycle (queue/pause/resume/cancel) is live; the execution engine that actually drives a simulated conversation is not wired up yet, so a run stays queued until that lands."
    }
  ],
  "paths": {
    "/auth/accessToken": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Get Access Token",
        "operationId": "authentication-get-access-token",
        "description": "This endpoint allows you to obtain an access token by providing the necessary authentication credentials.\n\nThe request body for this endpoint should include the your authentication credentials. Upon successful authentication, the server will respond with a status of \"success\" and provide the your email, access token, and refresh token in the response data.\n\n**Request rules.** The request body is entirely optional: you can post an empty JSON object. Authentication comes from your API key in the x-speakai-key request header, not from the body, and a missing or invalid key returns 401. A deactivated account returns 200 with a deactivated status rather than tokens. This endpoint is rate limited to 5 requests per minute per IP address.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "deviceType": {
                    "type": "string",
                    "description": "Labels the kind of client requesting the token so the resulting session is identified correctly in your login history. Leave it out and the session is labeled as an API session. Send zapier when you want a plain token pair with no session recorded; in that case the refresh token you get back cannot be exchanged later, so request a new access token instead of refreshing. Any value outside the accepted list is rejected when the session is saved, and you still get a working access token but no session record and no usable refresh token. Optional string. Defaults to api when you omit it or send an empty value. Only web, android, ios, zapier, api and desktop are stored successfully.",
                    "enum": [
                      "web",
                      "android",
                      "ios",
                      "zapier",
                      "api",
                      "desktop"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "email": {
                          "type": "string"
                        },
                        "accessToken": {
                          "type": "string"
                        },
                        "refreshToken": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "get-access-token": {
                    "summary": "Get Access Token",
                    "value": {
                      "status": "success",
                      "data": {
                        "email": "your_email_id",
                        "accessToken": "access_token",
                        "refreshToken": "refresh_token"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "get-access-token-failure-no-value-found-for-speak-ai-key": {
                    "summary": "Get Access Token - Failure (No value found for Speak Ai Key)",
                    "value": {
                      "status": "failed",
                      "requestId": "ca665625-645e-438a-867d-366a6e3f133a",
                      "code": 401,
                      "message": "The authorization api key provided for the request is invalid.",
                      "hints": [
                        "The authorization api key provided for the request is invalid."
                      ]
                    }
                  },
                  "get-access-token-failure-invalid-api-key": {
                    "summary": "Get Access Token - Failure - Invalid API Key",
                    "value": {
                      "status": "failed",
                      "requestId": "358bc130-e798-41c2-9864-2cd2ce9b766d",
                      "code": 401,
                      "message": "The authorization api key provided for the request is invalid.",
                      "hints": [
                        "The authorization api key provided for the request is invalid."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/auth/refreshToken": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Refresh Token",
        "operationId": "authentication-refresh-token",
        "description": "This endpoint is used to refresh the access token by providing the refresh token in the request body.\n\nThe refreshToken expires in 24 hour.\n\n### Request Body\n\n- refreshToken (string, required): The refresh token used to obtain a new access token.\n\n\n### Response\n\n- status (string): Indicates the status of the request, where \"success\" means the request was successful.\n- data (object): Contains the new access token and refresh token.\n - accessToken (string): The new access token.\n - refreshToken (string): The new refresh token.\n\n**Request rules.** You must send refreshToken in the body unless the request already carries Speak's refresh token session cookie, which only browser clients signed in through Speak's own web apps have. The server reads the body value first and falls back to that cookie, so an API integration that omits the field always gets a 404. This endpoint is rate limited to 5 requests per minute per IP address.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "refreshToken": {
                    "type": "string",
                    "description": "The refresh token you received the last time you signed in or requested a token. Send it here to get back a new access token and a new refresh token. Refresh tokens are single use: once you exchange one, the old value stops working, so store the new one from the response and use that next time. Replaying an already used refresh token ends the whole session and forces a fresh sign in. A missing token, or one that does not match an active session, returns 404. A token that is expired, tampered with, or otherwise not valid returns 401. Must be a string. An empty value or a value that is not a string is treated as missing and returns 404. Sending a non-string value also cancels the cookie fallback, so send either a real token string or no field at all. Required for API callers, since the only alternative the server accepts is a browser session cookie."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "accessToken": {
                          "type": "string"
                        },
                        "refreshToken": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "refresh-token": {
                    "summary": "Refresh Token",
                    "value": {
                      "status": "success",
                      "data": {
                        "accessToken": "new_access_token",
                        "refreshToken": "new_refresh_token"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "refresh-token-failure-invalid-expired-token": {
                    "summary": "Refresh Token - Failure - Invalid / Expired Token",
                    "value": {
                      "status": "failed",
                      "requestId": "3fcf7e0c-a977-4c37-bae5-a72485206cd0",
                      "code": 404,
                      "message": "We were unable to find a valid token. Your token may have expired or invalid. Please contact development team."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/media/upload/signedurl": {
      "get": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "Get a Signed Url",
        "operationId": "media-audio-video-get-a-signed-url",
        "description": "If you have a locally saved file and you want to upload it to our system using API, you'll have to follow through 3 simple steps:\n\n### Process\n\n1. Run this endpoint to retrieve an upload link for a placeholder on our storage bucket. You'll have `preSignedUrl.`\n\n2. This `preSignedUrl` is your ticket to which you `PUT` your local file using `curl` or any other HTTP client.\n\n3. Use \"[Upload your file with the Signed Url or External URL](https://docs.speakai.co/#c6106a66-6a3d-4b05-b4a2-4a68a4c1e95d)\" to upload your file on Speak.\n\n### How does this work?\n\nYou can find more information about uploading a file using signed URLs [here](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html).\nIf you still find this unenlightening, shoot a message to us on success@speakai.co!\n\n### Expiry\n\nThe link will expire in 2 hours.",
        "x-speak-group": "Audio or Video Upload",
        "parameters": [
          {
            "name": "mediaType",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "audio",
                "video"
              ]
            },
            "description": "The kind of file you are uploading. It decides the storage prefix, so it has to match the real file: a video signed as audio is stored as audio and can never be analysed as video. Required. The prefix is chosen before any bytes exist, so the server cannot work it out for you: omit it and the request is rejected. Nothing is read from the extension on filename.",
            "example": "audio"
          },
          {
            "name": "filename",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Filename with the extension is required",
            "example": "media_name.mp3"
          },
          {
            "name": "mimeType",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "For example audio/mpeg, audio/mp4, audio/wav or video/mp4",
            "example": "audio/mpeg"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "get-a-signed-url-audio": {
                    "summary": "Get a Signed Url (Audio)",
                    "value": ""
                  },
                  "get-a-signed-url-video": {
                    "summary": "Get a Signed Url (Video)",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/media/upload": {
      "post": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "Upload your file with the Signed Url or External URL",
        "operationId": "media-audio-video-upload-your-file-with-the-signed-url-or-external-url",
        "description": "If you want to add a hosted media (you must have a valid `URL`) to your media library, do it here.\n\n### Parameters\n\nPlease must specify `mediaType` as `audio` or `video`\n\n```\nname: String required\ndescription: string;\nurl: string required; // public URL or AWS signed URL\nmediaType: 'audio'; // 'video'\nuserId: \"\"; // for enterprise users only (optional)\nmedicalId: \"\" // custom media Id or medical Id for your reference (optional)\ncreatedAt: \"2021-08-09T00:13:11.717Z\" // must match the date format (optional)\ntags: \"comma separated strings\",\nfolderId: \"folder Id\" // to save in the folder\nfields: { id: string, value: string } = []; (Optional)\n\n ```\n\n### Webhook Callback URL:\n\n- If you created a webhook for media events and want to receive a callback to a specific URL for this text note, you can assign `callbackUrl` - `string` in a `req.body`.\n\n- Speak will consider the `callbackUrl` and will skip the callbackUrl created via [Webhook API](https://docs.speakai.co/#5777a89c-a6c3-4d0e-aab1-d33fdec5cbe8).\n\n\n**Fields:**\n\nYou can pass the **id and value** in the Fields array to include related to your media files.\n\n**Upload Considerations:**\n\n- Maximum duration limit of 3 hours for a media URL.\n\n- The URL needs to be accessible publicly. For Example - Google Drive, Dropbox are not supported.\n\n- Valid YouTube URL examples are: `https://www.youtube.com/watch?v=pTJ-yvNWCUE`.\n\n- **Supported File Formats are**:\n\n - Audio - `mp3 (recommended), m4a, wav, ogg, webm, m4p`\n\n - Video - `mp4 (recommended), m4v, wmv, avi, mov, flv`",
        "x-speak-group": "Audio or Video Upload",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "The title you want the uploaded file to have in Speak. Required. Trimmed. No maximum length and no pattern."
                  },
                  "description": {
                    "type": "string",
                    "description": "A short description stored alongside the file. Optional. Trimmed. An empty string is allowed. The schema declares a default of an empty string, but the validation middleware discards the schema defaults, so an omitted value simply stays unset."
                  },
                  "url": {
                    "type": "string",
                    "description": "The link Speak fetches the file from. YouTube, Google Drive, Amazon S3 and the social platforms the resolver supports (TikTok, Instagram, X, Facebook, Reddit, SoundCloud, Twitch, Dailymotion, Streamable, Snapchat, Pinterest, Tumblr, Bilibili, VK, OK.ru and Rutube) are all handled. Vimeo and Loom page links are not resolved here: import Vimeo through the connected Vimeo integration instead. Required. Plain string with no uri format check, so the server does not reject a malformed link at validation time."
                  },
                  "mediaType": {
                    "type": "string",
                    "description": "The kind of file you are uploading, and the field that decides how it is stored and what can be run on it later. Send it whenever you know which you want, including for a page link: asking for audio on a YouTube link imports the audio track only. Leave it out when you do not know, and the server works it out from better evidence than you have: it inspects the file for a direct URL, and for a page link the resolver returns the best track the platform offers, which can still be audio when no video rendition fits the size limit. Either way the stored type follows what was actually fetched. It has no default, so leaving it out is a real choice rather than a value invented on your behalf, and the only fallback is audio when nothing else can be determined. Do not send a value guessed from the file extension. A value you send is kept, which means it stops the server inspecting the file, and a video stored as audio can never be analysed as video afterwards. Lowercased before validation, so uppercase values such as VIDEO are accepted. 'all' is a filter value that leaked into this schema: it validates but is not a real upload type.",
                    "enum": [
                      "audio",
                      "video",
                      "text",
                      "media",
                      "csv",
                      "all"
                    ]
                  },
                  "sourceLanguage": {
                    "type": "string",
                    "description": "The language spoken in the file, given as a transcription language code such as en-US. Optional. Any string passes, because the validator substitutes rather than rejects. An unrecognized code becomes auto. The schema declares a default of 'en-US', but that default is discarded by the middleware, so if you omit it the server uses the source language on your account onboarding and falls back to auto. Defined."
                  },
                  "callbackUrl": {
                    "type": "string",
                    "description": "A URL you want Speak to call when the file finishes processing. Optional. Trimmed. An empty string is allowed. Stored on the media as webhookMetaData.callbackUrl. No uri format check."
                  },
                  "tags": {
                    "type": "string",
                    "description": "Tags to attach to the file, as a single comma separated string. Optional. Declared as a union, the schema) and allows null and an empty string, so an array also passes validation. The controller only reads a string and splits it on commas, so an array is accepted and then ignored."
                  },
                  "createdAt": {
                    "type": "string",
                    "description": "The creation timestamp to store on the file instead of the time of upload. Optional. An empty string is allowed. Parsed with new Date, so send an ISO 8601 string."
                  },
                  "isTranscriptionOnly": {
                    "type": "boolean",
                    "description": "Not used by this endpoint. Nothing in the upload flow reads it. Optional. Declared with a default of false, but that default is discarded and the value is never destructured or read by the controller.",
                    "deprecated": true
                  },
                  "folderId": {
                    "type": "string",
                    "description": "The folder you want the file to land in. If no folder with that id exists on your account, the server puts the file in your first folder. Optional. An empty string is allowed."
                  },
                  "fields": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    },
                    "description": "Custom field values to attach to the file. Each entry pairs the id of a field you created in Speak with the value you want stored. Optional. An unconstrained array, so validation does not check the item shape and does not cap the length. The controller expects objects with id and value, checks each id against your account fields, and silently drops the ones that do not match (checkForValidFields ends with.filter(Boolean))."
                  }
                },
                "required": [
                  "name",
                  "url"
                ]
              },
              "example": {
                "name": "Vatsal Test 1",
                "description": "Vatsal Description",
                "url": "https://kns.im/msgs/files/32dc84df-9650-4c17-b633-e80a5097ba6f.ogg",
                "mediaType": "video",
                "sourceLanguage": "he-IL",
                "tags": "your custom tags1, tag 2, tag 3",
                "fields": [
                  {
                    "id": "FIELD_ID_CREATED_BY_SPEAK",
                    "value": "YOUR_VALUE"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "mediaId": {
                          "type": "string"
                        },
                        "state": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "success",
                    "value": {
                      "status": "success",
                      "data": {
                        "mediaId": "86a36b59b38e",
                        "state": "uploaded"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/media": {
      "get": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "List",
        "operationId": "media-audio-video-list",
        "description": "If you are looking for a paginated, sorted and filtered listing of your media library.\n\n- You can pass `userId` in `params` to get data for a user. (Only for enterprise use cases)",
        "parameters": [
          {
            "name": "mediaType",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "audio, video, text",
            "example": "audio"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Default `1`st page",
            "example": "1"
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Default `50`",
            "example": "50"
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Default Created At in Descending order\n\nSort by: Created At, positive, neutral, negative\n\n`asc` or `desc`",
            "example": "createdAt:desc"
          },
          {
            "name": "filterMedia",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "0 -- Uploaded\n1 -- Assigned Media to a User\n2 -- Uploaded OR Assigned\n\nDefault: `0`",
            "example": "0"
          },
          {
            "name": "filterName",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Search from media name, keywords, labels, faces, brands, people, locations and transcription."
          },
          {
            "name": "folderId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Pass folderId to fetch only those records",
            "example": "568sd56899"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "totalCount": {
                          "type": "integer"
                        },
                        "pages": {
                          "type": "integer"
                        },
                        "mediaList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "duration": {
                                "type": "object",
                                "properties": {
                                  "inSecond": {
                                    "type": "string"
                                  },
                                  "start": {
                                    "type": "string"
                                  },
                                  "end": {
                                    "type": "string"
                                  }
                                }
                              },
                              "privacyMode": {
                                "type": "string"
                              },
                              "processingProgress": {
                                "type": "string"
                              },
                              "state": {
                                "type": "string"
                              },
                              "remark": {
                                "type": "string"
                              },
                              "_id": {
                                "type": "string"
                              },
                              "sentiment": {
                                "type": "array",
                                "items": {}
                              },
                              "mediaId": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "description": {
                                "type": "string"
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "thumbnailUrl": {
                                "type": "string",
                                "description": "A signed link to the video's thumbnail, custom or automatic. Present only when the file has one. It expires, so do not store it."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "success",
                    "value": {
                      "status": "success",
                      "data": {
                        "totalCount": 71,
                        "pages": 71,
                        "mediaList": [
                          {
                            "duration": {
                              "inSecond": "60",
                              "start": "0:00:00",
                              "end": "0:01:00.182"
                            },
                            "privacyMode": "Public",
                            "processingProgress": "100",
                            "state": "processed",
                            "remark": "",
                            "_id": "5f46c87668ee9913005e5bef",
                            "sentiment": [],
                            "mediaId": "50ek03r4kebud105",
                            "name": "vatsal-30",
                            "description": "url-test",
                            "createdAt": "2020-08-26T20:39:18.870Z"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/media/insight/{mediaId}": {
      "get": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "Insights",
        "operationId": "media-audio-video-insights",
        "description": "Load the results of analysis (sentiment, transcription, named entities, etc) for your media object here.\n\n- You can pass `userId` in `params` to get specifically for any user.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "5a4690abf255"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "insight": {
                          "type": "object",
                          "properties": {
                            "isAnalyze": {
                              "type": "boolean"
                            },
                            "transcript": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "integer"
                                  },
                                  "text": {
                                    "type": "string"
                                  },
                                  "confidence": {
                                    "type": "number"
                                  },
                                  "speakerId": {
                                    "type": "integer"
                                  },
                                  "language": {
                                    "type": "string"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "adjustedStart": {
                                          "type": "string"
                                        },
                                        "adjustedEnd": {
                                          "type": "string"
                                        },
                                        "start": {
                                          "type": "string"
                                        },
                                        "end": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "faces": {
                              "type": "array",
                              "items": {}
                            },
                            "keywords": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "adjustedStart": {
                                          "type": "string"
                                        },
                                        "adjustedEnd": {
                                          "type": "string"
                                        },
                                        "start": {
                                          "type": "string"
                                        },
                                        "end": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  },
                                  "id": {
                                    "type": "integer"
                                  },
                                  "name": {
                                    "type": "string"
                                  }
                                }
                              }
                            },
                            "labels": {
                              "type": "array",
                              "items": {}
                            },
                            "brands": {
                              "type": "array",
                              "items": {}
                            },
                            "topics": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "adjustedStart": {
                                          "type": "string"
                                        },
                                        "adjustedEnd": {
                                          "type": "string"
                                        },
                                        "start": {
                                          "type": "string"
                                        },
                                        "end": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  },
                                  "id": {
                                    "type": "integer"
                                  },
                                  "name": {
                                    "type": "string"
                                  }
                                }
                              }
                            },
                            "people": {
                              "type": "array",
                              "items": {}
                            },
                            "locations": {
                              "type": "array",
                              "items": {}
                            },
                            "arts": {
                              "type": "array",
                              "items": {}
                            },
                            "dates": {
                              "type": "array",
                              "items": {}
                            },
                            "events": {
                              "type": "array",
                              "items": {}
                            },
                            "geopolitical": {
                              "type": "array",
                              "items": {}
                            },
                            "languages": {
                              "type": "array",
                              "items": {}
                            },
                            "laws": {
                              "type": "array",
                              "items": {}
                            },
                            "money": {
                              "type": "array",
                              "items": {}
                            },
                            "ordinals": {
                              "type": "array",
                              "items": {}
                            },
                            "percentages": {
                              "type": "array",
                              "items": {}
                            },
                            "quantities": {
                              "type": "array",
                              "items": {}
                            },
                            "times": {
                              "type": "array",
                              "items": {}
                            },
                            "cardinals": {
                              "type": "array",
                              "items": {}
                            },
                            "nationalities": {
                              "type": "array",
                              "items": {}
                            },
                            "products": {
                              "type": "array",
                              "items": {}
                            }
                          }
                        },
                        "duration": {
                          "type": "object",
                          "properties": {
                            "inSecond": {
                              "type": "string"
                            },
                            "end": {
                              "type": "string"
                            },
                            "start": {
                              "type": "string"
                            }
                          }
                        },
                        "summary": {
                          "type": "object",
                          "properties": {
                            "original": {
                              "type": "object",
                              "properties": {
                                "text": {
                                  "type": "string"
                                },
                                "createdAt": {
                                  "type": "string",
                                  "format": "date-time"
                                }
                              }
                            }
                          }
                        },
                        "tags": {
                          "type": "array",
                          "items": {}
                        },
                        "translationSource": {
                          "type": "object",
                          "description": "Present only on a file Speak AI created by translating another one. It says whether the original source-language transcript can be read, so a client can offer the control without fetching the transcript. Fetch the transcript itself from GET /media/transcript/{mediaId}/source, which documents every reason value.",
                          "properties": {
                            "available": {
                              "type": "boolean"
                            },
                            "reason": {
                              "type": "string",
                              "description": "Why the original cannot be read. Present only when available is false."
                            },
                            "sourceMediaId": {
                              "type": "string"
                            },
                            "sourceLanguage": {
                              "type": "string"
                            },
                            "mediaType": {
                              "type": "string"
                            }
                          }
                        },
                        "isTranscriptionOnly": {
                          "type": "boolean"
                        },
                        "processingProgress": {
                          "type": "string"
                        },
                        "state": {
                          "type": "string"
                        },
                        "remark": {
                          "type": "string"
                        },
                        "sentiment": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "document": {
                                "type": "object",
                                "properties": {
                                  "Negative": {
                                    "type": "integer"
                                  },
                                  "Neutral": {
                                    "type": "integer"
                                  },
                                  "Positive": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "sentences": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "type": "integer"
                                    },
                                    "instances": {
                                      "type": "array",
                                      "items": {}
                                    },
                                    "score": {
                                      "type": "object",
                                      "properties": {
                                        "compound": {
                                          "type": "integer"
                                        },
                                        "neg": {
                                          "type": "integer"
                                        },
                                        "neu": {
                                          "type": "integer"
                                        },
                                        "pos": {
                                          "type": "integer"
                                        }
                                      }
                                    },
                                    "text": {
                                      "type": "string"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "name": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        },
                        "publishedUrl": {
                          "type": "string"
                        },
                        "mediaId": {
                          "type": "string"
                        },
                        "originalCreatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "faceSpriteImg": {
                          "type": "string"
                        },
                        "transcriptRevision": {
                          "type": "integer",
                          "description": "Revision of the transcript. Starts at 0 and increases by one on every saved change to the transcript. Send it back as `expectedTranscriptRevision` when you save the transcript, label a passage or comment on one."
                        },
                        "thumbnail": {
                          "type": "object",
                          "description": "The video's thumbnail. An empty object when the file has none, which includes every audio file and text note. Use it to follow a frame asked for with PUT /media/{mediaId}/thumbnail: pending is true while the frame is being made, and error is set when it failed, while url still shows the previous thumbnail.",
                          "properties": {
                            "url": {
                              "type": "string",
                              "description": "A signed link to the current thumbnail. Present only when the file has one. It expires, so do not store it."
                            },
                            "source": {
                              "type": "string",
                              "enum": [
                                "auto",
                                "custom"
                              ],
                              "description": "`auto` for the thumbnail Speak AI made, `custom` for one you set. Present only when the file has a thumbnail."
                            },
                            "pending": {
                              "type": "boolean",
                              "description": "Present and true while a requested frame is still being made."
                            },
                            "error": {
                              "type": "string",
                              "description": "Why the last requested frame was not saved, for example \"The frame took too long. Try again.\" Present only when it failed."
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "success",
                    "value": {
                      "status": "success",
                      "data": {
                        "insight": {
                          "isAnalyze": true,
                          "transcript": [
                            {
                              "id": 1,
                              "text": "Both. Hello hello good how are you?",
                              "confidence": 0.8278,
                              "speakerId": 1,
                              "language": "en-US",
                              "instances": [
                                {
                                  "adjustedStart": "0:00:00",
                                  "adjustedEnd": "0:00:05.92",
                                  "start": "0:00:00",
                                  "end": "0:00:05.92"
                                }
                              ]
                            }
                          ],
                          "faces": [],
                          "keywords": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "adjustedStart": "0:00:08.44",
                                  "adjustedEnd": "0:00:13.84",
                                  "start": "0:00:08.44",
                                  "end": "0:00:13.84"
                                }
                              ],
                              "id": 1,
                              "name": "company"
                            }
                          ],
                          "labels": [],
                          "brands": [],
                          "topics": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "adjustedStart": "0:00:00",
                                  "adjustedEnd": "0:00:47.744",
                                  "start": "0:00:00",
                                  "end": "0:00:47.744"
                                }
                              ],
                              "id": 1,
                              "name": "Promotions"
                            }
                          ],
                          "people": [],
                          "locations": [],
                          "arts": [],
                          "dates": [],
                          "events": [],
                          "geopolitical": [],
                          "languages": [],
                          "laws": [],
                          "money": [],
                          "ordinals": [],
                          "percentages": [],
                          "quantities": [],
                          "times": [],
                          "cardinals": [],
                          "nationalities": [],
                          "products": []
                        },
                        "duration": {
                          "inSecond": "47",
                          "end": "0:00:47.744",
                          "start": "0:00:00"
                        },
                        "summary": {
                          "original": {
                            "text": "",
                            "createdAt": "2020-09-04T16:16:19.118Z"
                          }
                        },
                        "tags": [],
                        "isTranscriptionOnly": false,
                        "processingProgress": "100",
                        "state": "processed",
                        "remark": "",
                        "sentiment": [
                          {
                            "document": {
                              "Negative": 0,
                              "Neutral": 0,
                              "Positive": 0
                            },
                            "sentences": [
                              {
                                "id": 1,
                                "instances": [],
                                "score": {
                                  "compound": 0,
                                  "neg": 0,
                                  "neu": 1,
                                  "pos": 0
                                },
                                "text": "Sentence 1"
                              }
                            ]
                          }
                        ],
                        "createdAt": "2020-08-22T23:05:57.000Z",
                        "updatedAt": "2020-08-22T23:11:11.288Z",
                        "name": "REc557e3c8f2ac42a828973c39f1d6be37",
                        "description": "",
                        "publishedUrl": "media/5d03a9d5d4bca272e9c8cf89/audio/1598137553998-rec557e3c8f2ac42a828973c39f1d6be37.mp3",
                        "mediaId": "81c226f66705",
                        "originalCreatedAt": "2020-11-08T16:40:10.706Z",
                        "faceSpriteImg": "",
                        "transcriptRevision": 3
                      }
                    },
                    "x-abridged": true
                  },
                  "insights-notuploaded": {
                    "summary": "Insights - notUploaded",
                    "value": {
                      "status": 200,
                      "state": "notUploaded",
                      "message": {
                        "insight": {
                          "isAnalyze": false,
                          "faces": [],
                          "keywords": [],
                          "sentiments": [],
                          "emotions": [],
                          "labels": [],
                          "brands": [],
                          "topics": [],
                          "transcript": [],
                          "speakers": []
                        },
                        "duration": {
                          "inSecond": "0"
                        },
                        "createdAt": "2019-09-25T14:32:19.000Z",
                        "_id": "5d8b7a730838363d90a17e86",
                        "videoId": "QHw2hPhk9-R7rrlPKBZk-FBY9P8rDBV",
                        "name": "ForBiggerBlazes - Copy",
                        "description": "",
                        "privacyMode": "Public",
                        "size": "0",
                        "processingProgress": "0",
                        "state": "notUploaded",
                        "publishedUrl": "video/5cc37a170eb2173efcfc1f7d/1569421938203-ForBiggerBlazesCopymp4.mp4",
                        "videoFormat": 1,
                        "sourceLanguage": "en-US",
                        "order": 0,
                        "__v": 0
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/media/transcript/{mediaId}": {
      "get": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "Transcript",
        "operationId": "media-audio-video-transcript",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "b4994aa1267c"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "folderId": {
                          "type": "string"
                        },
                        "mediaType": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "sourceLanguage": {
                          "type": "string"
                        },
                        "insight": {
                          "type": "object",
                          "properties": {
                            "transcript": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "integer"
                                  },
                                  "text": {
                                    "type": "string"
                                  },
                                  "speakerId": {
                                    "type": "string"
                                  },
                                  "confidence": {
                                    "type": "integer"
                                  },
                                  "language": {
                                    "type": "string"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "start": {
                                          "type": "string"
                                        },
                                        "end": {
                                          "type": "string"
                                        },
                                        "startInSec": {
                                          "type": "number"
                                        },
                                        "endInSec": {
                                          "type": "number"
                                        }
                                      }
                                    }
                                  },
                                  "entities": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "type": "string"
                                        },
                                        "text": {
                                          "type": "string"
                                        },
                                        "confidence": {
                                          "type": "number"
                                        },
                                        "speakerId": {
                                          "type": "string"
                                        },
                                        "language": {
                                          "type": "string"
                                        },
                                        "instances": {
                                          "type": "object",
                                          "properties": {
                                            "startInSec": {
                                              "type": "number"
                                            },
                                            "endInSec": {
                                              "type": "number"
                                            }
                                          }
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "speakers": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "integer"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "start": {
                                          "type": "string"
                                        },
                                        "end": {
                                          "type": "string"
                                        },
                                        "startInSec": {
                                          "type": "number"
                                        },
                                        "endInSec": {
                                          "type": "number"
                                        }
                                      }
                                    }
                                  },
                                  "totalWords": {
                                    "type": "integer"
                                  },
                                  "duration": {
                                    "type": "integer"
                                  },
                                  "wpm": {
                                    "type": "integer"
                                  }
                                }
                              }
                            }
                          }
                        },
                        "duration": {
                          "type": "object",
                          "properties": {
                            "start": {
                              "type": "string"
                            },
                            "end": {
                              "type": "string"
                            },
                            "inSecond": {
                              "type": "number"
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "mediaId": {
                          "type": "string"
                        },
                        "mediaUrl": {
                          "type": "string"
                        },
                        "transcriptRevision": {
                          "type": "integer",
                          "description": "Revision of the transcript. Starts at 0 and increases by one on every saved change to the transcript. Send it back as `expectedTranscriptRevision` when you save the transcript, label a passage or comment on one."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "transcript": {
                    "summary": "Transcript",
                    "value": {
                      "status": "success",
                      "data": {
                        "folderId": "0648e533f72c",
                        "mediaType": "audio",
                        "name": "vatsal",
                        "sourceLanguage": "en-US",
                        "insight": {
                          "transcript": [
                            {
                              "id": 0,
                              "text": "Okay. Let's do the testing for transcription.",
                              "speakerId": "0",
                              "confidence": 1,
                              "language": "en-US",
                              "instances": [
                                {
                                  "start": "00:00:00.240",
                                  "end": "00:00:02.994",
                                  "startInSec": 0.24,
                                  "endInSec": 2.9940499999999997
                                }
                              ],
                              "entities": [
                                {
                                  "id": "1",
                                  "text": "Okay.",
                                  "confidence": 0.99782515,
                                  "speakerId": "0",
                                  "language": "en-US",
                                  "instances": {
                                    "startInSec": 0.24,
                                    "endInSec": 0.48
                                  }
                                }
                              ]
                            }
                          ],
                          "speakers": [
                            {
                              "id": 0,
                              "name": "0",
                              "instances": [
                                {
                                  "start": "00:00:00.240",
                                  "end": "00:00:02.994",
                                  "startInSec": 0.24,
                                  "endInSec": 2.9940499999999997
                                }
                              ],
                              "totalWords": 10,
                              "duration": 3,
                              "wpm": 200
                            }
                          ]
                        },
                        "duration": {
                          "start": "00:00:00.240",
                          "end": "00:00:12.144",
                          "inSecond": 12.144
                        },
                        "createdAt": "2025-10-17T17:25:57.608Z",
                        "mediaId": "b4994aa1267c",
                        "mediaUrl": "MEDIA_URL",
                        "transcriptRevision": 3
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      },
      "put": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "Update Transcript",
        "operationId": "media-audio-video-update-transcript",
        "description": "Replaces the transcript of a media file with the array you send. Read the transcript first with `GET /media/transcript/{mediaId}`, change what you need, and send the whole array back.\n\n#### Avoid overwriting someone else's save\n\nSend `expectedTranscriptRevision` with the `transcriptRevision` you read. If anyone saved the transcript since, the request returns 409 \"This transcript changed since you opened it. Reload to keep editing.\" and changes nothing: read the transcript again, reapply your change, and save with the new revision. Leave it out and the save always goes through, replacing whatever is there.\n\nA successful save increases the revision by one and returns the new value. Labels and comments on passages are then moved to follow their words in the background.\n\n#### Request rules\n\n- `transcript` needs at least one sentence; an empty transcript cannot be saved.\n- Sentence `id` values must be unique when you send `expectedTranscriptRevision`.\n- Keys that are not listed below return 400.\n\n#### Errors\n\n- `400` when the body fails validation.\n- `404` when your company has no media with that id.\n- `409` when `expectedTranscriptRevision` is stale.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file.",
            "schema": {
              "type": "string"
            },
            "example": "b4994aa1267c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "transcript": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "number",
                          "description": "Sentence id. Must be unique across the array when you send `expectedTranscriptRevision`."
                        },
                        "speakerId": {
                          "type": "string",
                          "description": "Speaker id. Trimmed, required."
                        },
                        "speaker": {
                          "type": "object",
                          "properties": {
                            "userId": {
                              "type": "string",
                              "description": "Matched user id.",
                              "nullable": true
                            },
                            "name": {
                              "type": "string",
                              "description": "Matched name.",
                              "nullable": true
                            },
                            "email": {
                              "type": "string",
                              "description": "Matched email.",
                              "nullable": true
                            }
                          },
                          "description": "The team member matched to this speaker, when there is one. Every key may be empty or `null`."
                        },
                        "text": {
                          "type": "string",
                          "description": "Sentence text. Trimmed. An empty string is accepted."
                        },
                        "confidence": {
                          "type": "number",
                          "description": "Sentence confidence, as returned by the transcript endpoint."
                        },
                        "language": {
                          "type": "string",
                          "description": "Language code, as returned by the transcript endpoint."
                        },
                        "score": {
                          "type": "object",
                          "properties": {
                            "compound": {
                              "type": "number"
                            },
                            "neg": {
                              "type": "number"
                            },
                            "neu": {
                              "type": "number"
                            },
                            "pos": {
                              "type": "number"
                            }
                          },
                          "required": [
                            "compound",
                            "neg",
                            "neu",
                            "pos"
                          ],
                          "description": "Sentence sentiment, as returned by the transcript endpoint. Send it back so a save does not drop it."
                        },
                        "instances": {
                          "type": "array",
                          "description": "Timing of the sentence.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "start": {
                                "type": "string",
                                "description": "Start time as `HH:MM:SS.mmm`. Required."
                              },
                              "end": {
                                "type": "string",
                                "description": "End time as `HH:MM:SS.mmm`. Required."
                              },
                              "startInSec": {
                                "type": "number"
                              },
                              "endInSec": {
                                "type": "number"
                              },
                              "adjustedStart": {
                                "type": "string",
                                "description": "Adjusted start time."
                              },
                              "adjustedEnd": {
                                "type": "string",
                                "description": "Adjusted end time."
                              }
                            },
                            "required": [
                              "start",
                              "end"
                            ]
                          }
                        },
                        "entities": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          },
                          "description": "Word-level entries, as returned by the transcript endpoint. Not validated further."
                        }
                      },
                      "required": [
                        "id",
                        "speakerId",
                        "text",
                        "confidence"
                      ]
                    },
                    "description": "The full transcript, as an array of sentences. At least one."
                  },
                  "expectedTranscriptRevision": {
                    "type": "integer",
                    "description": "Optional. The `transcriptRevision` you read the transcript at. Integer, 0 or more. When it is stale the save returns 409 and nothing is written.",
                    "minimum": 0
                  }
                },
                "required": [
                  "transcript"
                ]
              },
              "example": {
                "transcript": [
                  {
                    "id": 0,
                    "text": "Okay. Let's do the testing for transcription.",
                    "speakerId": "0",
                    "confidence": 1,
                    "language": "en-US",
                    "instances": [
                      {
                        "start": "00:00:00.240",
                        "end": "00:00:02.994",
                        "startInSec": 0.24,
                        "endInSec": 2.994
                      }
                    ],
                    "entities": []
                  }
                ],
                "expectedTranscriptRevision": 3
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success`.",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "`Updated successfully.`"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "transcriptRevision": {
                          "type": "integer",
                          "description": "The transcript revision after this save."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "message": "Updated successfully.",
                      "data": {
                        "transcriptRevision": 4
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "The body failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "\"transcript\" must contain at least 1 items",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No media with that id in your company",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "No media with that id in your company",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Media details not found",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The transcript changed since you read it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-409": {
                    "summary": "The transcript changed since you read it",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 409,
                      "message": "This transcript changed since you opened it. Reload to keep editing.",
                      "hints": [
                        "Please use PUT for update instead of POST",
                        "The requested operation failed because it tried to create a resource that already exists."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/media/transcript/{mediaId}/source": {
      "get": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "Source transcript of a translated file",
        "operationId": "media-audio-video-source-transcript",
        "description": "Returns the transcript of the original source-language file behind a translated one, so you can read a translation against the text it came from.\n\nPass the media id of the **translated** file. Speak AI resolves the original from the translation record, either as the separate media the two-step flow keeps or, when the translation replaced the text in place, by rebuilding the original from the words the transcription engine stored.\n\nWhen the original cannot be shown, the request still answers 200. Read `data.available` first: `false` carries a `reason` and nothing else, and `true` carries the transcript. There is no 404 for an unavailable original.\n\nThe sentence shape matches `GET /media/transcript/{mediaId}`. The rebuilt in-place original omits the per-sentence `entities` array; the two-step original carries whatever the source media holds. `confidence` on every sentence is the confidence the transcription engine reported for the original, not a measure of the translation.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "The id of the translated media. Sending the id of the original returns available false with reason no-link.",
            "schema": {
              "type": "string"
            },
            "example": "b4994aa1267c"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "available": {
                          "type": "boolean",
                          "description": "Whether the original transcript can be shown. Everything below is present only when this is true."
                        },
                        "reason": {
                          "type": "string",
                          "enum": [
                            "no-link",
                            "original-not-retained",
                            "source-deleted",
                            "source-missing",
                            "source-not-ready",
                            "source-has-no-transcript"
                          ],
                          "description": "Why the original cannot be shown. Present only when available is false. no-link: this file is not a translation, or its translation has not finished. original-not-retained: a text note, whose original text the translation overwrote. source-deleted: the original media was deleted. source-missing: the original is not in your workspace, or your folder access does not reach it. source-not-ready: the original is still processing. source-has-no-transcript: the original holds no transcript to return."
                        },
                        "sourceMediaId": {
                          "type": "string",
                          "description": "The id of the original media. On an in-place translation this is the same id you asked for, because one media holds both versions."
                        },
                        "sourceLanguage": {
                          "type": "string",
                          "description": "The language the original was transcribed in. It can be auto on a file uploaded without a declared language."
                        },
                        "mediaType": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "duration": {
                          "type": "object",
                          "properties": {
                            "start": {
                              "type": "string"
                            },
                            "end": {
                              "type": "string"
                            },
                            "inSecond": {
                              "type": "number"
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "insight": {
                          "type": "object",
                          "properties": {
                            "transcript": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "integer"
                                  },
                                  "text": {
                                    "type": "string"
                                  },
                                  "speakerId": {
                                    "type": "string"
                                  },
                                  "confidence": {
                                    "type": "number"
                                  },
                                  "language": {
                                    "type": "string"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "start": {
                                          "type": "string"
                                        },
                                        "end": {
                                          "type": "string"
                                        },
                                        "startInSec": {
                                          "type": "number"
                                        },
                                        "endInSec": {
                                          "type": "number"
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "speakers": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "integer"
                                  },
                                  "name": {
                                    "type": "string"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "available": {
                    "summary": "The original is available",
                    "value": {
                      "status": "success",
                      "data": {
                        "available": true,
                        "sourceMediaId": "0648e533f72c",
                        "sourceLanguage": "en-US",
                        "mediaType": "audio",
                        "name": "Kickoff call",
                        "duration": {
                          "start": "00:00:00.000",
                          "end": "00:00:12.480",
                          "inSecond": 12.48
                        },
                        "createdAt": "2026-08-20T10:14:52.117Z",
                        "insight": {
                          "transcript": [
                            {
                              "id": 0,
                              "text": "Okay. Let's do the testing for transcription.",
                              "speakerId": "0",
                              "confidence": 0.98,
                              "language": "en-US",
                              "instances": [
                                {
                                  "start": "00:00:00.240",
                                  "end": "00:00:02.994",
                                  "startInSec": 0.24,
                                  "endInSec": 2.994
                                }
                              ]
                            }
                          ],
                          "speakers": [
                            {
                              "id": 0,
                              "name": "Speaker 1"
                            }
                          ]
                        }
                      }
                    }
                  },
                  "unavailable": {
                    "summary": "The original cannot be shown",
                    "value": {
                      "status": "success",
                      "data": {
                        "available": false,
                        "reason": "source-not-ready"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/media/speakers/{mediaId}": {
      "put": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "Update Transcript Speakers",
        "operationId": "media-audio-video-update-transcript-speakers",
        "description": "### Request Description\n\nThis API endpoint allows you to update speaker names in the transcription of a media object.\n\n#### Endpoint\n\n`PUT /v1/media/speakers/:mediaId`\n\n#### Method\n\n`PUT`\n\n#### Purpose\n\nThe purpose of this request is to update the speaker information associated with a specific media object. This includes modifying the names of the speakers in the transcription data.\n\n#### Input Parameters\n\n- `mediaId` (path parameter): The unique identifier for the media object whose speaker information you wish to update.\n\n- **Request Body**: The request body should be a JSON array containing objects with the following structure:\n\n - **id** (string): The unique identifier for the speaker **(ORIGINAL)**.\n\n - **name** (string): The new name of the speaker.\n\n\n#### Response Structure\n\nThe response will return a JSON object containing the following fields:\n\n- **status**: Indicates the status of the request.\n\n- **message**: String\n\n\n#### Example Response\n\n``` json\n{\n \"status\": \"\",\n \"message\": \"\"\n}\n\n ```\n\n#### Notes\n\n- Ensure that the `mediaId` provided in the URL corresponds to an existing media object.\n\n- The request body must be formatted as a JSON array, even if updating a single speaker.\n\n- The response will confirm the status of the update operation, along with any relevant data about the media analysis.\n\n**Request rules.** The body is an array, one entry per speaker you are relabelling, and every entry needs `id` and `name`. Omit `segmentIds` to relabel every segment for that speaker, or pass them to limit the rename to one paragraph. Pass `mergeIntoId` to merge this speaker into an existing one.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "b4994aa1267c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "description": "One entry per speaker you want to relabel.",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The speaker you are renaming, given as either the speaker's current label or its numeric speaker id. Required on every array entry. Trimmed. The server matches the current label first and the numeric id second (resolveTargetSpeaker at, so a label wins when both could match."
                    },
                    "name": {
                      "type": "string",
                      "description": "The new name for that speaker. Required on every array entry. Trimmed. Reusing another speaker's name returns 400 unless you also send mergeIntoId on the same entry."
                    },
                    "segmentIds": {
                      "type": "array",
                      "items": {
                        "type": "number"
                      },
                      "description": "The transcript segment ids you want renamed. Send it to limit the change to one paragraph, and leave it out to rename every segment belonging to that speaker. Optional. Items must be numbers. No minimum or maximum item count."
                    },
                    "mergeIntoId": {
                      "type": "string",
                      "description": "The id of the speaker you are merging this one into. Sending it confirms you meant to combine two speakers, so the duplicate name check is skipped for this entry. Optional. An empty string is allowed, and an empty string counts as not set."
                    }
                  },
                  "required": [
                    "id",
                    "name"
                  ]
                }
              },
              "example": [
                {
                  "id": "0",
                  "name": "Vatsal"
                }
              ]
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "insight": {
                          "type": "object",
                          "properties": {
                            "isAnalyze": {
                              "type": "boolean"
                            },
                            "transcript": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "integer"
                                  },
                                  "text": {
                                    "type": "string"
                                  },
                                  "confidence": {
                                    "type": "number"
                                  },
                                  "speakerId": {
                                    "type": "integer"
                                  },
                                  "language": {
                                    "type": "string"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "adjustedStart": {
                                          "type": "string"
                                        },
                                        "adjustedEnd": {
                                          "type": "string"
                                        },
                                        "start": {
                                          "type": "string"
                                        },
                                        "end": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "faces": {
                              "type": "array",
                              "items": {}
                            },
                            "keywords": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "adjustedStart": {
                                          "type": "string"
                                        },
                                        "adjustedEnd": {
                                          "type": "string"
                                        },
                                        "start": {
                                          "type": "string"
                                        },
                                        "end": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  },
                                  "id": {
                                    "type": "integer"
                                  },
                                  "name": {
                                    "type": "string"
                                  }
                                }
                              }
                            },
                            "labels": {
                              "type": "array",
                              "items": {}
                            },
                            "brands": {
                              "type": "array",
                              "items": {}
                            },
                            "topics": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "adjustedStart": {
                                          "type": "string"
                                        },
                                        "adjustedEnd": {
                                          "type": "string"
                                        },
                                        "start": {
                                          "type": "string"
                                        },
                                        "end": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  },
                                  "id": {
                                    "type": "integer"
                                  },
                                  "name": {
                                    "type": "string"
                                  }
                                }
                              }
                            },
                            "people": {
                              "type": "array",
                              "items": {}
                            },
                            "locations": {
                              "type": "array",
                              "items": {}
                            },
                            "arts": {
                              "type": "array",
                              "items": {}
                            },
                            "dates": {
                              "type": "array",
                              "items": {}
                            },
                            "events": {
                              "type": "array",
                              "items": {}
                            },
                            "geopolitical": {
                              "type": "array",
                              "items": {}
                            },
                            "languages": {
                              "type": "array",
                              "items": {}
                            },
                            "laws": {
                              "type": "array",
                              "items": {}
                            },
                            "money": {
                              "type": "array",
                              "items": {}
                            },
                            "ordinals": {
                              "type": "array",
                              "items": {}
                            },
                            "percentages": {
                              "type": "array",
                              "items": {}
                            },
                            "quantities": {
                              "type": "array",
                              "items": {}
                            },
                            "times": {
                              "type": "array",
                              "items": {}
                            },
                            "cardinals": {
                              "type": "array",
                              "items": {}
                            },
                            "nationalities": {
                              "type": "array",
                              "items": {}
                            },
                            "products": {
                              "type": "array",
                              "items": {}
                            }
                          }
                        },
                        "duration": {
                          "type": "object",
                          "properties": {
                            "inSecond": {
                              "type": "string"
                            },
                            "end": {
                              "type": "string"
                            },
                            "start": {
                              "type": "string"
                            }
                          }
                        },
                        "summary": {
                          "type": "object",
                          "properties": {
                            "original": {
                              "type": "object",
                              "properties": {
                                "text": {
                                  "type": "string"
                                },
                                "createdAt": {
                                  "type": "string",
                                  "format": "date-time"
                                }
                              }
                            }
                          }
                        },
                        "tags": {
                          "type": "array",
                          "items": {}
                        },
                        "isTranscriptionOnly": {
                          "type": "boolean"
                        },
                        "processingProgress": {
                          "type": "string"
                        },
                        "state": {
                          "type": "string"
                        },
                        "remark": {
                          "type": "string"
                        },
                        "sentiment": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "document": {
                                "type": "object",
                                "properties": {
                                  "Negative": {
                                    "type": "integer"
                                  },
                                  "Neutral": {
                                    "type": "integer"
                                  },
                                  "Positive": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "sentences": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "type": "integer"
                                    },
                                    "instances": {
                                      "type": "array",
                                      "items": {}
                                    },
                                    "score": {
                                      "type": "object",
                                      "properties": {
                                        "compound": {
                                          "type": "integer"
                                        },
                                        "neg": {
                                          "type": "integer"
                                        },
                                        "neu": {
                                          "type": "integer"
                                        },
                                        "pos": {
                                          "type": "integer"
                                        }
                                      }
                                    },
                                    "text": {
                                      "type": "string"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "name": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        },
                        "publishedUrl": {
                          "type": "string"
                        },
                        "mediaId": {
                          "type": "string"
                        },
                        "originalCreatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "faceSpriteImg": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "success",
                    "value": {
                      "status": "success",
                      "data": {
                        "insight": {
                          "isAnalyze": true,
                          "transcript": [
                            {
                              "id": 1,
                              "text": "Both. Hello hello good how are you?",
                              "confidence": 0.8278,
                              "speakerId": 1,
                              "language": "en-US",
                              "instances": [
                                {
                                  "adjustedStart": "0:00:00",
                                  "adjustedEnd": "0:00:05.92",
                                  "start": "0:00:00",
                                  "end": "0:00:05.92"
                                }
                              ]
                            }
                          ],
                          "faces": [],
                          "keywords": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "adjustedStart": "0:00:08.44",
                                  "adjustedEnd": "0:00:13.84",
                                  "start": "0:00:08.44",
                                  "end": "0:00:13.84"
                                }
                              ],
                              "id": 1,
                              "name": "company"
                            }
                          ],
                          "labels": [],
                          "brands": [],
                          "topics": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "adjustedStart": "0:00:00",
                                  "adjustedEnd": "0:00:47.744",
                                  "start": "0:00:00",
                                  "end": "0:00:47.744"
                                }
                              ],
                              "id": 1,
                              "name": "Promotions"
                            }
                          ],
                          "people": [],
                          "locations": [],
                          "arts": [],
                          "dates": [],
                          "events": [],
                          "geopolitical": [],
                          "languages": [],
                          "laws": [],
                          "money": [],
                          "ordinals": [],
                          "percentages": [],
                          "quantities": [],
                          "times": [],
                          "cardinals": [],
                          "nationalities": [],
                          "products": []
                        },
                        "duration": {
                          "inSecond": "47",
                          "end": "0:00:47.744",
                          "start": "0:00:00"
                        },
                        "summary": {
                          "original": {
                            "text": "",
                            "createdAt": "2020-09-04T16:16:19.118Z"
                          }
                        },
                        "tags": [],
                        "isTranscriptionOnly": false,
                        "processingProgress": "100",
                        "state": "processed",
                        "remark": "",
                        "sentiment": [
                          {
                            "document": {
                              "Negative": 0,
                              "Neutral": 0,
                              "Positive": 0
                            },
                            "sentences": [
                              {
                                "id": 1,
                                "instances": [],
                                "score": {
                                  "compound": 0,
                                  "neg": 0,
                                  "neu": 1,
                                  "pos": 0
                                },
                                "text": "Sentence 1"
                              }
                            ]
                          }
                        ],
                        "createdAt": "2020-08-22T23:05:57.000Z",
                        "updatedAt": "2020-08-22T23:11:11.288Z",
                        "name": "REc557e3c8f2ac42a828973c39f1d6be37",
                        "description": "",
                        "publishedUrl": "media/5d03a9d5d4bca272e9c8cf89/audio/1598137553998-rec557e3c8f2ac42a828973c39f1d6be37.mp3",
                        "mediaId": "81c226f66705",
                        "originalCreatedAt": "2020-11-08T16:40:10.706Z",
                        "faceSpriteImg": ""
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/media/status/{mediaId}": {
      "get": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "Status",
        "operationId": "media-audio-video-status",
        "description": "If you need a list or a quick preview of a media you can request meta-data about media objects with this endpoint, this will include all information except for results of analysis, transcripts, etc.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "duration": {
                          "type": "object",
                          "properties": {
                            "inSecond": {
                              "type": "string"
                            },
                            "end": {
                              "type": "string"
                            },
                            "start": {
                              "type": "string"
                            }
                          }
                        },
                        "tags": {
                          "type": "array",
                          "items": {}
                        },
                        "processingProgress": {
                          "type": "string"
                        },
                        "state": {
                          "type": "string"
                        },
                        "remark": {
                          "type": "string"
                        },
                        "_id": {
                          "type": "string"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "name": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        },
                        "publishedUrl": {
                          "type": "string"
                        },
                        "mediaId": {
                          "type": "string"
                        },
                        "originalCreatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "thumbnail": {
                          "type": "object",
                          "description": "The video's thumbnail. An empty object when the file has none, which includes every audio file and text note. Use it to follow a frame asked for with PUT /media/{mediaId}/thumbnail: pending is true while the frame is being made, and error is set when it failed, while url still shows the previous thumbnail.",
                          "properties": {
                            "url": {
                              "type": "string",
                              "description": "A signed link to the current thumbnail. Present only when the file has one. It expires, so do not store it."
                            },
                            "source": {
                              "type": "string",
                              "enum": [
                                "auto",
                                "custom"
                              ],
                              "description": "`auto` for the thumbnail Speak AI made, `custom` for one you set. Present only when the file has a thumbnail."
                            },
                            "pending": {
                              "type": "boolean",
                              "description": "Present and true while a requested frame is still being made."
                            },
                            "error": {
                              "type": "string",
                              "description": "Why the last requested frame was not saved, for example \"The frame took too long. Try again.\" Present only when it failed."
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "success",
                    "value": {
                      "status": "success",
                      "data": {
                        "duration": {
                          "inSecond": "47",
                          "end": "0:00:47.744",
                          "start": "0:00:00"
                        },
                        "tags": [],
                        "processingProgress": "100",
                        "state": "processed",
                        "remark": "",
                        "_id": "5f41a4d5c35d8d0fd556e075",
                        "createdAt": "2020-08-22T23:05:57.000Z",
                        "updatedAt": "2020-08-22T23:11:11.288Z",
                        "name": "REc557e3c8f2ac42a828973c39f1d6be37",
                        "description": "",
                        "publishedUrl": "media/5d03a9d5d4bca272e9c8cf89/audio/1598137553998-rec557e3c8f2ac42a828973c39f1d6be37.mp3",
                        "mediaId": "81c226f66705",
                        "originalCreatedAt": "2020-11-08T16:40:10.706Z"
                      }
                    }
                  },
                  "insights-notuploaded": {
                    "summary": "Insights - notUploaded",
                    "value": {
                      "status": 200,
                      "state": "notUploaded",
                      "message": {
                        "insight": {
                          "isAnalyze": false,
                          "faces": [],
                          "keywords": [],
                          "sentiments": [],
                          "emotions": [],
                          "labels": [],
                          "brands": [],
                          "topics": [],
                          "transcript": [],
                          "speakers": []
                        },
                        "duration": {
                          "inSecond": "0"
                        },
                        "createdAt": "2019-09-25T14:32:19.000Z",
                        "_id": "5d8b7a730838363d90a17e86",
                        "videoId": "QHw2hPhk9-R7rrlPKBZk-FBY9P8rDBV",
                        "name": "ForBiggerBlazes - Copy",
                        "description": "",
                        "privacyMode": "Public",
                        "size": "0",
                        "processingProgress": "0",
                        "state": "notUploaded",
                        "publishedUrl": "video/5cc37a170eb2173efcfc1f7d/1569421938203-ForBiggerBlazesCopymp4.mp4",
                        "videoFormat": 1,
                        "sourceLanguage": "en-US",
                        "order": 0,
                        "__v": 0
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/media/reanalyze/{mediaId}": {
      "get": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "Re-analyze a media file or text note",
        "operationId": "media-reanalyze",
        "description": "Run the Speak Ai analysis again over a record that has already been processed, and replace the insights it produced the first time.\n\nOne route covers both kinds of record. Pass the `mediaId` of an uploaded audio or video file, or the `mediaId` of a text note, and Speak Ai re-analyzes whichever record the id belongs to.\n\n### What the call does\n\nThe record moves into the `preparingAnalysis` state and the analysis runs in the background, so the response comes back before the new insights exist. Poll `GET /media/status/{mediaId}` to follow it, or subscribe to the `media.reanalyzed` and `text.reanalyzed` webhook events.\n\nThe query parameters select which parts of the analysis run again. Omit all of them to re-run the default analysis.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Id of the media file or text note to re-analyze.",
            "example": "3f8d1ec6ca39"
          },
          {
            "name": "isInsights",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Re-run insight extraction.",
            "example": "true"
          },
          {
            "name": "isSentiment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Re-run sentiment analysis.",
            "example": "true"
          },
          {
            "name": "isFillerWords",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Re-run filler word detection.",
            "example": "true"
          },
          {
            "name": "isEmbeddings",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Rebuild the embeddings used by AI chat.",
            "example": "true"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "reanalyze": {
                    "summary": "Re-analysis started",
                    "value": {
                      "status": "success",
                      "message": "Leon Wednesday Meeting re-analyzed successfully!"
                    }
                  },
                  "reanalyze-failed-media": {
                    "summary": "Record already in the failed state",
                    "value": {
                      "status": "success",
                      "message": "Media analysis failed. Please contact support if you need assistance."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "internal-server-error": {
                    "summary": "Internal server error",
                    "value": {
                      "status": "failed",
                      "requestId": "ca665625-645e-438a-867d-366a6e3f133a",
                      "code": 500,
                      "message": "Something went wrong. Please try again later.",
                      "hints": [
                        "Something went wrong. Please try again later."
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/media/{mediaId}": {
      "put": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "Update meta-data",
        "operationId": "media-audio-video-update-meta-data",
        "description": "If you want to rename, edit description or add a tag to your media, you can do it here.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "createdAt": {
                    "type": "string",
                    "description": "The creation date to store on the file. Optional. An empty string is allowed, but the controller only writes the value when it is truthy, so an empty string does not clear the existing date."
                  },
                  "description": {
                    "type": "string",
                    "description": "A short description for the file. Optional. Trimmed. An empty string is allowed by validation, but the controller only writes a non empty value, so you cannot clear the description this way."
                  },
                  "folderId": {
                    "type": "string",
                    "description": "The id of the folder you want to move the file into. Optional. An empty string is allowed but is treated as no change."
                  },
                  "mediaId": {
                    "type": "string",
                    "description": "Ignored. The server takes the media id from the path, not from the body. Optional. An empty string is allowed. Accepted by validation and never destructured by the controller.",
                    "deprecated": true
                  },
                  "manageBy": {
                    "type": "string",
                    "description": "The id of the user you want the file assigned to. Optional. An empty string is allowed but is treated as no change. Stored as a reference to a user record (media model: Schema.Types.ObjectId, ref 'User')."
                  },
                  "name": {
                    "type": "string",
                    "description": "The new title for the file. Required. Minimum length 1. This is the only property the controller always writes, so every update overwrites the title."
                  },
                  "remark": {
                    "type": "string",
                    "description": "A note stored with the file. Optional. An empty string is allowed but is treated as no change."
                  },
                  "status": {
                    "type": "string",
                    "description": "The workflow status of the file. Optional and unconstrained by the schema, so any string passes validation. The media model recognizes '', pending, progress, completed and pendingPayment, and the update runs through findOneAndUpdate without runValidators, so the model enum is not enforced on this path. Only written when not empty."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The full list of tags for the file. The list you send replaces the existing one. Optional. Items are strings and empty strings are allowed. There is no cap on the number of items. Only written when the property is present, and an empty array is truthy so it does clear the tags."
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "update-1",
                "description": "description-1",
                "tags": [
                  "work",
                  "personal"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "update-media-data-success": {
                    "summary": "Update Media data - success",
                    "value": {
                      "status": "success",
                      "message": "Updated successfully."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "update-media-data-failure": {
                    "summary": "Update Media data - failure",
                    "value": {
                      "status": "failed",
                      "requestId": "7ed88c1e-e1ee-44b0-afa5-50041d2b2309",
                      "code": 404,
                      "message": "Media does not exist!",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "Delete File",
        "operationId": "media-audio-video-delete-file",
        "description": "If you want to remove media from your library - you can do it here.\n\nWe can revert the changes if you send us a request.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "delete": {
                    "summary": "Delete",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/media/{mediaId}/thumbnail": {
      "put": {
        "tags": [
          "Media (Audio/Video)"
        ],
        "summary": "Set a custom thumbnail",
        "operationId": "media-audio-video-set-thumbnail",
        "description": "Replace a video's thumbnail with your own image or with a frame from the video. Send exactly one of:\n\n- an image file as multipart form data in the `image` field, for example `-F 'image=@cover.png'`\n- JSON `{ \"url\": \"https://...\" }`, a public https link to an image, which the server downloads\n- JSON `{ \"seekSec\": 12.5 }`, to use the video frame at that many seconds from the start\n\nThe image must be JPEG, PNG or WebP and at most 10 MB. The server checks the file's content, not its name or declared type, so a GIF is refused. A `url` must be https and point to a public address, every redirect included. The server follows up to 3 redirects and gives up after 8 seconds.\n\nA frame request answers `202` straight away and the frame is saved in the background. A `seekSec` past the end of the video uses the frame one second before the end. To follow it, poll `GET /media/status/{mediaId}` and read `data.thumbnail`: `pending` is true while the frame is being made, `error` says why it failed, and once it is saved `url` points to the new frame and `source` is `custom`. While a frame request for the video is still running, another one returns `409`. A request that has not finished after 5 minutes no longer blocks a new one.\n\nEach change replaces the current thumbnail and deletes the previous custom image. There is no way back to the automatic thumbnail. Only a video can have a thumbnail, and a frame cannot be taken from an archived video. You need permission to edit media.\n\n#### Errors\n\n- `400` when the request does not carry exactly one of `image`, `url` and `seekSec`: \"Send exactly one of an image file, an https url or seekSec.\"\n- `400` when `url` is not https or `seekSec` is below 0, with the validation message.\n- `400` when the media is not a video: \"Only a video can have a thumbnail.\"\n- `400` when the image is not a JPEG, PNG or WebP file: \"Use one JPEG, PNG or WebP image of up to 10 MB.\"\n- `400` when the link is blocked or cannot be downloaded: \"That image url could not be downloaded.\"\n- `400` when a frame is asked of an archived video, or of one whose file Speak does not hold: \"A frame cannot be taken from this video.\"\n- `400` when the frame service refuses the request: \"That frame could not be taken.\"\n- `403` when you do not have permission to edit media.\n- `404` when the media does not exist.\n- `409` when a frame is already being taken for this video.\n- `413` when the image is larger than 10 MB: \"Use one JPEG, PNG or WebP image of up to 10 MB.\"\n- `503` when the frame service is busy: \"Thumbnails are busy right now. Try again in a minute.\"",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the video.",
            "schema": {
              "type": "string"
            },
            "example": "b4994aa1267c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "A public https link to a JPEG, PNG or WebP image of up to 10 MB. The server downloads it. Send this or `seekSec`, not both."
                  },
                  "seekSec": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Use the video frame at this many seconds from the start. A value past the end uses the frame one second before the end. Send this or `url`, not both."
                  }
                }
              },
              "example": {
                "url": "https://example.com/images/cover.png"
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "binary",
                    "description": "The image file: JPEG, PNG or WebP, up to 10 MB."
                  }
                },
                "required": [
                  "image"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The image is saved as the thumbnail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "thumbnail": {
                          "type": "object",
                          "properties": {
                            "url": {
                              "type": "string",
                              "description": "A signed link to the new thumbnail. It expires, so do not store it."
                            },
                            "source": {
                              "type": "string",
                              "enum": [
                                "custom"
                              ],
                              "description": "`custom` for a thumbnail you set."
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "thumbnail": {
                      "url": "https://media.example.com/media/abc123/thumbnail/b4994aa1267c-1a2b3c4d5e6f7a8b.png?Expires=1767225600&Signature=abc",
                      "source": "custom"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "The frame request is accepted and runs in the background",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "thumbnail": {
                          "type": "object",
                          "properties": {
                            "pending": {
                              "type": "boolean",
                              "enum": [
                                true
                              ],
                              "description": "Always `true`. The frame is still being taken."
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "thumbnail": {
                      "pending": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Not exactly one of image, url and seekSec, an unsupported image, a link that cannot be downloaded, or a frame that cannot be taken",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 400,
                  "message": "Send exactly one of an image file, an https url or seekSec."
                }
              }
            }
          },
          "403": {
            "description": "You do not have permission to edit media",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "message": "You do not have permission to perform this action"
                }
              }
            }
          },
          "404": {
            "description": "The media does not exist",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "Media details not found"
                }
              }
            }
          },
          "409": {
            "description": "A frame is already being taken for this video",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 409,
                  "message": "A frame is already being taken for this video."
                }
              }
            }
          },
          "413": {
            "description": "The image is larger than 10 MB",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 413,
                  "message": "Use one JPEG, PNG or WebP image of up to 10 MB."
                }
              }
            }
          },
          "503": {
            "description": "The frame service is busy",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 503,
                  "message": "Thumbnails are busy right now. Try again in a minute."
                }
              }
            }
          }
        }
      }
    },
    "/live-transcription/create": {
      "post": {
        "tags": [
          "Live Transcription"
        ],
        "summary": "Create a live transcription session",
        "operationId": "live-transcription-create",
        "description": "Create the media record that a live transcription session writes into, and get back the `mediaId` the streaming connection needs.\n\nCall this first. The record is created in the `liveTranscript` state with its processing progress already at 100, so it appears in the folder straight away and fills with words as the session runs.\n\nEvery field in the body is optional. When `folderId` is left out, Speak Ai stores the record in the first folder on the account.\n\n### Sessions that already exist\n\nPass `meetingAssistantId` to attach the session to a scheduled meeting assistant event. When that event already has a media record, Speak Ai returns the existing `mediaId` instead of creating a second one, so the call is safe to repeat.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name for the media record. A meeting assistant event overrides this with its own title."
                  },
                  "mediaType": {
                    "type": "string",
                    "description": "Recording MIME type, for example `audio/webm` or `video/mp4`. Speak Ai keeps the part before the slash, and stores anything it does not recognise as `audio`."
                  },
                  "sourceLanguage": {
                    "type": "string",
                    "description": "Language code for the session. Defaults to `en-us`."
                  },
                  "folderId": {
                    "type": "string",
                    "description": "Folder to store the record in. Defaults to the first folder on the account."
                  },
                  "tag": {
                    "type": "string",
                    "description": "Single tag stored on the record."
                  },
                  "meetingAssistantId": {
                    "type": "string",
                    "description": "Id of a scheduled meeting assistant event to attach the session to."
                  },
                  "recorderToken": {
                    "type": "string",
                    "description": "Token of a recorder, when the session comes from an embedded recorder. Speak Ai then takes the folder and the source language from the recorder."
                  }
                }
              },
              "example": {
                "name": "Weekly customer call",
                "mediaType": "audio/webm",
                "sourceLanguage": "en-us",
                "folderId": "your_folder_id_here"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "mediaId": {
                          "type": "string"
                        },
                        "folderId": {
                          "type": "string"
                        },
                        "userId": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "live-transcription-create": {
                    "summary": "Session created",
                    "value": {
                      "status": "success",
                      "data": {
                        "mediaId": "3f8d1ec6ca39",
                        "folderId": "your_folder_id_here",
                        "userId": "609d7de35bde285f4c98ca63",
                        "message": "Live transcript media created successfully"
                      }
                    }
                  },
                  "live-transcription-create-existing": {
                    "summary": "Meeting assistant event already had a record",
                    "value": {
                      "status": "success",
                      "data": {
                        "mediaId": "3f8d1ec6ca39",
                        "folderId": "your_folder_id_here",
                        "userId": "609d7de35bde285f4c98ca63",
                        "message": "Existing live transcript media returned successfully"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "internal-server-error": {
                    "summary": "Internal server error",
                    "value": {
                      "status": "failed",
                      "requestId": "ca665625-645e-438a-867d-366a6e3f133a",
                      "code": 500,
                      "message": "Something went wrong. Please try again later.",
                      "hints": [
                        "Something went wrong. Please try again later."
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/live-transcription/update/{mediaId}": {
      "post": {
        "tags": [
          "Live Transcription"
        ],
        "summary": "Update a live transcription session",
        "operationId": "live-transcription-update",
        "description": "Append transcribed words to a live transcription session, and hand Speak Ai the finished recording when the session ends.\n\nSend `words` while the session runs. Speak Ai merges them into sentences by speaker and language and appends them to the transcript already on the record.\n\nSend `aws` once, after the recording is uploaded. That moves the record into the `preparingAnalysis` state, triggers transcoding, and starts the same analysis an uploaded file gets. Include `totalDuration` with it so the duration is right when the uploaded file does not report one.\n\nBoth fields are optional and they can be sent in the same call.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Id returned by `POST /live-transcription/create`.",
            "example": "3f8d1ec6ca39"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "words": {
                    "type": "array",
                    "description": "Words transcribed since the last call, in order.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "Position of the word in the session."
                        },
                        "text": {
                          "type": "string",
                          "description": "The word itself."
                        },
                        "confidence": {
                          "type": "number",
                          "description": "Recogniser confidence for the word, from 0 to 1."
                        },
                        "language": {
                          "type": "string",
                          "description": "Language code the word was recognised in."
                        },
                        "speakerId": {
                          "type": "string",
                          "description": "Speaker the word is attributed to."
                        },
                        "instances": {
                          "type": "object",
                          "description": "Where the word sits in the recording.",
                          "properties": {
                            "startInSec": {
                              "type": "number"
                            },
                            "endInSec": {
                              "type": "number"
                            }
                          }
                        },
                        "email": {
                          "type": "string",
                          "description": "Email of the speaker, when the session knows it."
                        },
                        "userId": {
                          "type": "string",
                          "description": "Speak Ai user id of the speaker, when the session knows it."
                        }
                      }
                    }
                  },
                  "aws": {
                    "type": "object",
                    "description": "Location of the finished recording. Send this once, at the end of the session.",
                    "properties": {
                      "bucket": {
                        "type": "string"
                      },
                      "key": {
                        "type": "string"
                      },
                      "location": {
                        "type": "string"
                      }
                    }
                  },
                  "totalDuration": {
                    "type": "number",
                    "description": "Length of the session in seconds, used when the uploaded file reports a duration of 0."
                  }
                }
              },
              "example": {
                "words": [
                  {
                    "id": 1,
                    "text": "hello",
                    "confidence": 0.95,
                    "language": "en",
                    "speakerId": "speaker-1",
                    "instances": {
                      "startInSec": 1.2,
                      "endInSec": 1.5
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "live-transcription-update": {
                    "summary": "Words appended",
                    "value": {
                      "status": "success",
                      "message": "Live transcription updated successfully"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "live-transcription-update-missing": {
                    "summary": "No media record for that id",
                    "value": {
                      "status": "failed",
                      "requestId": "3fcf7e0c-a977-4c37-bae5-a72485206cd0",
                      "code": 404,
                      "message": "Media does not exist!",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "internal-server-error": {
                    "summary": "Internal server error",
                    "value": {
                      "status": "failed",
                      "requestId": "ca665625-645e-438a-867d-366a6e3f133a",
                      "code": 500,
                      "message": "Something went wrong. Please try again later.",
                      "hints": [
                        "Something went wrong. Please try again later."
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/live-transcription/token": {
      "post": {
        "tags": [
          "Live Transcription"
        ],
        "summary": "Mint a live transcription handshake token",
        "operationId": "live-transcription-token",
        "description": "Mint the short-lived token that opens a live transcription streaming connection for the calling session.\n\nThe token is scoped to live transcription only. It is rejected anywhere else in the API, so it cannot stand in for an access token.\n\nThis endpoint takes no request body. The response carries the token and the number of seconds it stays valid for.\n\n### Rate limit\n\nThis endpoint is limited to 5 requests per 60 seconds per IP address. Going over returns `429` with a plain text body, so mint one token per session and reuse it until it expires.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "token": {
                          "type": "string"
                        },
                        "expiresIn": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "live-transcription-token": {
                    "summary": "Token minted",
                    "value": {
                      "status": "success",
                      "data": {
                        "token": "eyJhbGciOiJIUzI1NiJ9.test-live-token.0000000000",
                        "expiresIn": "18000s"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "live-transcription-token-rate-limited": {
                    "summary": "Rate limited",
                    "value": "Too many token requests from this IP, please try again after a minute"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "internal-server-error": {
                    "summary": "Internal server error",
                    "value": {
                      "status": "failed",
                      "requestId": "ca665625-645e-438a-867d-366a6e3f133a",
                      "code": 500,
                      "message": "Something went wrong. Please try again later.",
                      "hints": [
                        "Something went wrong. Please try again later."
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/text/create": {
      "post": {
        "tags": [
          "Text"
        ],
        "summary": "Create Text note",
        "operationId": "text-create-text-note",
        "description": "## PARAMETERS\n\nThe difference between `rawText` and `text.`\n\n`text` (required): Text is an HTML field to display content on the editor. It helps users to identify `bold,` `italic` or any other editor functionality.\n\n**Important:** If you don't have an HTML editor in your application, you can pass normal text content.\n\n`rawText` (required): This helps Speak Ai to analyze text notes.\n\n`remark`: If you want to pass any remarks from the user to display on Speak and also in your application.\n\n``` json\nuserId: String; // optional\nfolderId: String, // optional\nname: String, // required,\ndescription: string, // optional\ntags: [], // optional\ntext: \"HTML content\", // required\nrawText: \"raw text content\", // required\nremark: \"string\", // optional\n\n ```\n\n### Webhook Callback URL:\n\n- If you created a webhook for text events and want to receive a callback to a specific URL for this text note, you can assign `callbackUrl` - `string` in a `req.body`.\n- Speak will consider the `callbackUrl` and will skip the callbackUrl created via [Webhook API](https://docs.speakai.co/#5777a89c-a6c3-4d0e-aab1-d33fdec5cbe8).\n\n---\n\n## Response\n\nYou can select from the examples attached to this API endpoint or find below:\n\n```\n{\n \"status\": \"success\",\n \"data\": {\n \"mediaId\": \"xxxxxxxxx\",\n \"folderId\": \"\"\n }\n}\n\n ```\n\n**Request rules.** Nothing in the body is unconditionally required. The body is validated, and any property not listed below is rejected with a 400, so do not send extra keys.\n\nIn practice: send name, text and rawText. If you omit name, the note is titled with the creation timestamp in YYYY-MM-DD HH:mm:ss form. If rawText is missing or empty the note is saved but never analyzed, so you get no insights, sentiment, keywords or search embeddings for it.\n\nfolderId: if you omit it or send an empty string, the note goes into the first folder belonging to the note owner, and one is created for them if they have none. The folder actually used comes back in the response.\n\ncount: if you omit it, word and character counts are calculated from rawText. If you send it, your numbers are stored as given and no counting is done.\n\ntags: only the comma separated string form is saved on this endpoint. An array passes validation and is then discarded, leaving the note with no tags.\n\nBilling: if the workspace has no text note credit left, the request still returns HTTP 200, but the body carries a failed status with code 402 and no note is created.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Names the note. Surrounding whitespace is removed. If you leave it out, Speak titles the note with the creation timestamp in YYYY-MM-DD HH:mm:ss form. String. Optional. Stored trimmed. Falls back to a generated timestamp title."
                  },
                  "text": {
                    "type": "string",
                    "description": "Holds the display copy of the note. It can contain HTML so an editor keeps bold, italic and other formatting. If your application has no rich text editor, send the same plain content you send in rawText. This copy is stored and shown, but it is not what gets analyzed. String. Empty string allowed. Stored trimmed. Stored as an empty string if you omit it."
                  },
                  "rawText": {
                    "type": "string",
                    "description": "Carries the plain text that Speak analyzes. This is what produces insights, sentiment, keywords and the search index for the note, so send it whenever you want the note analyzed. If it is empty, the note is saved but no analysis runs. String. Empty string allowed. Stored trimmed. Stored as an empty string if you omit it."
                  },
                  "description": {
                    "type": "string",
                    "description": "Adds a short summary shown alongside the note. String. Empty string allowed. Stored trimmed. Defaults to an empty string."
                  },
                  "tags": {
                    "type": "string",
                    "description": "Labels the note. Send a comma separated string such as \"sales,q3\" and Speak splits it into separate tags. A string with no comma becomes a single tag. An array passes validation on this endpoint but is not saved, so use the string form when you create a note. String or array. Only the string form is stored on create. Split on commas. An empty string leaves the note with no tags."
                  },
                  "folderId": {
                    "type": "string",
                    "description": "Files the note in one of your folders. Leave it out or send an empty string and Speak puts the note in the first folder belonging to the owner, creating one if they have none. The folder that was used comes back in the response. String. Empty string allowed."
                  },
                  "fields": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    },
                    "description": "Sets values for the custom fields on the note. Each entry takes an id and a value. Entries whose id does not match a custom field in your workspace are dropped and the remaining ones are saved. If none of the ids match, no custom field values are saved. Array of objects shaped {id, value}. Every entry must carry an id. Value can be any JSON type. Unknown ids are silently removed."
                  },
                  "count": {
                    "type": "object",
                    "description": "Overrides the word and character counts stored on the note. Send wordCount, characterCount and characterCountWithoutSpace. Leave it out and Speak counts them from rawText for you. Object. Keys read: wordCount, characterCount, characterCountWithoutSpace, all numbers. Any object shape is accepted, and keys you leave out are stored as empty."
                  },
                  "createdAt": {
                    "type": "string",
                    "description": "Sets the creation date recorded on the note, so you can backdate content you are importing. Defaults to the time of the request. Date. Accepts an ISO 8601 date string or a timestamp."
                  },
                  "callbackUrl": {
                    "type": "string",
                    "description": "Stores a webhook delivery URL on the note. Speak uses it in place of the URL configured on your webhook only for deliveries that carry the whole note record, which on this endpoint means the failure event sent if the note cannot be saved. The note created and note analyzed events from this endpoint always go to the URL configured on your webhook. String. Empty string allowed. Stored exactly as sent, without trimming. Stored as an empty string if you omit it."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Assigns the new note to another user in your workspace, using that user's 24 character id. Leave it out and the note belongs to the account making the request. The owner also decides which folder is used when you do not name one. String. Must be the 24 character id of a user. Any other value fails the save and returns a 500."
                  },
                  "remark": {
                    "type": "string",
                    "description": "A free text remark on the note. Postman's example sends this on create, but the value is not saved at creation time. Add a remark by updating the note afterwards."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "mediaId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "create-text-note": {
                    "summary": "Create Text note",
                    "value": {
                      "status": "success",
                      "data": {
                        "mediaId": "c55125c7cc32"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/text/insight/{mediaId}": {
      "get": {
        "tags": [
          "Text"
        ],
        "summary": "Text Insight",
        "operationId": "text-text-insight",
        "description": "You need to call this API to find the insights from your text note.\n\nPlease check an example find the return response and an object.\n\n## Response\n\n```\n{\n \"status\": \"success\",\n \"data\": {\n \"count\": {\n \"wordCount\": 0,\n \"characterCount\": 0,\n \"characterCountWithoutSpace\": 0\n },\n \"insight\": {\n \"intents\": {\n \"needs\": [\n {\n \"id\": 32,\n \"text\": \"Sentence 1\"\n }\n ],\n \"wants\": [\n {\n \"id\": 50,\n \"text\": \"Sentence 1\"\n }\n ]\n },\n \"state\": \"processed\",\n \"updatedAt\": \"2021-04-13T00:30:26.720Z\",\n \"arts\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 512,\n \"startChar\": 489\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n },\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 1397,\n \"startChar\": 1386\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxxxx\",\n \"id\": 1\n }\n ],\n \"brands\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 202,\n \"startChar\": 198\n },\n {\n \"endChar\": 356,\n \"startChar\": 352\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n },\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 333,\n \"startChar\": 310\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 1\n },\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 721,\n \"startChar\": 713\n },\n {\n \"endChar\": 3009,\n \"startChar\": 3001\n },\n {\n \"endChar\": 6074,\n \"startChar\": 6066\n },\n {\n \"endChar\": 6391,\n \"startChar\": 6383\n },\n {\n \"endChar\": 6615,\n \"startChar\": 6607\n },\n {\n \"endChar\": 6854,\n \"startChar\": 6846\n },\n {\n \"endChar\": 6914,\n \"startChar\": 6906\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 2\n }\n ],\n \"cardinals\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 1797,\n \"startChar\": 1794\n },\n {\n \"endChar\": 1850,\n \"startChar\": 1847\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n },\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 3028,\n \"startChar\": 3022\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 1\n }\n ],\n \"dates\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 755,\n \"startChar\": 739\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"events\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 755,\n \"startChar\": 739\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"facs\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 755,\n \"startChar\": 739\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"geopolitical\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 172,\n \"startChar\": 163\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"keywords\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 172,\n \"startChar\": 163\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"languages\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 172,\n \"startChar\": 163\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"laws\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 172,\n \"startChar\": 163\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"locations\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 172,\n \"startChar\": 163\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"money\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 172,\n \"startChar\": 163\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"nationalities\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 1284,\n \"startChar\": 1275\n }\n ],\n \"isCustom\": false,\n \"name\": \"Republish\",\n \"id\": 0\n }\n ],\n \"ordinals\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 2812,\n \"startChar\": 2807\n },\n {\n \"endChar\": 2851,\n \"startChar\": 2846\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"people\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 196,\n \"startChar\": 188\n },\n {\n \"endChar\": 350,\n \"startChar\": 342\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"percentages\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 196,\n \"startChar\": 188\n },\n {\n \"endChar\": 350,\n \"startChar\": 342\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"products\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 4930,\n \"startChar\": 4926\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"quantities\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 4930,\n \"startChar\": 4926\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"times\": [\n {\n \"isDeleted\": false,\n \"instances\": [\n {\n \"endChar\": 4930,\n \"startChar\": 4926\n }\n ],\n \"isCustom\": false,\n \"name\": \"xxxxx\",\n \"id\": 0\n }\n ],\n \"topics\": []\n },\n \"description\": \"xxxxx\",\n \"tags\": [\n \"tag1\",\n \"tag2\"\n ],\n \"text\": \"<strong class=&#x27;preserveHtml&#x27; class=&#x27;preserveHtml&#x27; class=&#x27;preserveHtml&#x27; class=&#x27;preserveHtml&#x27;>Hello, This is sample text</b>\",\n \"rawText\": \"Hello, This is sample text\",\n \"state\": \"processed\",\n \"assignTo\": \"\",\n \"remark\": \"\",\n \"sentiment\": [\n {\n \"document\": {\n \"Negative\": 0.00000,\n \"Neutral\": 0.00000,\n \"Positive\": 0.00000\n },\n \"sentences\": [\n {\n \"id\": 1,\n \"instances\": [],\n \"score\": {\n \"compound\": 0,\n \"neg\": 0,\n \"neu\": 1,\n \"pos\": 0\n },\n \"text\": \"Sentence 1\"\n },\n {\n \"id\": 2,\n \"instances\": [],\n \"score\": {\n \"compound\": 0,\n \"neg\": 0,\n \"neu\": 1,\n \"pos\": 0\n },\n \"text\": \"Sentence 2\"\n },\n {\n \"id\": 3,\n \"instances\": [],\n \"score\": {\n \"compound\": 0.7269,\n \"neg\": 0.037,\n \"neu\": 0.809,\n \"pos\": 0.154\n },\n \"text\": \"Sentence 3\"\n }\n ]\n }\n ],\n \"createdAt\": \"2021-04-13T00:30:26.721Z\",\n \"originalCreatedAt\": \"2021-04-13T00:30:26.721Z\",\n \"name\": \"xxxxx\"\n }\n}\n\n ```",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "c1f4c82dec47"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "object",
                          "properties": {
                            "wordCount": {
                              "type": "integer"
                            },
                            "characterCount": {
                              "type": "integer"
                            },
                            "characterCountWithoutSpace": {
                              "type": "integer"
                            }
                          }
                        },
                        "insight": {
                          "type": "object",
                          "properties": {
                            "intents": {
                              "type": "object",
                              "properties": {
                                "needs": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "id": {
                                        "type": "integer"
                                      },
                                      "text": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                },
                                "wants": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "id": {
                                        "type": "integer"
                                      },
                                      "text": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "state": {
                              "type": "string"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "arts": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "brands": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "cardinals": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "dates": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "events": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "facs": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "geopolitical": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "keywords": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "languages": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "laws": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "locations": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "money": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "nationalities": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "ordinals": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "people": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "percentages": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "products": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "quantities": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "times": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "isDeleted": {
                                    "type": "boolean"
                                  },
                                  "instances": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "endChar": {
                                          "type": "integer"
                                        },
                                        "startChar": {
                                          "type": "integer"
                                        }
                                      }
                                    }
                                  },
                                  "isCustom": {
                                    "type": "boolean"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "type": "integer"
                                  }
                                }
                              }
                            },
                            "topics": {
                              "type": "array",
                              "items": {}
                            }
                          }
                        },
                        "description": {
                          "type": "string"
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "text": {
                          "type": "string"
                        },
                        "rawText": {
                          "type": "string"
                        },
                        "state": {
                          "type": "string"
                        },
                        "assignTo": {
                          "type": "string"
                        },
                        "remark": {
                          "type": "string"
                        },
                        "sentiment": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "document": {
                                "type": "object",
                                "properties": {
                                  "Negative": {
                                    "type": "integer"
                                  },
                                  "Neutral": {
                                    "type": "integer"
                                  },
                                  "Positive": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "sentences": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "type": "integer"
                                    },
                                    "instances": {
                                      "type": "array",
                                      "items": {}
                                    },
                                    "score": {
                                      "type": "object",
                                      "properties": {
                                        "compound": {
                                          "type": "integer"
                                        },
                                        "neg": {
                                          "type": "integer"
                                        },
                                        "neu": {
                                          "type": "integer"
                                        },
                                        "pos": {
                                          "type": "integer"
                                        }
                                      }
                                    },
                                    "text": {
                                      "type": "string"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "originalCreatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "text-insight": {
                    "summary": "Text Insight",
                    "value": {
                      "status": "success",
                      "data": {
                        "count": {
                          "wordCount": 0,
                          "characterCount": 0,
                          "characterCountWithoutSpace": 0
                        },
                        "insight": {
                          "intents": {
                            "needs": [
                              {
                                "id": 32,
                                "text": "Sentence 1"
                              }
                            ],
                            "wants": [
                              {
                                "id": 50,
                                "text": "Sentence 1"
                              }
                            ]
                          },
                          "state": "processed",
                          "updatedAt": "2021-04-13T00:30:26.720Z",
                          "arts": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 512,
                                  "startChar": 489
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "brands": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 202,
                                  "startChar": 198
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "cardinals": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 1797,
                                  "startChar": 1794
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "dates": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 755,
                                  "startChar": 739
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "events": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 755,
                                  "startChar": 739
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "facs": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 755,
                                  "startChar": 739
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "geopolitical": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 172,
                                  "startChar": 163
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "keywords": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 172,
                                  "startChar": 163
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "languages": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 172,
                                  "startChar": 163
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "laws": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 172,
                                  "startChar": 163
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "locations": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 172,
                                  "startChar": 163
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "money": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 172,
                                  "startChar": 163
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "nationalities": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 1284,
                                  "startChar": 1275
                                }
                              ],
                              "isCustom": false,
                              "name": "Republish",
                              "id": 0
                            }
                          ],
                          "ordinals": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 2812,
                                  "startChar": 2807
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "people": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 196,
                                  "startChar": 188
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "percentages": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 196,
                                  "startChar": 188
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "products": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 4930,
                                  "startChar": 4926
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "quantities": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 4930,
                                  "startChar": 4926
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "times": [
                            {
                              "isDeleted": false,
                              "instances": [
                                {
                                  "endChar": 4930,
                                  "startChar": 4926
                                }
                              ],
                              "isCustom": false,
                              "name": "xxxxx",
                              "id": 0
                            }
                          ],
                          "topics": []
                        },
                        "description": "xxxxx",
                        "tags": [
                          "tag1"
                        ],
                        "text": "<b>Hello, This is sample text</b>",
                        "rawText": "Hello, This is sample text",
                        "state": "processed",
                        "assignTo": "",
                        "remark": "",
                        "sentiment": [
                          {
                            "document": {
                              "Negative": 0,
                              "Neutral": 0,
                              "Positive": 0
                            },
                            "sentences": [
                              {
                                "id": 1,
                                "instances": [],
                                "score": {
                                  "compound": 0,
                                  "neg": 0,
                                  "neu": 1,
                                  "pos": 0
                                },
                                "text": "Sentence 1"
                              }
                            ]
                          }
                        ],
                        "createdAt": "2021-04-13T00:30:26.721Z",
                        "originalCreatedAt": "2021-04-13T00:30:26.721Z",
                        "name": "xxxxx"
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          }
        }
      }
    },
    "/text/update/{mediaId}": {
      "put": {
        "tags": [
          "Text"
        ],
        "summary": "Update Text Note",
        "operationId": "text-update-text-note",
        "description": "## PARAMETERS\n\nIf you want to update your customer unique `medicalId` key then you can pass as a `string`.\n\nThe difference between `rawText` and `text`\n\n`text`: Text is an HTML field to display content on the editor. It helps users to identify `bold`, `italic` or any other editor functionality.\n\n**Important:** If you don't have HTML editor in your application then you can pass normal text content.\n\n`rawText`: This helps Speak Ai to analyze text notes.\n\n`remark`: If you want to pass any remarks from the user to display on Speak and also in your application.\n\n```\nmedicalId: String, // optional\nname: String, // required,\ndescription: string, // optional\ntags: [], // optional\ntext: \"HTML content\", // see below\nrawText: \"raw text content\", // see below\nremark: \"string\", // optional\n```\n\n**Request rules.** The mediaId in the path is required and must belong to a note in your workspace that is not deleted. If it does not, you get a 404 before the controller runs. Body validation happens first, so a bad body returns a 400 before that check.\n\nNothing in the body is unconditionally required, but any property not listed below is rejected with a 400, so do not send extra keys.\n\n**Updating the note's text is an all-or-nothing operation, everything else is a partial update.** Omit `rawText` entirely and the note's `text`, `rawText`, sentiment, and word/character counts are left completely unchanged \u2014 nothing else in the request affects them. If you include `rawText` at all (even as an empty string), this endpoint replaces rather than patches the text content: an empty or wordless `rawText` clears both `rawText` and `text` on the note and empties its stored sentiment. So: to update the note's text, always send the complete `text` and `rawText` you want to keep together in the same request; to update anything else (name, description, tags, remark, status, manageBy) without touching the note's content, leave `rawText` out entirely.\n\ndescription, manageBy, remark, status and createdAt are only written when you send a value that is not empty. Sending an empty string for any of them leaves the current value in place instead of clearing it. tags behaves differently: an empty string leaves the current tags alone, but an empty array is written and clears them.\n\nOmitting name leaves the stored title unchanged.\n\nSet isAutoSave to true for background editor saves. That skips reanalysis and skips the in-app update notification. On a normal save, Speak reanalyzes the note only if it has not been processed before, and a note analyzed webhook is attempted when it does.\n",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "2b12351c8146"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "rawText": {
                    "type": "string",
                    "description": "Replaces the plain text that Speak analyzes. Omit this field entirely and the note's text, rawText, sentiment, and word/character counts are left completely unchanged, regardless of what else is in the request. If you include it at all \u2014 even as an empty string, or text with no words in it \u2014 this endpoint replaces rather than patches: Speak clears both the analyzed text and the display text on the note and empties its stored sentiment. If you're updating the note's text, always send the complete note body you want to keep. String. Empty string allowed (clears the note). Stored trimmed. The word count derived from this value decides whether text and rawText are stored or cleared, but only when this field is present in the request at all."
                  },
                  "text": {
                    "type": "string",
                    "description": "Replaces the display copy of the note, which can contain HTML so an editor keeps bold, italic and other formatting. Only takes effect when rawText is also present in the request \u2014 see rawText. If the rawText you send has no words, Speak clears this instead. If the rawText you send has words but you leave text out, the current display copy stays as it is. String. Empty string allowed. Stored trimmed. Cleared whenever the rawText you send has no words."
                  },
                  "name": {
                    "type": "string",
                    "description": "Replaces the note title. It also appears in the success message and in the in-app update notification. Leave it out and the current title stays as it is. String. Stored trimmed."
                  },
                  "description": {
                    "type": "string",
                    "description": "Replaces the short summary shown alongside the note. An empty string leaves the current summary in place rather than clearing it. String. Empty string allowed but treated as no change. Stored trimmed."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Replaces the tags on the note. Send an array of strings. A comma separated string is accepted but is stored as one tag on this endpoint, so use the array form here. Leave it out to keep the existing tags, or send an empty array to remove them all. String or array. Stored as sent. An empty array clears the tags; an empty string is treated as no change."
                  },
                  "remark": {
                    "type": "string",
                    "description": "Replaces the free text remark on the note. An empty string or null leaves the current remark in place rather than clearing it. String. Empty string and null allowed but treated as no change."
                  },
                  "status": {
                    "type": "string",
                    "description": "Sets the status recorded on the note. An empty string leaves the current status in place. String. Empty string allowed but treated as no change. Values outside the listed set are stored as sent but are not recognized anywhere in the product, so stay within the list.",
                    "enum": [
                      "",
                      "pending",
                      "progress",
                      "completed",
                      "pendingPayment"
                    ]
                  },
                  "manageBy": {
                    "type": "string",
                    "description": "Assigns the note to a user in your workspace, using that user's 24 character id. An empty string leaves the current assignee in place. String. Must be the 24 character id of a user. Empty string allowed but treated as no change. Any other value fails the update and returns a 500."
                  },
                  "isAutoSave": {
                    "type": "boolean",
                    "description": "Marks the request as a background save from an editor. Send true and Speak skips reanalyzing the note and skips the in-app update notification, which keeps frequent autosaves cheap. Send false or leave it out for a normal save. Boolean. Defaults to a normal save when absent."
                  },
                  "count": {
                    "type": "object",
                    "description": "Overrides the word and character counts stored on the note. Only takes effect when rawText is also present in the request. Send wordCount, characterCount and characterCountWithoutSpace. Leave rawText out and these counts are left unchanged regardless of what you send here; include rawText without this and Speak recounts from the rawText you sent. These numbers do not decide whether the body is kept: only the rawText you send does that. Object. Keys read: wordCount, characterCount, characterCountWithoutSpace, all numbers."
                  },
                  "createdAt": {
                    "type": "string",
                    "description": "Changes the creation date recorded on the note. Leave it out to keep the current date. Date. Accepts an ISO 8601 date string or a timestamp. Only written when present."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "update-text-note": {
                    "summary": "Update Text Note",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/text/{mediaId}": {
      "delete": {
        "tags": [
          "Text"
        ],
        "summary": "Delete Text Note",
        "operationId": "text-delete-text-note",
        "description": "## DELETE Request to Remove a Text Resource\n\nThis endpoint is used to delete a specific text resource identified by its unique `mediaId`. By sending a DELETE request to this endpoint, the client can remove the text resource from the server.\n\n### Request Parameters\n\n- **mediaId** (path parameter): A unique identifier for the text resource that you wish to delete. This is a required parameter and should be included in the URL.\n\n\n### Response Structure\n\nUpon successful deletion of the text resource, the server will respond with a status code indicating the outcome of the request:\n\n- **204 No Content**: Indicates that the resource was successfully deleted and there is no additional content to return.\n\n- **404 Not Found**: Indicates that the specified `mediaId` does not correspond to any existing resource.\n\n\n### Example\n\nTo delete a text resource with a specific `mediaId`, the request would look like:\n\n```\nDELETE {{url}}/v1/text/12345\n\n ```\n\nThis request would attempt to delete the text resource with the ID `12345`.\n\nMake sure to handle the response appropriately to confirm the deletion or to manage any errors that may arise.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "3722e7826784"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "delete-text-note": {
                    "summary": "Delete Text Note",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/media/export/{mediaId}/{fileType}": {
      "post": {
        "tags": [
          "Exports"
        ],
        "summary": "Export a media file",
        "operationId": "exports-export-media",
        "description": "Export one audio or video file from Speak Ai as a document, a caption file, or its source file.\n\n### Which formats can you export?\n\nPass the format as the `fileType` path parameter. Speak AI documents PDF, TXT, DOCX, SRT, VTT, and the source file itself as MP4.\n\n### How do you export a file's labels?\n\nPass `csv-labels` as `fileType` to get the labels on the transcript as a CSV, with one row for each labelled passage and label. A passage with two labels gives two rows. The response carries `Content-Disposition: attachment; filename=\"<file name>-labels.csv\"`. A file with no labels returns the header row only.\n\nThe columns, in order, are File name, Media ID, Folder, Group, Label, Label colour, Start, End, Speaker, Excerpt, Added by, Added at, Status, Confidence %, Comment count.\n\n- `Start` and `End` are times in the transcript, as `HH:mm:ss.SSS`.\n- `Speaker` holds the speaker names, joined with ` / ` when a passage spans speakers.\n- `Added by` is the team member who applied the label, or the name a reviewer gave on a dashboard link.\n- `Added at` is an ISO 8601 date.\n- `Status` is `active`, `shifted` or `needs_review`. A passage is `needs_review` when a transcript edit changed its words too much to place it with confidence.\n- `Confidence %` is the average transcription confidence of the passage's words. It is empty when the transcript has no word confidences, or while the passage is still being moved after a transcript edit.\n- `Comment count` counts the comments and replies on the passage, without deleted ones.\n- Archived labels are left out.\n- A text cell that starts with `=`, `+`, `-`, `@`, a tab or a carriage return gets a leading `'`, so a spreadsheet does not run it as a formula.\n\n### Which formats are unsupported?\n\nNot every format fits every record. You cannot export a text note as `srt`, `vtt`, `sourceFile`, `csv-transcript` or `csv-transcript-sentiment`, and you cannot export an audio or video file as `html`. Every one of those combinations returns `500` with the generic `Internal Server Error` body, so the response does not tell you which rule you hit. Quote the `requestId` it returns when you ask support about one.\n\n`ttml`, `md` and `mp4` pass validation, but Speak AI builds no export for any of them. The request returns neither a file nor an error, so it hangs until your client or the network times it out. Use `srt` or `vtt` for captions, and `sourceFile` for the original media.\n\n### Which prefix do you use?\n\nThe export route is mounted at three prefixes, `/media`, `/text`, and `/prompt`, and all three reach the same handler. The prefix does not change the result. Speak Ai reads the record that `mediaId` belongs to and exports it in the format `fileType` names, so `POST /media/export/{mediaId}/{fileType}` and `POST /text/export/{mediaId}/{fileType}` return the same file for the same id.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "a59b93b67685",
            "description": "Id of the record to export."
          },
          {
            "name": "fileType",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "csv-insights",
                "csv-labels",
                "csv-transcript",
                "csv-transcript-sentiment",
                "csv-text-sentiment",
                "docx",
                "html",
                "json",
                "md",
                "pdf",
                "sourceFile",
                "srt",
                "ttml",
                "txt",
                "vtt",
                "mp4"
              ]
            },
            "description": "Name the format to export the record in. One of `csv`, `csv-insights`, `csv-labels`, `csv-transcript`, `csv-transcript-sentiment`, `csv-text-sentiment`, `docx`, `html`, `json`, `md`, `pdf`, `sourceFile`, `srt`, `ttml`, `txt`, `vtt` or `mp4`. Any other value, `word` among them, is rejected as a validation error, and the unsupported combinations above still apply.",
            "example": "csv"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "txt": {
                    "summary": "TXT",
                    "value": "Speak Transcript - txt\nVideo Name: How To Find Your First Analyzed Video\nDate: Monday, December 14, 2020 12:09 PM\n\n0:00:00\r\nSpeaker #1\r\nHey there, in this video will show you how you can actually access the first \r\n\r\n\r\n0:00:03\r\nSpeaker #2\r\nvideo that you've uploaded. So right now we're in the sign in screen. All you have to do hit the sign in button. You're going to be redirected to the dashboard and you can sort of see some of the statistics and everything there, but what you're actually looking to do is hit the button where you can see the little video icon.\r\n\r\nYour list is actually going to\n...",
                    "x-abridged": true
                  },
                  "srt": {
                    "summary": "SRT",
                    "value": "1\n00:00:00,000 --> 00:00:05,920\nUpdated\n\n2\n00:00:05,920 --> 00:00:08,440\nIs this speak AI? Yes it is.\n\n3\n00:00:08,440 --> 00:00:13,840\nYeah, I was looking at the company and\nnotice here that you develop software\nright?\n\n4\n00:00:13,840 --> 00:00:19,240\nYes, and I wanted to see if your\ncompany's ever applied for the irap\ngrants.\n\n5\n00:00:19,240 --> 00:00:22,480\nYes we have. We have a have a person\n\n6\n00:00:22,480 --> 00:00:25,360\nthat we've sponsored right now and then\nwe,\n\n7\n00:00:25,360 --> 00:00:28,240\nyou know, I wrap your kickoff projects\nhere.\n\n8\n00:00:28,240 --> 00:00:31,840\nSo we've got \n...",
                    "x-abridged": true
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "unsupported-format": {
                    "summary": "unsupported format.",
                    "value": {
                      "status": "failed",
                      "message": "Can't export text object to .srt, try .docx or .pdf instead."
                    }
                  },
                  "json": {
                    "summary": "JSON",
                    "value": {
                      "mediaId": "875777809d88",
                      "name": "How To Customize Your Account & Interactive Media Players Globally",
                      "description": "Tyler shows you how to customize your account at the global level for audio and video.",
                      "tags": [
                        "speak"
                      ],
                      "duration": "136",
                      "createdAt": "2020-08-19T01:34:31.000Z",
                      "state": "processed",
                      "remark": "",
                      "summary": "Hi there, in this video I'm going to show you how you can actually customize your account globally, so that if you're sharing I frames are custom landing pages, whether audio or.",
                      "sentiment": {
                        "document": {
                          "Negative": 2.857142857142857,
                          "Neutral": 28.57142857142857,
                          "Positive": 68.57142857142857
                        },
                        "sentences": [
                          {
                            "id": 1,
                            "instances": [
                              {
                                "adjustedEnd": "0:00:05.85",
                                "adjustedStart": "0:00:00",
                                "end": "0:00:05.85",
                                "start": "0:00:00"
                              }
                            ],
                            "score": {
                              "compound": 0,
                              "neg": 0,
                              "neu": 1,
                              "pos": 0
                            },
                            "text": "Hi there, in this video I'm going to show you how you can actually customize your account globally,"
                          }
                        ]
                      },
                      "transcript": [
                        {
                          "speakerId": 1,
                          "text": "Hi there, in this video I'm going to show you how you can actually customize your account globally, so that if you're sharing I frames are custom landing pages, whether audio or vi...",
                          "start": "0:00:00",
                          "link": "https://app.speakai.co/video/insight/875777809d88?insight=transcript&timeStart=0:00:00"
                        }
                      ]
                    },
                    "x-abridged": true
                  }
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "csv": {
                    "summary": "CSV",
                    "value": "MediaId,Media Name,Tags,Duration,Created At,State,Remark,Summary,Overall sentiment,Sentence id,Speaker name,Sentence start time,Sentence end time,Sentence duration,Transcript,Sentiment,Insight category,Insight,Insight starts at,Insight ends at\n875777809d88,How To Customize Your Account & Interactive Media Players Globally,speak,136,Tue Aug 18 2020 21:34:31 GMT-0400 (Eastern Daylight Time),processed,,Hi there, in this video I'm going to show you how you can actually customize your account globally,  so that if you're sharing I frames are custom landing pages,  whether audio or video, that the s\n...",
                    "x-abridged": true
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "isSpeakerNames": {
                    "type": "boolean",
                    "description": "Set to true to print speaker names next to each segment of the transcript."
                  },
                  "isSpeakerEmail": {
                    "type": "boolean",
                    "description": "Set to true to print speaker email addresses next to each segment of the transcript. Null is accepted. The schema declares a default of false, but the validation middleware discards the schema's converted output, so omitting the property leaves it unset. Every export writer reads it for truthiness, so unset behaves the same as false."
                  },
                  "isTimeStamps": {
                    "type": "boolean",
                    "description": "Set to true to print a timestamp on each segment of the transcript."
                  },
                  "isInsightVisualized": {
                    "type": "boolean",
                    "description": "Set to true to render insights as charts and visuals in the exported file instead of plain text."
                  },
                  "isRedacted": {
                    "type": "boolean",
                    "description": "Set to true to redact sensitive content from the exported file."
                  },
                  "redactedCategories": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "List the categories of sensitive content you want redacted when isRedacted is true. the schema with no.items call, so the server does not validate the item type and applies no maximum array length. The server code types the value as string[]."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/text/export/{mediaId}/{fileType}": {
      "post": {
        "tags": [
          "Exports"
        ],
        "summary": "Export a text note",
        "operationId": "exports-export-text",
        "description": "Export one text note from Speak Ai as a document. The response is the same as the `/media` prefix returns for the same id.\n\n### Which formats can you export?\n\nPass the format as the `fileType` path parameter. Speak AI documents PDF, TXT, DOCX, SRT, VTT, and the source file itself as MP4.\n\n### Which formats are unsupported?\n\nNot every format fits every record. You cannot export a text note as `srt`, `vtt`, `sourceFile`, `csv-transcript` or `csv-transcript-sentiment`, and you cannot export an audio or video file as `html`. Every one of those combinations returns `500` with the generic `Internal Server Error` body, so the response does not tell you which rule you hit. Quote the `requestId` it returns when you ask support about one.\n\n`ttml`, `md` and `mp4` pass validation, but Speak AI builds no export for any of them. The request returns neither a file nor an error, so it hangs until your client or the network times it out. Use `srt` or `vtt` for captions, and `sourceFile` for the original media.\n\n### Which prefix do you use?\n\nThe export route is mounted at three prefixes, `/media`, `/text`, and `/prompt`, and all three reach the same handler. The prefix does not change the result. Speak Ai reads the record that `mediaId` belongs to and exports it in the format `fileType` names, so `POST /media/export/{mediaId}/{fileType}` and `POST /text/export/{mediaId}/{fileType}` return the same file for the same id.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "a59b93b67685",
            "description": "Id of the record to export."
          },
          {
            "name": "fileType",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "csv-insights",
                "csv-labels",
                "csv-transcript",
                "csv-transcript-sentiment",
                "csv-text-sentiment",
                "docx",
                "html",
                "json",
                "md",
                "pdf",
                "sourceFile",
                "srt",
                "ttml",
                "txt",
                "vtt",
                "mp4"
              ]
            },
            "description": "Name the format to export the record in. One of `csv`, `csv-insights`, `csv-labels`, `csv-transcript`, `csv-transcript-sentiment`, `csv-text-sentiment`, `docx`, `html`, `json`, `md`, `pdf`, `sourceFile`, `srt`, `ttml`, `txt`, `vtt` or `mp4`. Any other value, `word` among them, is rejected as a validation error, and the unsupported combinations above still apply.",
            "example": "csv"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "unsupported-format": {
                    "summary": "Unsupported format",
                    "value": {
                      "status": "failed",
                      "message": "Can't export text object to .srt, try .docx or .pdf instead."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "isSpeakerNames": {
                    "type": "boolean",
                    "description": "Set to true to print speaker names next to each segment of the transcript."
                  },
                  "isSpeakerEmail": {
                    "type": "boolean",
                    "description": "Set to true to print speaker email addresses next to each segment of the transcript. Null is accepted. The schema declares a default of false, but the validation middleware discards the schema's converted output, so omitting the property leaves it unset. Unset behaves the same as false."
                  },
                  "isTimeStamps": {
                    "type": "boolean",
                    "description": "Set to true to print a timestamp on each segment of the transcript."
                  },
                  "isInsightVisualized": {
                    "type": "boolean",
                    "description": "Set to true to render insights as charts and visuals in the exported file instead of plain text."
                  },
                  "isRedacted": {
                    "type": "boolean",
                    "description": "Set to true to redact sensitive content from the exported file."
                  },
                  "redactedCategories": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "List the categories of sensitive content you want redacted when isRedacted is true. the schema with no.items call, so the server does not validate the item type and applies no maximum array length. The server code types the value as string[]."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/prompt/export/{mediaId}/{fileType}": {
      "post": {
        "tags": [
          "Exports"
        ],
        "summary": "Export through the prompt prefix",
        "operationId": "exports-export-prompt",
        "description": "Export one record from Speak Ai through the `/prompt` prefix. The response is the same as the `/media` prefix returns for the same id.\n\n### Which formats can you export?\n\nPass the format as the `fileType` path parameter. Speak AI documents PDF, TXT, DOCX, SRT, VTT, and the source file itself as MP4.\n\n### Which formats are unsupported?\n\nNot every format fits every record. You cannot export a text note as `srt`, `vtt`, `sourceFile`, `csv-transcript` or `csv-transcript-sentiment`, and you cannot export an audio or video file as `html`. Every one of those combinations returns `500` with the generic `Internal Server Error` body, so the response does not tell you which rule you hit. Quote the `requestId` it returns when you ask support about one.\n\n`ttml`, `md` and `mp4` pass validation, but Speak AI builds no export for any of them. The request returns neither a file nor an error, so it hangs until your client or the network times it out. Use `srt` or `vtt` for captions, and `sourceFile` for the original media.\n\n### Which prefix do you use?\n\nThe export route is mounted at three prefixes, `/media`, `/text`, and `/prompt`, and all three reach the same handler. The prefix does not change the result. Speak Ai reads the record that `mediaId` belongs to and exports it in the format `fileType` names, so `POST /media/export/{mediaId}/{fileType}` and `POST /text/export/{mediaId}/{fileType}` return the same file for the same id.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "a59b93b67685",
            "description": "Id of the record to export."
          },
          {
            "name": "fileType",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "csv-insights",
                "csv-labels",
                "csv-transcript",
                "csv-transcript-sentiment",
                "csv-text-sentiment",
                "docx",
                "html",
                "json",
                "md",
                "pdf",
                "sourceFile",
                "srt",
                "ttml",
                "txt",
                "vtt",
                "mp4"
              ]
            },
            "description": "Name the format to export the record in. One of `csv`, `csv-insights`, `csv-labels`, `csv-transcript`, `csv-transcript-sentiment`, `csv-text-sentiment`, `docx`, `html`, `json`, `md`, `pdf`, `sourceFile`, `srt`, `ttml`, `txt`, `vtt` or `mp4`. Any other value, `word` among them, is rejected as a validation error, and the unsupported combinations above still apply.",
            "example": "csv"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "unsupported-format": {
                    "summary": "Unsupported format",
                    "value": {
                      "status": "failed",
                      "message": "Can't export text object to .srt, try .docx or .pdf instead."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "isSpeakerNames": {
                    "type": "boolean",
                    "description": "Set to true to print speaker names next to each segment of the transcript."
                  },
                  "isSpeakerEmail": {
                    "type": "boolean",
                    "description": "Set to true to print speaker email addresses next to each segment of the transcript. Null is accepted. The schema declares a default of false, but the validation middleware discards the schema's converted output, so omitting the property leaves it unset. Unset behaves the same as false."
                  },
                  "isTimeStamps": {
                    "type": "boolean",
                    "description": "Set to true to print a timestamp on each segment of the transcript."
                  },
                  "isInsightVisualized": {
                    "type": "boolean",
                    "description": "Set to true to render insights as charts and visuals in the exported file instead of plain text."
                  },
                  "isRedacted": {
                    "type": "boolean",
                    "description": "Set to true to redact sensitive content from the exported file."
                  },
                  "redactedCategories": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "List the categories of sensitive content you want redacted when isRedacted is true. the schema with no.items call, so the server does not validate the item type and applies no maximum array length. The server code types the value as string[]."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/media/exportMultiple": {
      "post": {
        "tags": [
          "Exports"
        ],
        "summary": "Multi-export",
        "operationId": "exports-multi-export",
        "description": "You can export multiple media at once. We're going to zip the documents and send it to you as an `arraybuffer`.\n\n**Request rules.** No field is conditionally required. Some behaviour depends on what you send rather than on validation, so read the field descriptions below.\n\nWith `fileType` set to `csv-labels`, the ZIP holds one `<file name>-labels.csv` for each file that has labels, and files without labels are left out. With `isMerged` set to true it holds one `merged_export.csv` with the rows of every file. When none of the files has labels, the request returns a JSON body instead of a ZIP, with HTTP status 200, `status` set to `failed` and `message` set to `No labels found for these files`. Check the response content type before you save it as a ZIP. The columns are the same as for a single export.\n\nA text note in the set is skipped rather than failed when `fileType` is `sourceFile`, `csv-transcript` or `csv-transcript-sentiment`, so the ZIP can hold fewer files than you asked for. The notification Speak AI raises when the export finishes counts the files it actually wrote against the number you requested.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mediaIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "List the IDs of the media files you want to export together. Required. the schema with no.items call, so the server does not validate the item type and applies no maximum array length. Pass an empty array to fall back to exporting a whole folder through folderId."
                  },
                  "fileType": {
                    "type": "string",
                    "description": "Choose the file format used for every file in the export. Must be one of the accepted values. There is no default, and the schema does not mark it required, but the controller dereferences it unconditionally, so omitting it returns a 500 rather than a validation error. Treat it as required in practice.",
                    "enum": [
                      "csv",
                      "csv-insights",
                      "csv-labels",
                      "csv-transcript",
                      "csv-transcript-sentiment",
                      "csv-text-sentiment",
                      "docx",
                      "html",
                      "json",
                      "md",
                      "pdf",
                      "sourceFile",
                      "srt",
                      "ttml",
                      "txt",
                      "vtt",
                      "mp4"
                    ]
                  },
                  "isSpeakerNames": {
                    "type": "boolean",
                    "description": "Set to true to print speaker names next to each segment of the transcript."
                  },
                  "isSpeakerEmail": {
                    "type": "boolean",
                    "description": "Set to true to print speaker email addresses next to each segment of the transcript. Null is accepted. The schema declares a default of false, but the validation middleware discards the schema's converted output, so omitting the property leaves it unset. Unset behaves the same as false."
                  },
                  "isTimeStamps": {
                    "type": "boolean",
                    "description": "Set to true to print a timestamp on each segment of the transcript."
                  },
                  "isInsightVisualized": {
                    "type": "boolean",
                    "description": "Set to true to render insights as charts and visuals in the exported files instead of plain text."
                  },
                  "isRedacted": {
                    "type": "boolean",
                    "description": "Set to true to redact sensitive content from the exported files."
                  },
                  "redactedCategories": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "List the categories of sensitive content you want redacted when isRedacted is true. the schema with no.items call, so the server does not validate the item type and applies no maximum array length. The server code types the value as string[]."
                  },
                  "folderId": {
                    "type": "string",
                    "description": "Give the ID of a folder to export every media file inside it. The server uses this only when mediaIds is empty. An empty string is explicitly allowed. The schema declares a default of empty string, but the validation middleware discards the schema's converted output, so an omitted folderId reaches the controller as undefined rather than as an empty string."
                  },
                  "isMerged": {
                    "type": "boolean",
                    "description": "Set to true to combine every media file into one document instead of one file per media inside the ZIP. The schema declares a default of false, but that default is not written back to the request, so omitting it leaves it unset. Unset behaves the same as false."
                  }
                },
                "required": [
                  "mediaIds"
                ]
              },
              "example": {
                "mediaIds": [
                  "a59b93b67685",
                  "dsd33b676asd"
                ],
                "fileType": "pdf",
                "isSpeakerNames": true,
                "isTimeStamps": true,
                "isInsightVisualized": true,
                "isRedacted": true,
                "isMerged": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "multi-export": {
                    "summary": "Multi-export",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/folder/views": {
      "get": {
        "tags": [
          "Folder"
        ],
        "summary": "Get All Views",
        "operationId": "folder-get-all-views",
        "description": "Get all views across all folders for the company. Used to populate dropdown for cloning views.",
        "x-speak-group": "Folder Views",
        "responses": {
          "200": {
            "description": "Success. This spec records no example response body for this endpoint."
          }
        },
        "x-doc-group": "Views"
      }
    },
    "/folder/{folderId}/views": {
      "get": {
        "tags": [
          "Folder"
        ],
        "summary": "Get Views by Folder ID",
        "operationId": "folder-get-views-by-folder-id",
        "description": "Get all views for a specific folder",
        "x-speak-group": "Folder Views",
        "parameters": [
          {
            "name": "folderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The ID of the folder to get views for",
            "example": "your_folder_id_here"
          }
        ],
        "responses": {
          "200": {
            "description": "Success. This spec records no example response body for this endpoint."
          }
        },
        "x-doc-group": "Folder Views"
      },
      "post": {
        "tags": [
          "Folder"
        ],
        "summary": "Create View",
        "operationId": "folder-create-view",
        "description": "Create a new view for a specific folder. Column types can be:\n\n**FieldType values:**\n- text\n- url\n- boolean\n- date\n- datetime\n- number\n- currency\n\n**DefaultViewColumn values:**\n- name\n- duration\n- tags\n- sentiment\n- datetime\n- createdAt\n- updatedAt",
        "x-speak-group": "Folder Views",
        "parameters": [
          {
            "name": "folderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The ID of the folder to create view for",
            "example": "your_folder_id_here"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "The name for the new view. Required."
                  },
                  "isDefault": {
                    "type": "boolean",
                    "description": "Whether this view becomes the folder's default view. Setting it to true clears the default flag on your other active views in the folder. Optional. The schema declares a default of false, but the middleware discards the schema's converted value, so an omitted isDefault reaches the handler as undefined. The stored value still ends up false, because the FolderView model defaults isDefault to false."
                  },
                  "columns": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "fieldId": {
                          "type": "string",
                          "description": "The ID of the custom field this column shows. Leave it empty for a built-in column. Optional. Empty string and null are accepted."
                        },
                        "name": {
                          "type": "string",
                          "description": "The heading shown for this column. Required."
                        },
                        "type": {
                          "type": "string",
                          "description": "What kind of value the column holds. The accepted set is the FieldType values followed by the DefaultViewColumn values. Required. The value must be one of the listed values. The set is built from Object.values(FieldType) and Object.values(DefaultViewColumn), both declared in speak-shared and re-exported through and The raw.valid list contains \"datetime\" twice, because it appears in both enums; the accepted set is the 15 distinct values listed here.",
                          "enum": [
                            "text",
                            "url",
                            "boolean",
                            "date",
                            "datetime",
                            "number",
                            "currency",
                            "name",
                            "duration",
                            "tags",
                            "sentiment",
                            "size",
                            "mediaType",
                            "createdAt",
                            "updatedAt"
                          ]
                        },
                        "definition": {
                          "type": "string",
                          "description": "An optional label describing what the column is derived from. Optional. Empty string and null are accepted."
                        },
                        "order": {
                          "type": "number",
                          "description": "The position of the column in the view, counting from zero. The server replaces a value of 0 with the column's position in the array you sent, so a column with order 0 in third position is stored as 2. Required. Declared as Any number passes; there is no minimum and no integer-only rule. The handler stores col.order || index, which is why 0 is overwritten."
                        }
                      }
                    },
                    "description": "The columns the view shows, in the order you want them displayed. Required. Each entry must be an object matching columnSchema. No cap on the number of entries. An empty array passes validation, because the array has no.min."
                  }
                },
                "required": [
                  "name",
                  "columns"
                ]
              },
              "example": {
                "name": "My Custom View",
                "isDefault": false,
                "columns": [
                  {
                    "fieldId": "",
                    "name": "Name",
                    "type": "name",
                    "definition": "",
                    "order": 0
                  },
                  {
                    "fieldId": "",
                    "name": "Duration",
                    "type": "duration",
                    "definition": "duration",
                    "order": 1
                  },
                  {
                    "fieldId": "",
                    "name": "Tags",
                    "type": "tags",
                    "definition": "tags",
                    "order": 2
                  },
                  {
                    "fieldId": "",
                    "name": "Sentiment",
                    "type": "sentiment",
                    "definition": "sentiment",
                    "order": 3
                  },
                  {
                    "fieldId": "",
                    "name": "Created At",
                    "type": "datetime",
                    "definition": "createdAt",
                    "order": 4
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. This spec records no example response body for this endpoint."
          }
        },
        "x-doc-group": "Folder Views"
      }
    },
    "/folder/{folderId}/views/{viewId}": {
      "put": {
        "tags": [
          "Folder"
        ],
        "summary": "Update View",
        "operationId": "folder-update-view",
        "description": "Update an existing view. Note: isDefault is required in update operation.",
        "x-speak-group": "Folder Views",
        "parameters": [
          {
            "name": "folderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The ID of the folder",
            "example": "your_folder_id_here"
          },
          {
            "name": "viewId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The ID of the view to update",
            "example": "your_view_id_here"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "The new name for the view. Required."
                  },
                  "isDefault": {
                    "type": "boolean",
                    "description": "Whether this view is the folder's default view. Unlike the create call, you must send this value on every update. Setting it to true clears the default flag on your other active views in the folder. Required, with no default declared, so omitting it returns 400."
                  },
                  "columns": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "fieldId": {
                          "type": "string",
                          "description": "The ID of the custom field this column shows. Leave it empty for a built-in column. Optional. Empty string and null are accepted."
                        },
                        "name": {
                          "type": "string",
                          "description": "The heading shown for this column. Required."
                        },
                        "type": {
                          "type": "string",
                          "description": "What kind of value the column holds. The accepted set is the FieldType values followed by the DefaultViewColumn values. Required. The value must be one of the listed values. The set is built from Object.values(FieldType) and Object.values(DefaultViewColumn), both declared in speak-shared and re-exported through and The raw.valid list contains \"datetime\" twice, because it appears in both enums; the accepted set is the 15 distinct values listed here.",
                          "enum": [
                            "text",
                            "url",
                            "boolean",
                            "date",
                            "datetime",
                            "number",
                            "currency",
                            "name",
                            "duration",
                            "tags",
                            "sentiment",
                            "size",
                            "mediaType",
                            "createdAt",
                            "updatedAt"
                          ]
                        },
                        "definition": {
                          "type": "string",
                          "description": "An optional label describing what the column is derived from. Optional. Empty string and null are accepted."
                        },
                        "order": {
                          "type": "number",
                          "description": "The position of the column in the view, counting from zero. The server replaces a value of 0 with the column's position in the array you sent, so a column with order 0 in third position is stored as 2. Required. Declared as Any number passes; there is no minimum and no integer-only rule. The handler stores col.order || index, which is why 0 is overwritten."
                        }
                      }
                    },
                    "description": "The full set of columns the view shows, in display order. This replaces the view's existing columns. Required. Each entry must be an object matching columnSchema. No cap on the number of entries. An empty array passes validation, because the array has no.min."
                  }
                },
                "required": [
                  "name",
                  "isDefault",
                  "columns"
                ]
              },
              "example": {
                "name": "Updated View Name",
                "isDefault": true,
                "columns": [
                  {
                    "fieldId": "",
                    "name": "Name",
                    "type": "name",
                    "definition": "",
                    "order": 0
                  },
                  {
                    "fieldId": "",
                    "name": "Duration",
                    "type": "duration",
                    "definition": "duration",
                    "order": 1
                  },
                  {
                    "fieldId": "",
                    "name": "Tags",
                    "type": "tags",
                    "definition": "tags",
                    "order": 2
                  },
                  {
                    "fieldId": "",
                    "name": "Sentiment",
                    "type": "sentiment",
                    "definition": "sentiment",
                    "order": 3
                  },
                  {
                    "fieldId": "",
                    "name": "Created At",
                    "type": "datetime",
                    "definition": "createdAt",
                    "order": 4
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. This spec records no example response body for this endpoint."
          }
        },
        "x-doc-group": "Folder Views"
      },
      "delete": {
        "tags": [
          "Folder"
        ],
        "summary": "Delete View",
        "operationId": "folder-delete-view",
        "description": "Delete a view (soft delete - sets isActive to false)",
        "x-speak-group": "Folder Views",
        "parameters": [
          {
            "name": "folderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The ID of the folder",
            "example": "your_folder_id_here"
          },
          {
            "name": "viewId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The ID of the view to delete",
            "example": "your_view_id_here"
          }
        ],
        "responses": {
          "200": {
            "description": "Success. This spec records no example response body for this endpoint."
          }
        },
        "x-doc-group": "Folder Views"
      }
    },
    "/folder/views/clone": {
      "post": {
        "tags": [
          "Folder"
        ],
        "summary": "Clone View",
        "operationId": "folder-clone-view",
        "description": "Clone a view from source folder to target folder. Use 'Get All Views' to get available view IDs for cloning.\n\n**Request rules.** `targetFolderId` must differ from `sourceFolderId`. Sending the same id for both is rejected.",
        "x-speak-group": "Folder Views",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sourceFolderId": {
                    "type": "string",
                    "description": "The ID of the folder that holds the view you want to copy. Required."
                  },
                  "targetFolderId": {
                    "type": "string",
                    "description": "The ID of the folder you want the copied view added to. It must be a different folder from sourceFolderId. Required. Rejected when it equals sourceFolderId,. invalid(the schema). The error message is \"Source and target folder IDs cannot be the same\"."
                  },
                  "viewId": {
                    "type": "string",
                    "description": "The ID of the view inside the source folder that you want to copy. It must belong to an active view, otherwise the request returns 404. Required."
                  },
                  "name": {
                    "type": "string",
                    "description": "The name for the copied view in the target folder. Required."
                  },
                  "isDefault": {
                    "type": "boolean",
                    "description": "Whether the copied view becomes the default view for the target folder. Setting it to true clears the default flag on your other active views in that folder. Optional. The schema declares a default of false, but the middleware discards the schema's converted value, so an omitted isDefault reaches the handler as undefined. The stored value still ends up false, because the FolderView model defaults isDefault to false."
                  }
                },
                "required": [
                  "sourceFolderId",
                  "targetFolderId",
                  "viewId",
                  "name"
                ]
              },
              "example": {
                "sourceFolderId": "source_folder_id_here",
                "targetFolderId": "target_folder_id_here",
                "viewId": "view_id_to_clone_here",
                "name": "Cloned View Name",
                "isDefault": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. This spec records no example response body for this endpoint."
          }
        },
        "x-doc-group": "Views"
      }
    },
    "/folder": {
      "get": {
        "tags": [
          "Folder"
        ],
        "summary": "Get folders",
        "operationId": "folder-get-folders",
        "description": "## Get Folders\n\nThis endpoint retrieves a list of folders based on pagination and sorting criteria.\n\n### Request Parameters\n\n- **page** (integer, required): The page number to retrieve. This parameter is used for pagination.\n\n- **pageSize** (integer, required): The number of folders to return per page. This parameter controls the size of the result set.\n\n- **sortBy** (string, required): The field by which to sort the folders. In this case, it is sorted by `createdAt`.\n\n\n### Response Format\n\nThe response will contain the following structure:\n\n- **status** (string): The status of the request.\n\n- **data** (object): Contains the details of the folders retrieved.\n\n - **totalCount** (integer): The total number of folders available.\n\n - **pages** (integer or null): The total number of pages available based on the pagination.\n\n - **folders** (array): An array of folder objects, each containing:\n\n - **_id** (string): The unique identifier for the folder.\n\n - **defaultAssignTo** (string): The default user assigned to the folder.\n\n - **showOrder** (integer): The order in which the folder should be displayed.\n\n - **name** (string): The name of the folder.\n\n - **folderId** (string): The identifier for the folder.\n\n - **createdAt** (string): The creation date of the folder.\n\n - **updatedAt** (string): The last updated date of the folder.\n\n - **user** (object): An object representing the user associated with the folder.\n\n - **_id** (string): The unique identifier for the user.\n\n - **firstName** (string): The first name of the user.\n\n - **lastName** (string): The last name of the user.\n\n - **userId** (string): The identifier for the user associated with the folder.\n\n\n### Notes\n\n- Ensure that the `page` and `pageSize` parameters are set correctly to retrieve the desired set of folders.\n\n- The response may return an empty array if no folders are available for the specified page and size.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "example": "0"
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "example": "5"
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "createdAt"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "You can pass in the dateFormat",
            "x-postman-disabled": true
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "You can pass in the dateFormat",
            "x-postman-disabled": true
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "totalCount": {
                          "type": "integer"
                        },
                        "pages": {
                          "type": "string",
                          "nullable": true
                        },
                        "folders": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string"
                              },
                              "defaultAssignTo": {
                                "type": "string"
                              },
                              "showOrder": {
                                "type": "integer"
                              },
                              "name": {
                                "type": "string"
                              },
                              "folderId": {
                                "type": "string"
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "user": {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "string"
                                  },
                                  "firstName": {
                                    "type": "string"
                                  },
                                  "lastName": {
                                    "type": "string"
                                  }
                                }
                              },
                              "userId": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "get-folders": {
                    "summary": "Get folders",
                    "value": {
                      "status": "success",
                      "data": {
                        "totalCount": 93,
                        "pages": null,
                        "folders": [
                          {
                            "_id": "61e3d27bxxxx5041a7",
                            "defaultAssignTo": "",
                            "showOrder": 1,
                            "name": "AudioAudioAudioAudioAudioAudioAudioAudioAu",
                            "folderId": "905c208f1c07",
                            "createdAt": "2022-01-16T08:08:27.821Z",
                            "updatedAt": "2025-01-06T15:05:38.939Z",
                            "user": {
                              "_id": "5d03a9d5xxxx8cf89",
                              "firstName": "Vatsal",
                              "lastName": "Shah"
                            },
                            "userId": "5d03a9d5dxxxxc8cf89"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Folder"
      },
      "post": {
        "tags": [
          "Folder"
        ],
        "summary": "Create folder",
        "operationId": "folder-create-folder",
        "description": "### Create a New Folder\n\nThis endpoint allows you to create a new folder by sending an HTTP POST request to the specified URL.\n\n#### Request Body\n\n- **name** (string, required): The name of the folder to be created.\n\n\nExample:\n\n``` json\n{\n \"name\": \"Folder name 2\"\n}\n\n ```\n\n#### Response\n\n- **status** (string): The status of the request.\n\n- **data**\n\n - **folderId** (string): The ID of the newly created folder.\n\n - **message** (string): A message related to the folder creation.\n\n\nExample:\n\n``` json\n{\n \"status\": \"\",\n \"data\": {\n \"folderId\": \"\",\n \"message\": \"\"\n }\n}\n\n ```",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "folderId": {
                    "type": "string",
                    "description": "An existing folder ID. The create handler ignores this value, so you can leave it out. Optional. Empty string and null are accepted."
                  },
                  "name": {
                    "type": "string",
                    "description": "The name you want to give the folder. Leading and trailing whitespace is stripped before the folder is saved. Required. The schema declares.trim, but the validation middleware discards the schema's converted value, so the trimming you see comes from the handler itself (it calls name.trim for both the duplicate check and the saved value) and from the Folder model, which sets trim: true on name. No maximum length is enforced anywhere.",
                    "deprecated": true
                  },
                  "defaultAssignTo": {
                    "type": "string",
                    "description": "A single user ID to assign the folder to. Use assignTo instead. When you send this and omit assignTo, the server wraps the value into a one-item assignTo array. Optional. Empty string and null are accepted. The schema declares a default of an empty string, but that default never reaches the handler because the middleware throws away the schema's converted value.",
                    "deprecated": true
                  },
                  "assignTo": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The user IDs you want the folder assigned to. Optional. No cap on the number of entries. The schema declares a default of an empty array, but that default never reaches the handler. Omitting assignTo is exactly what lets defaultAssignTo take effect, because the handler checks Array.isArray(assignTo) first."
                  },
                  "description": {
                    "type": "string",
                    "description": "A short description of what the folder holds. It is saved exactly as you send it. Optional. Empty string and null are accepted. The schema declares.trim and a default of an empty string, but neither takes effect: the middleware discards the schema's converted value and the Folder model does not trim description, so leading and trailing whitespace is preserved."
                  },
                  "source": {
                    "type": "object",
                    "description": "Where the folder's content comes from. The create handler ignores this value, so it only takes effect on PUT /folder/{folderId}. Optional, and null is accepted. Accepts three optional inner keys: type (string, empty string and null allowed), subCategory (string, empty string and null allowed), and fields (array, null allowed, with no item schema declared so any entries pass). Any other inner key is rejected, including goal, which the Folder model stores but this schema does not accept."
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "Folder name 2"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "folderId": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "create-folder": {
                    "summary": "Create folder",
                    "value": {
                      "status": "success",
                      "data": {
                        "folderId": "0648e533f72c",
                        "message": "Folder name 2 folder created successfully"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Folder"
      }
    },
    "/folder/{folderId}": {
      "get": {
        "tags": [
          "Folder"
        ],
        "summary": "Get folders info",
        "operationId": "folder-get-folders-info",
        "description": "## Get Folder Details\n\nThis endpoint retrieves the details of a specific folder identified by its unique `folderId`.\n\n### Request Parameters\n\n- `folderId` (path parameter): The unique identifier of the folder you want to retrieve. This should be a valid ID corresponding to an existing folder in the system.\n\n\n### Response\n\nThe response will contain a JSON object with the following structure:\n\n- `status`: A string indicating the status of the request.\n\n- `data`: An object containing detailed information about the folder:\n\n - `_id`: The unique identifier of the folder.\n\n - `companyId`: The ID of the company associated with the folder.\n\n - `userId`: The ID of the user who owns the folder.\n\n - `folderType`: The type of folder.\n\n - `name`: The name of the folder.\n\n - `description`: A brief description of the folder.\n\n - `defaultAssignTo`: The default user assigned to the folder (can be null).\n\n - `showOrder`: An integer indicating the order in which the folder is displayed.\n\n - `userShowOrder`: An object mapping user IDs to their specific display order for the folder.\n\n - `isDeleted`: A boolean indicating whether the folder has been deleted.\n\n - `folderId`: The ID of the folder.\n\n - `createdAt`: The timestamp when the folder was created.\n\n - `updatedAt`: The timestamp when the folder was last updated.\n\n - `__v`: The version key for the document.\n\n - `source`: An object containing:\n\n - `type`: The type of source associated with the folder.\n\n - `subCategory`: The subcategory of the source.\n\n - `shared`: An array containing information about users or entities with whom the folder is shared.\n\n\n### Notes\n\n- Ensure that the `folderId` provided in the request is valid, as an invalid ID will result in an error response.\n\n- The `isDeleted` field in the response indicates whether the folder is currently active or has been marked for deletion.",
        "parameters": [
          {
            "name": "folderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "e88575b384b6"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "string"
                        },
                        "companyId": {
                          "type": "string"
                        },
                        "userId": {
                          "type": "string"
                        },
                        "folderType": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        },
                        "defaultAssignTo": {
                          "type": "string",
                          "nullable": true
                        },
                        "showOrder": {
                          "type": "integer"
                        },
                        "userShowOrder": {
                          "type": "object",
                          "properties": {
                            "5d03a9d5d4bca272e9c8cf89": {
                              "type": "integer"
                            }
                          }
                        },
                        "isDeleted": {
                          "type": "boolean"
                        },
                        "folderId": {
                          "type": "string"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "__v": {
                          "type": "integer"
                        },
                        "source": {
                          "type": "object",
                          "properties": {
                            "type": {
                              "type": "string"
                            },
                            "subCategory": {
                              "type": "string"
                            }
                          }
                        },
                        "shared": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "get-folders-info": {
                    "summary": "Get folders info",
                    "value": {
                      "status": "success",
                      "data": {
                        "_id": "6776f1459df32xxx30f8",
                        "companyId": "5e21c8ddxxxxxx2c64214816",
                        "userId": "5d03a9d5d4xxxxxc8cf89",
                        "folderType": "sub",
                        "name": "v35",
                        "description": "",
                        "defaultAssignTo": null,
                        "showOrder": 2,
                        "userShowOrder": {
                          "5d03a9d5d4bca272e9c8cf89": 2
                        },
                        "isDeleted": false,
                        "folderId": "e8857xxx4b6",
                        "createdAt": "2025-01-02T20:04:21.511Z",
                        "updatedAt": "2025-01-06T15:05:38.939Z",
                        "__v": 0,
                        "source": {
                          "type": "content",
                          "subCategory": "podcast"
                        },
                        "shared": []
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Folder"
      },
      "put": {
        "tags": [
          "Folder"
        ],
        "summary": "Update folder",
        "operationId": "folder-update-folder",
        "description": "\n## Update Folder\n\nThis endpoint allows you to update the details of a specific folder identified by its `folderId`.\n\n### Request\n\n- **Method**: `PUT`\n- **Endpoint**: `{{url}}/v1/folder/:folderId`\n- **Path Parameter**:\n - `folderId` (string): The unique identifier of the folder you wish to update.\n\n### Request Body\n\n`name` (string) is the only required field. `description`, `assignTo`, `defaultAssignTo`, and `source` are all optional \u2014 **omit a field entirely to leave its current value unchanged.** This is a partial update: only fields you actually include in the request body are written.\n\nTo explicitly clear a value instead of leaving it as-is, send it as an empty string (`description`) or an empty array (`assignTo`) \u2014 that is different from omitting the field.\n\n- `name` (string, required): The new name for the folder.\n- `description` (string, optional): Short description of the folder's contents. Omit to leave unchanged; send `\"\"` to clear.\n- `assignTo` (string[], optional): User IDs the folder is shared with. Omit (and omit `defaultAssignTo`) to leave the current sharing list unchanged; send `[]` to clear it.\n- `defaultAssignTo` (string, deprecated): Single-user convenience form of `assignTo`. Prefer `assignTo`.\n- `source` (object, optional): Where the folder's content comes from; sending it replaces the stored source.\n\n**Example Request Body** (rename only \u2014 sharing and description are left untouched):\n```json\n{\n \"name\": \"Folder name 2 Updated\"\n}\n```\n\n**Example Request Body** (rename and replace the sharing list):\n```json\n{\n \"name\": \"Folder name 2 Updated\",\n \"assignTo\": [\"64f0a1b2c3d4e5f678901234\"]\n}\n```\n\n### Response\n\nUpon a successful update, the response will be in JSON format and will include the following fields:\n\n- `status` (string): The status of the request.\n- `data` (object): Contains additional information about the update.\n - `folderId` (string): The ID of the updated folder.\n - `message` (string): A message indicating the result of the update.\n - `fields` (array): An array that may contain any relevant fields related to the update.\n\n**Example Response**:\n```json\n{\n \"status\": \"\",\n \"data\": {\n \"folderId\": \"\",\n \"message\": \"\",\n \"fields\": []\n }\n}\n```\n\n### Notes\n\nEnsure that the `folderId` in the URL is valid and that you have the necessary permissions to update the folder.\n",
        "parameters": [
          {
            "name": "folderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "0648e533f72c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "folderId": {
                    "type": "string",
                    "description": "An existing folder ID. The update handler takes the folder from the path instead, so this body value is ignored. Optional. Empty string and null are accepted."
                  },
                  "name": {
                    "type": "string",
                    "description": "The new name for the folder. Leading and trailing whitespace is stripped before it is saved. Required. The schema declares.trim, but the middleware discards the schema's converted value, so the trimming comes from the Folder model, which sets trim: true on name. No maximum length is enforced."
                  },
                  "defaultAssignTo": {
                    "type": "string",
                    "description": "A single user ID to assign the folder to. Use assignTo instead. When you send this and omit assignTo, the server wraps the value into a one-item assignTo array. Optional. Empty string and null are accepted. The schema declares a default of an empty string, but that default never reaches the handler.",
                    "deprecated": true
                  },
                  "assignTo": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The user IDs you want the folder assigned to. Sending this replaces the current assignment list. Omitting both assignTo and defaultAssignTo leaves the current assignment list unchanged \u2014 send an empty array explicitly if you want to clear it. Optional. No cap on the number of entries. The schema declares a default of an empty array, but that default never reaches the handler."
                  },
                  "description": {
                    "type": "string",
                    "description": "A short description of what the folder holds. It is saved exactly as you send it. Omitting this field entirely leaves the existing description unchanged; sending an empty string clears it. Optional. Empty string and null are accepted. The schema declares.trim and a default of an empty string, but neither takes effect, so leading and trailing whitespace is preserved."
                  },
                  "source": {
                    "type": "object",
                    "description": "Where the folder's content comes from. Sending it replaces the folder's stored source, and sending source.fields with entries also creates the matching folder fields and a new default view for the folder. Optional, and null is accepted. Accepts three optional inner keys: type (string, empty string and null allowed), subCategory (string, empty string and null allowed), and fields (array, null allowed, with no item schema declared so any entries pass). Only type and subCategory are persisted on the folder document; the Folder model's source sub-schema has no fields path, so fields is consumed to create folder fields rather than stored."
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "Folder name 2 Updated"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "folderId": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "fields": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "update-folder": {
                    "summary": "Update folder",
                    "value": {
                      "status": "success",
                      "data": {
                        "folderId": "0648e533f72c",
                        "message": "Folder name 2 Updated folder updated successfully",
                        "fields": []
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Folder"
      },
      "delete": {
        "tags": [
          "Folder"
        ],
        "summary": "Delete folder",
        "operationId": "folder-delete-folder",
        "description": "### DELETE /v1/folder/:folderId\n\nThis endpoint is used to delete a specific folder identified by the `folderId`. The deletion operation will remove the folder and all its contents from the system.\n\n#### Request Parameters\n\n- `folderId` (path parameter): The unique identifier of the folder that you wish to delete. This parameter is required.\n\n\n#### Response Structure\n\nUpon successful deletion, the response will return a JSON object with the following structure:\n\n- `status`: A string indicating the status of the operation (e.g., success or failure).\n\n- `message`: A string providing additional information about the result of the deletion operation.\n\n\n#### Example Response\n\n``` json\n{\n \"status\": \"success\",\n \"message\": \"Folder deleted successfully.\"\n}\n\n ```\n\nIn case of an error, the response may contain an appropriate error message indicating what went wrong.",
        "parameters": [
          {
            "name": "folderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "0648e533f72c"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "delete-folder": {
                    "summary": "Delete folder",
                    "value": {
                      "status": "success",
                      "message": "Folder successfully deleted."
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Folder"
      }
    },
    "/folder/clone": {
      "post": {
        "tags": [
          "Folder"
        ],
        "summary": "Clone Folder",
        "operationId": "folder-clone-folder",
        "description": "### Clone Folder\n\nThis endpoint allows the user to clone a folder by making an HTTP POST request to the specified URL.\n\n#### Request Body\n\n- `folderId` (string) - The ID of the folder to be cloned.\n\n- `name` (string) - The name of the new folder.\n\n- `description` (string) - The description of the new folder.\n\n- `defaultAssignTo` (string) - The default assignee for the new folder.\n\n- `isSaveDefaultView` (boolean) - Indicates whether the default view should be saved.\n\n\n#### Response\n\nThe response of this request is a JSON object with the following schema:\n\n``` json\n{\n \"type\": \"object\",\n \"properties\": {\n \"status\": {\n \"type\": \"string\"\n },\n \"data\": {\n \"type\": \"object\",\n \"properties\": {\n \"folderId\": {\n \"type\": \"string\"\n },\n \"message\": {\n \"type\": \"string\"\n }\n }\n }\n }\n}\n\n ```\n\n#### Example Response\n\n``` json\n{\n \"status\": \"\",\n \"data\": {\n \"folderId\": \"\",\n \"message\": \"\"\n }\n}\n\n ```",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "folderId": {
                    "type": "string",
                    "description": "The ID of the folder you want to copy. Required. Empty string and null are not accepted."
                  },
                  "name": {
                    "type": "string",
                    "description": "The name for the new copy. Leave it out and the server names the copy \"<original folder name> (Clone)\". Optional. Empty string and null are accepted. An empty string is treated as absent by the handler, because it falls back on a falsy check."
                  },
                  "description": {
                    "type": "string",
                    "description": "A description for the new copy. Leave it out and the original folder's description is carried over, falling back to an empty string. Optional. Empty string and null are accepted. An empty string is treated as absent by the handler, because it falls back on a falsy check."
                  },
                  "defaultAssignTo": {
                    "type": "string",
                    "description": "A single user ID to assign the copy to. Use assignTo instead. When you send this and omit assignTo, the server wraps the value into a one-item assignTo array. Optional. Empty string and null are accepted. No default is declared.",
                    "deprecated": true
                  },
                  "assignTo": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The user IDs you want the new copy assigned to. The copy does not inherit the original folder's assignment list, so send this if you want the assignment carried over. Optional. No cap on the number of entries. The schema declares a default of an empty array, but that default never reaches the handler; omitting assignTo is what lets defaultAssignTo take effect."
                  },
                  "isSaveDefaultView": {
                    "type": "boolean",
                    "description": "Whether to copy the source folder's default view onto the new folder. Send true explicitly if you want the view copied. Optional. The schema declares a default of true, but the middleware discards the schema's converted value, so an omitted isSaveDefaultView reaches the handler as undefined and the default view is not copied. There is no model-level default to fall back on here, because the flag only gates a branch in the handler."
                  }
                },
                "required": [
                  "folderId"
                ]
              },
              "example": {
                "folderId": "905c208f1c07",
                "name": "New Folder Name",
                "description": "New Folder description",
                "defaultAssignTo": "",
                "isSaveDefaultView": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "folderId": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "create-folder": {
                    "summary": "Create folder",
                    "value": {
                      "status": "success",
                      "data": {
                        "folderId": "0648e533f72c",
                        "message": "Folder name 2 folder created successfully"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Folder"
      }
    },
    "/recorder/status/{token}": {
      "get": {
        "tags": [
          "Recorder/Survey"
        ],
        "summary": "Check Recorder Status",
        "operationId": "recorder-survey-check-recorder-status",
        "description": "Reveals whether recorder is publically open or password-protected",
        "x-speak-group": "Recorder Embed",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "recorder-9"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "isSecure": {
                          "type": "boolean",
                          "description": "True when the recorder is password-protected, so the page must collect a password and call POST /v1/recorder/verify before recording. False when the recorder is open to anyone with the link."
                        },
                        "email": {
                          "type": "string",
                          "description": "Email address of the user who owns the recorder."
                        },
                        "userId": {
                          "type": "string",
                          "description": "Id of the user who owns the recorder."
                        },
                        "companyId": {
                          "type": "string",
                          "description": "Id of the company the recorder belongs to."
                        },
                        "isExpired": {
                          "type": "boolean",
                          "description": "Carries the recorder's disabled flag. It is always false on a 200, because a disabled recorder returns 404 with 'Embedded Recorder is disabled!' before the payload is built."
                        },
                        "name": {
                          "type": "string",
                          "description": "Recorder name, shown as the heading on the recording page unless the recorder hides the title."
                        },
                        "description": {
                          "type": "string",
                          "description": "Recorder description, shown under the heading unless the recorder hides the description."
                        },
                        "bucketId": {
                          "type": "string",
                          "description": "Storage bucket the recording is uploaded to. It comes from the company's subscription and falls back to speakai-storage-us-east-1 when the subscription does not name one."
                        },
                        "meta": {
                          "type": "object",
                          "description": "Branding and capture settings for the recording page. It carries the recorder's own meta, with primaryColor, logo, backgroundImg and fontFamily falling back to the company's branding when the recorder leaves them empty, customCSS sanitized before it is returned, hideImages defaulting to false, and isFooter from the subscription's recorder features. isFooter true renders the Speak footer at the bottom of the recording page, and is false for accounts whose plan includes recorder customization. S3 logo and background URLs are rewritten to their CloudFront address."
                        },
                        "minDuration": {
                          "type": "integer",
                          "description": "Shortest recording the recorder accepts, in seconds."
                        },
                        "maxDuration": {
                          "type": "integer",
                          "description": "Longest recording the recorder accepts, in seconds."
                        },
                        "sourceLanguage": {
                          "type": "string",
                          "description": "Transcription language code the recorder is set to, such as en-US, or multi for a recorder that expects more than one language in the same recording. Open the live transcription socket with this value: a client that assumes en-US instead drops the sentences spoken in the recorder's other languages."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "check-recorder-status": {
                    "summary": "Check Recorder Status",
                    "value": {
                      "status": "success",
                      "data": {
                        "isSecure": false,
                        "email": "demo@example.com",
                        "userId": "66f0a1b2c3d4e5f60718293a",
                        "companyId": "66f0a1b2c3d4e5f60718293b",
                        "isExpired": false,
                        "name": "Customer feedback recorder",
                        "description": "Tell us how the call went.",
                        "bucketId": "speakai-storage-ca-central-1",
                        "meta": {
                          "logo": "",
                          "backgroundImg": "",
                          "primaryColor": "#4338ca",
                          "fontFamily": "Lato",
                          "customCSS": "",
                          "hideImages": false,
                          "isFooter": true
                        },
                        "minDuration": 15,
                        "maxDuration": 7200,
                        "sourceLanguage": "en-US"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "404": {
                    "summary": "404",
                    "value": {
                      "status": "failed",
                      "requestId": "eb3e08b0-3d91-47e1-81bc-8432f76be977",
                      "code": 404,
                      "message": "Recorder not found!",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/recorder/verify": {
      "post": {
        "tags": [
          "Recorder/Survey"
        ],
        "summary": "Verify Password",
        "operationId": "recorder-survey-verify-password",
        "description": "User to grant\\prohobit access to a password-protected recorder",
        "x-speak-group": "Recorder Embed",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "Pass the recorder's embed token, the same token that appears in the public recorder URL. Required. An empty string is rejected. A token that matches no recorder returns 404 with 'Recorder not found!'."
                  },
                  "password": {
                    "type": "string",
                    "description": "Pass the password a viewer typed so Speak can check it against the recorder. Required. An empty string is rejected. Unlike most string fields on the recorder endpoints this one is a plain the schema with no.trim, so leading and trailing spaces are compared as typed."
                  }
                },
                "required": [
                  "token",
                  "password"
                ]
              },
              "example": {
                "token": "token",
                "password": "123"
              }
            }
          }
        },
        "responses": {
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "404": {
                    "summary": "404",
                    "value": {
                      "status": "failed",
                      "requestId": "32732927-3809-4973-a82b-82663013d36f",
                      "code": 404,
                      "message": "Recorder not found!",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/recorder/create": {
      "post": {
        "tags": [
          "Recorder/Survey"
        ],
        "summary": "Create Recorder",
        "operationId": "recorder-survey-create-recorder",
        "description": "**Create a recorder and integrate with your platform easily.**\n\n**All the required fields are as below:**\n\n`name` - Name of the recorder\n\nAll the other fields are optional. Your recorder will be created automatically.\n\n`description` - Assign description of the recorder for internal purpose.\n\n`folderId` - Save all your recordings to the assigned FolderId.\n\n---\n\n**Duration of the recorder:**\n\n- `minDuration` - 15 seconds (min) & 5 min (max)\n - Pass the duration in **seconds**\n\n- `maxDuration` - 10 seconds (min) & 3 hours (max)\n - Pass the duration in seconds\n\n\n---\n\n**Source Language:**\n\n- You can pass the `sourceLanguage` as a code.\n\n- Other language codes available at the top of the page.\n\n\n---\n\n**Recorder options:**\n\n- We allow to support creating recorder with the multiple options such as:\n - `audio` - Audio recorder\n\n - `video` - Video recorder\n\n - `screeShare` - Allow to screen share on browser (Mobile not supported)\n\n - `uploadFile` - Allow to upload various file formats\n - `allowMultiple` - Supporting multiple file uploads\n\n\n---\n\n**Notifications:**\n\n`upload` - Recieve an email notification when anyone uploads a recording on the recorder\n\n`client` - When your user submits a recording (have the email address in a form) - they will receive an submittion email\n\n---\n\n**Client Information Questions:**\n\n`name` - Ask for their name\n\n`email` - Ask for their email address\n\n`questions` - Check an API endpoint to update different types of questions.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name the recorder. This is the only field you have to send. Required. An empty or whitespace-only value is rejected because the validator is the schema.trim with no.allow(''). The value is stored exactly as you send it, including any surrounding whitespace."
                  },
                  "description": {
                    "type": "string",
                    "description": "Describe the recorder for your own reference. Optional. An empty string is allowed."
                  },
                  "isAutoAnalyze": {
                    "type": "boolean",
                    "description": "Analyze each recording automatically as soon as it is submitted. Optional. If you leave it out, the recorder is saved with automatic analysis on, which is the default on the Recorder model."
                  },
                  "sourceLanguage": {
                    "type": "string",
                    "description": "Set the spoken language Speak transcribes recordings in. Optional. Must be one of the transcription language codes the server compiles at start up from the static list (137 entries, including auto and multi). An unrecognized code returns 400 with the message 'sourceLanguage must be a valid transcription language code'. GET /v1/media/supportedLanguages returns the list the server is currently serving, which can be refreshed from the database at runtime while the accepted set for this field stays as it was at start up, so the two can drift. If you leave the field out, the recorder is saved with en-US."
                  },
                  "folderId": {
                    "type": "string",
                    "description": "Save every recording from this recorder into the folder you name here. Optional. An empty string is allowed and is the only value that makes Speak pick your first folder. Leaving the field out is not the same: the recorder is saved with an empty folderId instead. A folderId that does not exist in your company returns 400 with 'Folder not found'."
                  },
                  "duration": {
                    "type": "object",
                    "description": "Set how long a recording is allowed to run. Optional. Two optional number keys, both in seconds. minDuration accepts 0 to 300, maxDuration accepts 15 to 10800. The create handler applies 15 and 300 when you leave the object or either key out."
                  },
                  "notification": {
                    "type": "object",
                    "description": "Choose who gets an email when a recording comes in. Optional. Two optional booleans, both treated as true when you leave them out. upload emails the users in notifyUsers when a recording arrives. client emails the respondent a confirmation, and only fires when they gave an email address."
                  },
                  "options": {
                    "type": "object",
                    "description": "Turn the individual capture and upload modes on or off. Optional. Keys are all optional booleans unless noted: audio (true when omitted), video (true), screenShare (true), liveTranscription (false, also accepts null), and upload, a nested object with file (true), text (false), multiple (false) and url (true). The create handler applies those fallbacks."
                  },
                  "notifyUsers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "List the user IDs that get emailed when a recording arrives. Optional. Each item is a non-empty string. Stored under the recorder's notification block and used only when notification.upload is on."
                  },
                  "clientInformation": {
                    "type": "object",
                    "description": "Decide what you ask a respondent for before they record. Optional. Reuses the updateQuestions schema at:33-46. Keys: name (boolean, true when omitted), email (boolean, true when omitted), questions (array, items unconstrained), and consent, a nested object with isEnabled (boolean, false), title (string, empty allowed), description (string, empty allowed), yesButtonLabel (string, 'Yes'), noButtonLabel (string, 'No'), isRequired (boolean, false) and fieldId (string, empty allowed, ''). The whole object is stored as sent."
                  },
                  "meta": {
                    "type": "object",
                    "description": "Customize the recorder page. On create, only the layout fields below take effect. Optional. The create handler reads only customCSS, hideWaveform, hideTitle, hideDescription, hideSubmitButton, submitButtonLabel, countdown and hideImages. customCSS is capped at 50000 characters and is run through a CSS sanitizer before it is stored; when you leave it out or send an empty string, the company's stored customCSS is used. The booleans are false when omitted and submitButtonLabel is 'Upload' when omitted. primaryColor, backgroundImg, logo, fontColor, fontFamily and theme are accepted by the validator but ignored on create: a new recorder always inherits those six from your company branding. Use PUT /recorder/settings/{recorderId} to change them."
                  },
                  "assignTo": {
                    "type": "string",
                    "description": "Accepted by the request validator but never used. Optional, empty string allowed. The create handler never reads this field and nothing in the recorder module references it, so sending it has no effect."
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "Speak test 1",
                "description": "Speak recorder description",
                "folderId": "0648e533f72c",
                "sourceLanguage": "en-US",
                "duration": {
                  "minDuration": 120,
                  "maxDuration": 300
                },
                "options": {
                  "audio": true,
                  "video": true,
                  "screenShare": true,
                  "upload": {
                    "file": false,
                    "text": true,
                    "multiple": true,
                    "url": false
                  }
                },
                "notification": {
                  "upload": true,
                  "client": false
                },
                "clientInformation": {
                  "name": true,
                  "email": true,
                  "questions": []
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "recorderData": {
                          "type": "object",
                          "properties": {
                            "notification": {
                              "type": "object",
                              "properties": {
                                "upload": {
                                  "type": "boolean"
                                },
                                "client": {
                                  "type": "boolean"
                                }
                              }
                            },
                            "recordings": {
                              "type": "array",
                              "items": {}
                            },
                            "minDuration": {
                              "type": "integer"
                            },
                            "maxDuration": {
                              "type": "integer"
                            },
                            "privacyMode": {
                              "type": "string"
                            },
                            "password": {
                              "type": "string"
                            },
                            "isAutoAnalyze": {
                              "type": "boolean"
                            },
                            "assignTo": {
                              "type": "string"
                            },
                            "folderId": {
                              "type": "string"
                            },
                            "sourceLanguage": {
                              "type": "string"
                            },
                            "isActive": {
                              "type": "boolean"
                            },
                            "isDisabled": {
                              "type": "boolean"
                            },
                            "isDeleted": {
                              "type": "boolean"
                            },
                            "_id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "description": {
                              "type": "string"
                            },
                            "companyId": {
                              "type": "string"
                            },
                            "userId": {
                              "type": "string"
                            },
                            "recorderId": {
                              "type": "string"
                            },
                            "token": {
                              "type": "string"
                            },
                            "meta": {
                              "type": "object",
                              "properties": {
                                "backgroundImg": {
                                  "type": "string"
                                },
                                "logo": {
                                  "type": "string"
                                },
                                "primaryColor": {
                                  "type": "string"
                                },
                                "type": {
                                  "type": "object",
                                  "properties": {
                                    "audio": {
                                      "type": "boolean"
                                    },
                                    "video": {
                                      "type": "boolean"
                                    },
                                    "screenShare": {
                                      "type": "boolean"
                                    },
                                    "upload": {
                                      "type": "object",
                                      "properties": {
                                        "file": {
                                          "type": "boolean"
                                        },
                                        "multiple": {
                                          "type": "boolean"
                                        },
                                        "text": {
                                          "type": "boolean"
                                        }
                                      }
                                    }
                                  }
                                },
                                "client": {
                                  "type": "object",
                                  "properties": {
                                    "name": {
                                      "type": "boolean"
                                    },
                                    "email": {
                                      "type": "boolean"
                                    },
                                    "questions": {
                                      "type": "array",
                                      "items": {}
                                    }
                                  }
                                }
                              }
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "__v": {
                              "type": "integer"
                            }
                          }
                        },
                        "recorderId": {
                          "type": "string"
                        },
                        "token": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "create-recorder": {
                    "summary": "Create Recorder",
                    "value": {
                      "status": "success",
                      "data": {
                        "recorderData": {
                          "notification": {
                            "upload": true,
                            "client": false
                          },
                          "recordings": [],
                          "minDuration": 120,
                          "maxDuration": 300,
                          "privacyMode": "public",
                          "password": "",
                          "isAutoAnalyze": true,
                          "assignTo": "",
                          "folderId": "",
                          "sourceLanguage": "en-US",
                          "isActive": true,
                          "isDisabled": false,
                          "isDeleted": false,
                          "_id": "640f5c18a33c35424caa86fc",
                          "name": "Speak test",
                          "description": "Speak recorder description",
                          "companyId": "5e21c8dd2d77242c64214816",
                          "userId": "5d03a9d5d4bca272e9c8cf89",
                          "recorderId": "3a1c8f68f2de",
                          "token": "speak-test-5b87d2c2d21e",
                          "meta": {
                            "backgroundImg": "https://speakai-storage.s3.amazonaws.com/backgroundImg/prod/5d03a9d5d4bca272e9c8cf89/1649768360045-blob",
                            "logo": "https://speakai-storage.s3.amazonaws.com/logo/prod/5d03a9d5d4bca272e9c8cf89/1649768327203-Speak---Rectange-Logo---Black---5000px-Wide.png",
                            "primaryColor": "#000000",
                            "type": {
                              "audio": true,
                              "video": true,
                              "screenShare": true,
                              "upload": {
                                "file": true,
                                "multiple": false,
                                "text": true
                              }
                            },
                            "client": {
                              "name": true,
                              "email": true,
                              "questions": []
                            }
                          },
                          "createdAt": "2023-03-13T17:23:36.374Z",
                          "updatedAt": "2023-03-13T17:23:36.374Z",
                          "__v": 0
                        },
                        "recorderId": "3a1c8f68f2de",
                        "token": "speak-test-5b87d2c2d21e"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/recorder": {
      "get": {
        "tags": [
          "Recorder/Survey"
        ],
        "summary": "Recorder List",
        "operationId": "recorder-survey-recorder-list",
        "description": "## API Endpoint: Retrieve Recorders\n\nThis endpoint retrieves a list of recorders with pagination and sorting options. It allows users to fetch details about available recorders based on specified parameters.\n\n### Request\n\n**Method:** GET\n**URL:** `{{url}}/v1/recorder`\n\n**Query Parameters:**\n\n- `page` (integer): The page number of the results to retrieve. Default is `0`.\n\n- `pageSize` (integer): The number of records to return per page. Default is `20`.\n\n- `sortBy` (string): The field by which to sort the results, followed by the sorting order. For example, `createdAt:desc` sorts by the creation date in descending order.\n\n\n### Response\n\nThe response will contain a JSON object with the following structure:\n\n- `status` (string): The status of the request.\n\n- `data` (object): Contains the results of the request.\n\n - `totalCount` (integer): The total number of recorders available.\n\n - `page` (integer): The current page number of the results.\n\n - `recorderList` (array): A list of recorder objects, each containing:\n\n - `duration` (integer): The duration of the recording.\n\n - `isAutoAnalyze` (boolean): Indicates if the recorder is set for automatic analysis.\n\n - `isActive` (boolean): Indicates if the recorder is currently active.\n\n - `recordings` (array): An array of recordings associated with the recorder.\n\n - `createdAt` (string): The timestamp when the recorder was created.\n\n - `updatedAt` (string): The timestamp when the recorder was last updated.\n\n - `userId` (string): The ID of the user associated with the recorder.\n\n - `recorderId` (string): The unique ID of the recorder.\n\n - `token` (string): A token associated with the recorder.\n\n - `name` (string): The name of the recorder.\n\n - `meta` (object): Metadata about the recorder, including:\n\n - `type` (object): Specifies the types of media supported (e.g., video and audio).\n\n - `client` (object): Information about the client, including name and email.\n\n\n### Example Response\n\n``` json\n{\n \"status\": \"\",\n \"data\": {\n \"totalCount\": 0,\n \"page\": \"\",\n \"recorderList\": [\n {\n \"duration\": 0,\n \"isAutoAnalyze\": true,\n \"isActive\": true,\n \"recordings\": [],\n \"createdAt\": \"\",\n \"updatedAt\": \"\",\n \"userId\": \"\",\n \"recorderId\": \"\",\n \"token\": \"\",\n \"name\": \"\",\n \"meta\": {\n \"type\": {\n \"video\": true,\n \"audio\": true\n },\n \"client\": {\n \"name\": true,\n \"email\": true\n }\n }\n }\n ]\n }\n}\n\n ```",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "example": "0"
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "example": "20"
          },
          {
            "name": "filterName",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "recorder",
            "x-postman-disabled": true
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "createdAt:desc"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "totalCount": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "string"
                        },
                        "recorderList": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "duration": {
                                "type": "integer"
                              },
                              "isAutoAnalyze": {
                                "type": "boolean"
                              },
                              "isActive": {
                                "type": "boolean"
                              },
                              "recordings": {
                                "type": "array",
                                "items": {}
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "userId": {
                                "type": "string"
                              },
                              "recorderId": {
                                "type": "string"
                              },
                              "token": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "meta": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "object",
                                    "properties": {
                                      "video": {
                                        "type": "boolean"
                                      },
                                      "audio": {
                                        "type": "boolean"
                                      }
                                    }
                                  },
                                  "client": {
                                    "type": "object",
                                    "properties": {
                                      "name": {
                                        "type": "boolean"
                                      },
                                      "email": {
                                        "type": "boolean"
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "200": {
                    "summary": "200",
                    "value": {
                      "status": "success",
                      "data": {
                        "totalCount": 1,
                        "page": "1",
                        "recorderList": [
                          {
                            "duration": 120,
                            "isAutoAnalyze": false,
                            "isActive": true,
                            "recordings": [],
                            "createdAt": "2020-12-15T14:02:21.615Z",
                            "updatedAt": "2020-12-15T14:02:21.616Z",
                            "userId": "5d03a9d5d4bca272e9c8cf89",
                            "recorderId": "70ea4d569736",
                            "token": "recorder-9-4fb7713e267a",
                            "name": "recorder-9",
                            "meta": {
                              "type": {
                                "video": false,
                                "audio": true
                              },
                              "client": {
                                "name": false,
                                "email": false
                              }
                            }
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/recorder/clone": {
      "post": {
        "tags": [
          "Recorder/Survey"
        ],
        "summary": "Clone Recorder",
        "operationId": "recorder-survey-clone-recorder",
        "description": "**Clone Recorder to copy all the settings from the existing recorders**\n\n**All the required fields are as below:**\n\n`recorderId` - Pass the recorderId from the existing recorder\n\n**Optional:**\n\n`name` - New name for the recorder. If not pass, it will take the existing recorder name and add `(clone)` to the new recorder\n\n`description` - New description for the recorder. If not pass, it will take the existing recorder description as is.\n\n`folderId` - IMPORTANT! We recommend to pass the `folderId` to ensure the recordings save in the specific folder. If not pass, it will take the existing recorder folderId setting.\n\n---\n\nIf you need to change any other settings, we recommend to use the `Create Recorder` API call.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "recorderId": {
                    "type": "string",
                    "description": "Name the recorder you want to copy. Required. An empty or whitespace-only value is rejected. A recorderId that matches no recorder returns 404 with 'Recorder not found'."
                  },
                  "name": {
                    "type": "string",
                    "description": "Name the copy. Optional, empty string allowed. If you leave it out or send an empty string, the copy is named after the source recorder with ' (Clone)' appended."
                  },
                  "description": {
                    "type": "string",
                    "description": "Describe the copy. Optional, empty string allowed. If you leave it out or send an empty string, the copy inherits the source recorder's description."
                  },
                  "folderId": {
                    "type": "string",
                    "description": "Put the copy in this folder. Optional, empty string allowed. If you leave it out or send an empty string, the copy stays in the source recorder's folder. A folderId that matches no folder returns 404 with 'Folder not found. Please create or select a valid folder Id.'"
                  }
                },
                "required": [
                  "recorderId"
                ]
              },
              "example": {
                "recorderId": "ce8f9465763c",
                "name": "Speak Clone test"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "recorderData": {
                          "type": "object",
                          "properties": {
                            "notification": {
                              "type": "object",
                              "properties": {
                                "upload": {
                                  "type": "boolean"
                                },
                                "client": {
                                  "type": "boolean"
                                }
                              }
                            },
                            "recordings": {
                              "type": "array",
                              "items": {}
                            },
                            "minDuration": {
                              "type": "integer"
                            },
                            "maxDuration": {
                              "type": "integer"
                            },
                            "privacyMode": {
                              "type": "string"
                            },
                            "password": {
                              "type": "string"
                            },
                            "isAutoAnalyze": {
                              "type": "boolean"
                            },
                            "assignTo": {
                              "type": "string"
                            },
                            "folderId": {
                              "type": "string"
                            },
                            "sourceLanguage": {
                              "type": "string"
                            },
                            "isActive": {
                              "type": "boolean"
                            },
                            "isDisabled": {
                              "type": "boolean"
                            },
                            "isDeleted": {
                              "type": "boolean"
                            },
                            "_id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "description": {
                              "type": "string"
                            },
                            "companyId": {
                              "type": "string"
                            },
                            "userId": {
                              "type": "string"
                            },
                            "recorderId": {
                              "type": "string"
                            },
                            "token": {
                              "type": "string"
                            },
                            "meta": {
                              "type": "object",
                              "properties": {
                                "backgroundImg": {
                                  "type": "string"
                                },
                                "logo": {
                                  "type": "string"
                                },
                                "primaryColor": {
                                  "type": "string"
                                },
                                "type": {
                                  "type": "object",
                                  "properties": {
                                    "audio": {
                                      "type": "boolean"
                                    },
                                    "video": {
                                      "type": "boolean"
                                    },
                                    "screenShare": {
                                      "type": "boolean"
                                    },
                                    "upload": {
                                      "type": "object",
                                      "properties": {
                                        "file": {
                                          "type": "boolean"
                                        },
                                        "multiple": {
                                          "type": "boolean"
                                        },
                                        "text": {
                                          "type": "boolean"
                                        }
                                      }
                                    }
                                  }
                                },
                                "client": {
                                  "type": "object",
                                  "properties": {
                                    "name": {
                                      "type": "boolean"
                                    },
                                    "email": {
                                      "type": "boolean"
                                    },
                                    "questions": {
                                      "type": "array",
                                      "items": {}
                                    }
                                  }
                                }
                              }
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "__v": {
                              "type": "integer"
                            }
                          }
                        },
                        "recorderId": {
                          "type": "string"
                        },
                        "token": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "clone-recorder": {
                    "summary": "Clone Recorder",
                    "value": {
                      "status": "success",
                      "data": {
                        "recorderData": {
                          "notification": {
                            "upload": true,
                            "client": false
                          },
                          "recordings": [],
                          "minDuration": 120,
                          "maxDuration": 300,
                          "privacyMode": "public",
                          "password": "",
                          "isAutoAnalyze": true,
                          "assignTo": "",
                          "folderId": "",
                          "sourceLanguage": "en-US",
                          "isActive": true,
                          "isDisabled": false,
                          "isDeleted": false,
                          "_id": "640f5c18a33c35424caa86fc",
                          "name": "Speak test",
                          "description": "Speak recorder description",
                          "companyId": "5e21c8dd2d77242c64214816",
                          "userId": "5d03a9d5d4bca272e9c8cf89",
                          "recorderId": "3a1c8f68f2de",
                          "token": "speak-test-5b87d2c2d21e",
                          "meta": {
                            "backgroundImg": "https://speakai-storage.s3.amazonaws.com/backgroundImg/prod/5d03a9d5d4bca272e9c8cf89/1649768360045-blob",
                            "logo": "https://speakai-storage.s3.amazonaws.com/logo/prod/5d03a9d5d4bca272e9c8cf89/1649768327203-Speak---Rectange-Logo---Black---5000px-Wide.png",
                            "primaryColor": "#000000",
                            "type": {
                              "audio": true,
                              "video": true,
                              "screenShare": true,
                              "upload": {
                                "file": true,
                                "multiple": false,
                                "text": true
                              }
                            },
                            "client": {
                              "name": true,
                              "email": true,
                              "questions": []
                            }
                          },
                          "createdAt": "2023-03-13T17:23:36.374Z",
                          "updatedAt": "2023-03-13T17:23:36.374Z",
                          "__v": 0
                        },
                        "recorderId": "3a1c8f68f2de",
                        "token": "speak-test-5b87d2c2d21e"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/recorder/{recorderId}": {
      "get": {
        "tags": [
          "Recorder/Survey"
        ],
        "summary": "Recorder info",
        "operationId": "recorder-survey-recorder-info",
        "description": "### API Endpoint: Get Recorder Details\n\n**Method:** GET\n**Endpoint:** `{{url}}/v1/recorder/:recorderId`\n\nThis endpoint retrieves detailed information about a specific recorder identified by the `recorderId`. The response includes various attributes related to the recorder, such as its name, description, user information, recording settings, privacy options, and metadata.\n\n#### Response Structure:\n\n- **status**: Status of the request.\n\n- **data**: Contains the details of the recorder:\n\n - **recorderId**: Unique identifier for the recorder.\n\n - **userId**: Identifier for the user associated with the recorder.\n\n - **name**: Name of the recorder.\n\n - **description**: Description of the recorder.\n\n - **token**: Authentication token for the recorder.\n\n - **recordings**: Array of recordings associated with the recorder.\n\n - **minDuration**: Minimum duration for recordings.\n\n - **maxDuration**: Maximum duration for recordings.\n\n - **privacyMode**: Privacy settings for the recorder.\n\n - **password**: Password for accessing the recorder, if applicable.\n\n - **isAutoAnalyze**: Indicates if automatic analysis is enabled.\n\n - **assignTo**: User or entity to which the recorder is assigned.\n\n - **folderId**: Identifier for the folder containing the recorder.\n\n - **sourceLanguage**: Language settings for the recorder.\n\n - **meta**: Metadata related to the recorder, including:\n\n - **backgroundImg**: Background image URL.\n\n - **logo**: Logo URL.\n\n - **primaryColor**: Primary color used in the recorder interface.\n\n - **type**: Supported types of recordings (audio, video, screen share, etc.).\n\n - **client**: Client-related information including name, email, and questions.\n\n - **callToActionButtons**: Action buttons associated with the recorder.\n\n - **notification**: Notification settings for the recorder.\n\n - **isActive**: Indicates if the recorder is currently active.\n\n - **createdAt**: Timestamp of when the recorder was created.\n\n - **updatedAt**: Timestamp of when the recorder was last updated.\n\n - **domain**: Domain associated with the recorder.",
        "parameters": [
          {
            "name": "recorderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "recorderId": {
                          "type": "string"
                        },
                        "userId": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        },
                        "token": {
                          "type": "string"
                        },
                        "recordings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "minDuration": {
                          "type": "integer"
                        },
                        "maxDuration": {
                          "type": "integer"
                        },
                        "privacyMode": {
                          "type": "string"
                        },
                        "password": {
                          "type": "string"
                        },
                        "isAutoAnalyze": {
                          "type": "boolean"
                        },
                        "assignTo": {
                          "type": "string"
                        },
                        "folderId": {
                          "type": "string"
                        },
                        "sourceLanguage": {
                          "type": "string"
                        },
                        "meta": {
                          "type": "object",
                          "properties": {
                            "backgroundImg": {
                              "type": "string"
                            },
                            "logo": {
                              "type": "string"
                            },
                            "primaryColor": {
                              "type": "string"
                            },
                            "type": {
                              "type": "object",
                              "properties": {
                                "audio": {
                                  "type": "boolean"
                                },
                                "video": {
                                  "type": "boolean"
                                },
                                "screenShare": {
                                  "type": "boolean"
                                },
                                "upload": {
                                  "type": "object",
                                  "properties": {
                                    "file": {
                                      "type": "boolean"
                                    },
                                    "url": {
                                      "type": "boolean"
                                    },
                                    "multiple": {
                                      "type": "boolean"
                                    },
                                    "text": {
                                      "type": "string",
                                      "nullable": true
                                    }
                                  }
                                }
                              }
                            },
                            "client": {
                              "type": "object",
                              "properties": {
                                "name": {
                                  "type": "boolean"
                                },
                                "email": {
                                  "type": "boolean"
                                },
                                "questions": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "id": {
                                        "type": "string"
                                      },
                                      "question": {
                                        "type": "string"
                                      },
                                      "isRequired": {
                                        "type": "boolean"
                                      },
                                      "answerType": {
                                        "type": "string"
                                      },
                                      "options": {
                                        "type": "array",
                                        "items": {}
                                      },
                                      "includeOther": {
                                        "type": "boolean"
                                      },
                                      "fieldId": {
                                        "type": "string"
                                      },
                                      "_id": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "callToActionButtons": {
                              "type": "array",
                              "items": {}
                            }
                          }
                        },
                        "notification": {
                          "type": "object",
                          "properties": {
                            "client": {
                              "type": "boolean"
                            },
                            "upload": {
                              "type": "boolean"
                            },
                            "notifyUsers": {
                              "type": "array",
                              "items": {}
                            }
                          }
                        },
                        "isActive": {
                          "type": "boolean"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "domain": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "recorder-info": {
                    "summary": "Recorder info",
                    "value": {
                      "status": "success",
                      "data": {
                        "recorderId": "2f93b3d68937",
                        "userId": "5d03a9d5d4bca272e9c8cf89",
                        "name": "Recorder Mon Jun 24 2024",
                        "description": "",
                        "token": "recorder-mon-jun-24-2024-a3535823b1a8",
                        "recordings": [
                          "667c643820f2e801e047953c"
                        ],
                        "minDuration": 15,
                        "maxDuration": 300,
                        "privacyMode": "public",
                        "password": "",
                        "isAutoAnalyze": true,
                        "assignTo": "",
                        "folderId": "f89a9eac1b62",
                        "sourceLanguage": "en-AU",
                        "meta": {
                          "backgroundImg": "",
                          "logo": "",
                          "primaryColor": "#c42860",
                          "type": {
                            "audio": true,
                            "video": true,
                            "screenShare": false,
                            "upload": {
                              "file": true,
                              "url": true,
                              "multiple": false,
                              "text": null
                            }
                          },
                          "client": {
                            "name": false,
                            "email": false,
                            "questions": [
                              {
                                "id": "41db9890bab9",
                                "question": "test question",
                                "isRequired": true,
                                "answerType": "single",
                                "options": [],
                                "includeOther": false,
                                "fieldId": "",
                                "_id": "66bd01f4507d676698028770"
                              }
                            ]
                          },
                          "callToActionButtons": []
                        },
                        "notification": {
                          "client": true,
                          "upload": true,
                          "notifyUsers": []
                        },
                        "isActive": true,
                        "createdAt": "2024-06-24T15:05:41.703Z",
                        "updatedAt": "2024-06-24T15:05:41.703Z",
                        "domain": ""
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Recorder/Survey"
        ],
        "summary": "Delete Recorder",
        "operationId": "recorder-survey-delete-recorder",
        "description": "## DELETE /v1/recorder/:recorderId\n\nThis endpoint allows clients to delete a specific recorder resource identified by the `recorderId`.\n\n### Parameters\n\n- **recorderId** (path parameter): The unique identifier of the recorder that you wish to delete. This parameter is required.\n\n\n### Response\n\nUpon successful deletion, the server will respond with a confirmation message indicating the result of the operation. The structure of the response will typically include:\n\n- A status code indicating the success or failure of the operation.\n\n- A message providing additional context about the deletion.\n\n\nEnsure that the `recorderId` provided corresponds to an existing recorder, as attempting to delete a non-existent recorder may result in an error response.",
        "parameters": [
          {
            "name": "recorderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "404": {
                    "summary": "404",
                    "value": {
                      "status": "failed",
                      "requestId": "8389bb88-ad28-4210-a72b-b9326e51d9cd",
                      "code": 404,
                      "message": "Recorder Note not found!",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/recorder/recordings/{recorderId}": {
      "get": {
        "tags": [
          "Recorder/Survey"
        ],
        "summary": "Recording Details",
        "operationId": "recorder-survey-recording-details",
        "description": "Get Recording meta details such as:\n\n* Name\n* Email\n* Other asked questions",
        "parameters": [
          {
            "name": "recorderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "totalCount": {
                          "type": "integer"
                        },
                        "recordings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string"
                              },
                              "recorderId": {
                                "type": "string"
                              },
                              "mediaId": {
                                "type": "object",
                                "properties": {
                                  "_id": {
                                    "type": "string"
                                  },
                                  "folderId": {
                                    "type": "string"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  },
                                  "tags": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "state": {
                                    "type": "string"
                                  },
                                  "duration": {
                                    "type": "object",
                                    "properties": {
                                      "inSecond": {
                                        "type": "integer"
                                      },
                                      "end": {
                                        "type": "string"
                                      },
                                      "start": {
                                        "type": "string"
                                      }
                                    }
                                  },
                                  "mediaId": {
                                    "type": "string"
                                  },
                                  "createdAt": {
                                    "type": "string",
                                    "format": "date-time"
                                  },
                                  "publishedUrl": {
                                    "type": "string"
                                  }
                                }
                              },
                              "client": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "type": "string"
                                  },
                                  "email": {
                                    "type": "string"
                                  },
                                  "questions": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "type": "string"
                                        },
                                        "question": {
                                          "type": "string"
                                        },
                                        "answer": {
                                          "type": "string"
                                        },
                                        "answerType": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  }
                                }
                              },
                              "isDeleted": {
                                "type": "boolean"
                              },
                              "meta": {
                                "type": "object",
                                "properties": {
                                  "isScreenShare": {
                                    "type": "boolean"
                                  },
                                  "microphoneMuted": {
                                    "type": "boolean"
                                  },
                                  "microphoneReadyState": {
                                    "type": "string"
                                  },
                                  "microphoneName": {
                                    "type": "string"
                                  },
                                  "microphoneNumber": {
                                    "type": "integer"
                                  },
                                  "cameraMuted": {
                                    "type": "boolean"
                                  },
                                  "cameraReadyState": {
                                    "type": "string"
                                  },
                                  "cameraName": {
                                    "type": "string"
                                  },
                                  "cameraNumber": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "__v": {
                                "type": "integer"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "recording-details": {
                    "summary": "Recording Details",
                    "value": {
                      "status": "success",
                      "data": {
                        "totalCount": 3,
                        "recordings": [
                          {
                            "_id": "66bd022e507d6766980287eb",
                            "recorderId": "66798b454a53154b90d40077",
                            "mediaId": {
                              "_id": "66bd022e507d6766980287e9",
                              "folderId": "f89a9eac1b62",
                              "name": "Wed Aug 14 2024 15:14:54 GMT-0400 (Eastern Daylight Time)",
                              "description": "Client's recording for Recorder Mon Jun 24 2024",
                              "tags": [
                                "Recorder Mon Jun 24 2024"
                              ],
                              "state": "processed",
                              "duration": {
                                "inSecond": 15,
                                "end": "00:00:15.504",
                                "start": "00:00:00.080"
                              },
                              "mediaId": "dc49faf822df",
                              "createdAt": "2024-08-14T19:14:54.194Z",
                              "publishedUrl": "media/5d03a9d5d4bca272e9c8cf89/audio/1723662893381-recorder_mon_jun_24_2024.mp3"
                            },
                            "client": {
                              "name": "",
                              "email": "",
                              "questions": [
                                {
                                  "id": "41db9890bab9",
                                  "question": "test question",
                                  "answer": "test 3",
                                  "answerType": "single"
                                }
                              ]
                            },
                            "isDeleted": false,
                            "meta": {
                              "isScreenShare": false,
                              "microphoneMuted": false,
                              "microphoneReadyState": "live",
                              "microphoneName": "Default - MacBook Pro Microphone (Built-in)",
                              "microphoneNumber": 5,
                              "cameraMuted": false,
                              "cameraReadyState": "live",
                              "cameraName": "",
                              "cameraNumber": 1
                            },
                            "createdAt": "2024-08-14T19:14:54.586Z",
                            "updatedAt": "2024-08-14T19:14:54.586Z",
                            "__v": 0
                          }
                        ]
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/recorder/url/{recorderId}": {
      "get": {
        "tags": [
          "Recorder/Survey"
        ],
        "summary": "Generate Recorder URL",
        "operationId": "recorder-survey-generate-recorder-url",
        "description": "### API Endpoint: Get Recorder URL\n\n**Method:** `GET`\n**Endpoint:** `{{url}}/v1/recorder/url/:recorderId`\n\n#### Description\n\nThis endpoint retrieves the URL associated with a specific recorder identified by `recorderId`. It is used to obtain the necessary information to access the recorder's iframe and page details.\n\n#### Parameters\n\n- **recorderId** (path parameter): The unique identifier for the recorder whose URL is being requested.\n\n\n#### Response Format\n\nThe response will be in JSON format and includes the following fields:\n\n- **status**: A string indicating the status of the request.\n\n- **data**: An object containing:\n\n - **iframe**: A string representing the iframe URL for the recorder.\n\n - **page**: A string representing the page URL for the recorder.\n\n\n#### Example Response\n\n``` json\n{\n \"status\": \"\",\n \"data\": {\n \"iframe\": \"\",\n \"page\": \"\"\n }\n}\n\n ```",
        "parameters": [
          {
            "name": "recorderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "iframe": {
                          "type": "string"
                        },
                        "page": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "200": {
                    "summary": "200",
                    "value": {
                      "status": "success",
                      "data": {
                        "iframe": "<iframe style=\"height: 800px !important; width: 960px !important;\" src=\"https://recorder.speakai.co/iframe/recorder-9-4fb7713e267a\" frameborder=\"0\" scrolling=\"no\"></iframe>",
                        "page": "https://recorder.speakai.co/recorder-9-4fb7713e267a"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "404": {
                    "summary": "404",
                    "value": {
                      "status": "failed",
                      "requestId": "1babfc3a-9f8f-4c22-83c8-0367cb2b7cb1",
                      "code": 404,
                      "message": "Recorder Id not found!",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/recorder/settings/{recorderId}": {
      "put": {
        "tags": [
          "Recorder/Survey"
        ],
        "summary": "Update Recorder Settings",
        "operationId": "recorder-survey-update-recorder-settings",
        "description": "**Update a recorder details.**\n\n`name` - Name of the recorder\n\nAll the other fields are optional. Your recorder will be updated automatically.\n\n---\n\n**Duration of the recorder:**\n\n- `minDuration` - 15 seconds (min) & 5 min (max)\n - Pass the duration in **seconds**\n- `maxDuration` - 10 seconds (min) & 3 hours (max)\n - Pass the duration in seconds\n\n---\n\n**Source Language:**\n\n- You can pass the `sourceLanguage` as a code.\n- Other language codes available at the top of the page.\n\n\n---\n\n**Recorder options:**\n\n- We allow to support creating recorder with the multiple options such as:\n - `audio` - Audio recorder\n - `video` - Video recorder\n - `screeShare` - Allow to screen share on browser (Mobile not supported)\n - `uploadFile` - Allow to upload various file formats\n - `allowMultiple` - Supporting multiple file uploads\n\n---\n\n**Notifications:**\n\n`upload` - Recieve an email notification when anyone uploads a recording on the recorder\n\n`client` - When your user submits a recording (have the email address in a form) - they will receive an submittion email\n\n---\n\n**Not found:**\n\nThe lookup is scoped to your own workspace. If no recorder with that `recorderId` belongs to it, the call returns 404 and nothing is updated.",
        "parameters": [
          {
            "name": "recorderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": null
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Set the recorder name. Required on every call, even when you only mean to change something else. An empty or whitespace-only value is rejected. Sending the current name back is how you make a partial update."
                  },
                  "description": {
                    "type": "string",
                    "description": "Describe the recorder for your own reference. Optional, empty string allowed. The handler writes this only when the value is truthy, so an empty string leaves the stored description as it was."
                  },
                  "isAutoAnalyze": {
                    "type": "boolean",
                    "description": "Analyze each recording automatically as soon as it is submitted. Optional. Leaving it out leaves the stored setting alone. Send false to turn automatic analysis off."
                  },
                  "sourceLanguage": {
                    "type": "string",
                    "description": "Set the spoken language Speak transcribes recordings in. Optional. Leaving it out or sending an empty string leaves the stored language alone. Must be one of the transcription language codes the server compiles at start up from the static list (137 entries, including auto and multi). An unrecognized code returns 400 with 'sourceLanguage must be a valid transcription language code'."
                  },
                  "folderId": {
                    "type": "string",
                    "description": "Move new recordings from this recorder into the folder you name here. Optional, empty string allowed. The handler writes the folder only when the value is truthy, so an empty string leaves the current folder alone. A folderId that does not exist in your company returns 400 with 'Folder not found'."
                  },
                  "notifyUsers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "List the user IDs that get emailed when a recording arrives. Optional. Each item is a non-empty string. The handler persists this list only when you also send a notification object with at least one of upload or client set, so notifyUsers on its own is accepted and then ignored."
                  },
                  "duration": {
                    "type": "object",
                    "description": "Set how long a recording is allowed to run. Optional. Two optional number keys, both in seconds. minDuration accepts 0 to 300, maxDuration accepts 15 to 10800. Each key is written only when it is truthy, so 0 does not overwrite the stored minDuration."
                  },
                  "notification": {
                    "type": "object",
                    "description": "Choose who gets an email when a recording comes in. Optional. Two optional booleans. upload emails the users in notifyUsers when a recording arrives. client emails the respondent a confirmation, and only fires when they gave an email address. Sending this object with at least one key also writes notifyUsers, and any key you leave out is cleared on the stored notification block."
                  },
                  "options": {
                    "type": "object",
                    "description": "Turn the individual capture and upload modes on or off. Optional. Keys are all optional booleans unless noted: audio, video, screenShare, liveTranscription (also accepts null), and upload, a nested object with file, text, multiple and url. When you send this object the handler replaces the whole stored block, so send every mode you want kept or the ones you leave out are cleared."
                  },
                  "meta": {
                    "type": "object",
                    "description": "Brand and customize the recorder page. Optional, and unlike POST /recorder/create every key here takes effect. Strings, each written only when truthy: primaryColor, fontColor, fontFamily, theme, backgroundImg, logo. backgroundImg and logo are normalized from a signed CloudFront URL back to an S3 URI before storage. customCSS is capped at 50000 characters, is run through a CSS sanitizer before it is stored, and is written whenever you send it, so an empty string clears it. Booleans, each written whenever you send it: hideWaveform, hideTitle, hideDescription, hideSubmitButton, countdown, hideImages. submitButtonLabel is a string written only when truthy."
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "recorder-9",
                "description": "recorder-9 description",
                "folderId": "0648e533f72c",
                "sourceLanguage": "en-US",
                "duration": {
                  "minDuration": 120,
                  "maxDuration": 300
                },
                "options": {
                  "audio": true,
                  "video": true,
                  "screenShare": true,
                  "upload": {
                    "file": false,
                    "text": true,
                    "multiple": true,
                    "url": false
                  }
                },
                "notification": {
                  "upload": true,
                  "client": false
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "message": {
                          "type": "string"
                        },
                        "recorderId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "200": {
                    "summary": "200",
                    "value": {
                      "status": "success",
                      "data": {
                        "message": "recorder-9 updated is successfully updated",
                        "recorderId": "70ea4d569736"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "404": {
                    "summary": "404",
                    "value": {
                      "status": "failed",
                      "requestId": "3f0c1c2e-6c1b-4a3f-9a2d-7c5f0b1e4d88",
                      "code": 404,
                      "message": "Recorder not found",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/recorder/questions/{recorderId}": {
      "post": {
        "tags": [
          "Recorder/Survey"
        ],
        "summary": "Update Recorder Questions",
        "operationId": "recorder-survey-update-recorder-questions",
        "description": "**Update a recorder questions:**\n\n`questions` - Speak offer different set of questions to create and ask to your clients.\n\nHere're the few examples with value:\n\n1. Single Line - \"single\"\n2. Multi Line - \"multiple\"\n3. Checkbox\\* - \"checkbox\"\n4. Radio Button\\* - \"radiobutton\"\n5. Dropdown\\* - \"dropdownlist\"\n6. Date - \"date\"\n7. Date & Time - \"datetime\"\n\n\nCheckbox, Radio Button, Dropdown offers \"Include Others\" option.\n\nCheckbox Sample:\n\n``` json\n{\n\"question\":\"My Checkbox question\",\n\"isRequired\":true,\n\"answerType\":\"checkbox\",\n\"options\":[\"Option A\",\"Option B\"],\n\"includeOther\":false\n}\n\n```\n\nDropdown Sample with Include Other:\n\n``` json\n{\n \"question\": \"My Dropdown Question with Include Others\",\n \"isRequired\": true,\n \"answerType\": \"dropdownlist\",\n \"options\": [\n \"Value 1\",\n \"Value 2\"\n ],\n \"includeOther\": true\n}\n\n```",
        "parameters": [
          {
            "name": "recorderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": null
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Send the id of an existing question to edit it. Leave it out to add a new question. Optional. Accepts an empty string and null, both of which are treated as 'add a new question'. If you send an id that no question on the recorder matches, the request still returns 200 but nothing changes and questionData comes back empty."
                  },
                  "question": {
                    "type": "string",
                    "description": "Write the question text a respondent sees. Required. An empty or whitespace-only value is rejected."
                  },
                  "isRequired": {
                    "type": "boolean",
                    "description": "Make the respondent answer this question before they can submit. Required. There is no fallback, so you have to send it on every call, including edits."
                  },
                  "answerType": {
                    "type": "string",
                    "description": "Set the kind of answer control the question uses. Required. An empty or whitespace-only value is rejected. This route puts no.valid constraint on the value, so the server stores whatever string you send. The recorder reads these values from the RecorderAnswerType enum in @speakai/shared: single, multiple, checkbox, radiobutton, dropdownlist, date, time, datetime. The public submission route does enforce that enum with.valid, so a value outside the set is stored here and then rejected when a respondent submits an answer."
                  },
                  "options": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "List the choices for a question that offers a fixed set of answers. Optional. Each item is a non-empty string. There is no cap on the number of items."
                  },
                  "includeOther": {
                    "type": "boolean",
                    "description": "Add an 'Other' choice alongside the options you listed. Optional. No fallback, so it is stored as undefined when you leave it out."
                  },
                  "fieldId": {
                    "type": "string",
                    "description": "Map the answers to one of your custom fields. Optional. Accepts an empty string and null."
                  }
                },
                "required": [
                  "question",
                  "isRequired",
                  "answerType"
                ]
              },
              "example": {
                "question": "My First Sample Question",
                "isRequired": true,
                "answerType": "single",
                "options": [],
                "includeOther": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "message": {
                          "type": "string"
                        },
                        "recorderId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "200": {
                    "summary": "200",
                    "value": {
                      "status": "success",
                      "data": {
                        "message": "recorder-9 updated is successfully updated",
                        "recorderId": "70ea4d569736"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/embed": {
      "post": {
        "tags": [
          "Media Embed"
        ],
        "summary": "Create Embed",
        "operationId": "media-embed-create-embed",
        "description": "Create an Interactive Media Player by passing the value for `mediaId` OR `folderIds`\n\n- By passing `mediaId` - Create an individual media player.\n\n- By passing `folderIds` - Create a repository for a folder to share with others.\n\n\nMake sure you have access to Shareable Media Repository in your subscription.\n\n**Request rules.** Send either a media id or a set of folder ids. A non-empty media id creates a single media player, and the request is rejected with 403 unless your plan includes the media player feature and your role allows sharing media. An empty or absent media id switches to the library path, which is rejected with 403 unless your plan includes the media library feature. A media id that matches no media file in your workspace returns 404.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mediaId": {
                    "type": "string",
                    "description": "The id of the media file you want to publish as a standalone player. Send it to create a media player. Leave it out, or send an empty string, when you want a shared library built from folders instead. If that media file already has a player, you get the existing one back instead of a duplicate. Optional. An empty string is allowed and is treated the same as leaving it out."
                  },
                  "folderIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The folders whose media you want to publish together as a shared library. Send folder ids with no media id to create one. If a library already exists for the same folder ids in the same order, you get that one back instead of a duplicate. Whenever you send folder ids, they are recorded on the new embed and a password is generated for it, and that password comes back in the response. Optional. A list of folder ids, with no minimum or maximum length. Folder ids that match nothing in your workspace do not cause an error."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "string"
                        },
                        "meta": {
                          "type": "object",
                          "properties": {
                            "callToActionButtons": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "url": {
                                    "type": "string"
                                  },
                                  "label": {
                                    "type": "string"
                                  }
                                }
                              }
                            },
                            "features": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "type": "string"
                                  },
                                  "isActive": {
                                    "type": "boolean"
                                  }
                                }
                              }
                            },
                            "isDataVizDownloadable": {
                              "type": "boolean"
                            },
                            "isDescription": {
                              "type": "boolean"
                            },
                            "isSEOIndexing": {
                              "type": "boolean"
                            },
                            "isRemarks": {
                              "type": "boolean"
                            },
                            "isPromptAsk": {
                              "type": "boolean"
                            },
                            "isPromptHistory": {
                              "type": "boolean"
                            },
                            "isTitle": {
                              "type": "boolean"
                            },
                            "primaryColor": {
                              "type": "string"
                            }
                          }
                        },
                        "mediaId": {
                          "type": "string"
                        },
                        "folderIds": {
                          "type": "array",
                          "items": {}
                        },
                        "mediaType": {
                          "type": "string"
                        },
                        "token": {
                          "type": "string"
                        },
                        "privacyMode": {
                          "type": "string"
                        },
                        "page": {
                          "type": "string"
                        },
                        "iframe": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "create-embed": {
                    "summary": "Create Embed",
                    "value": {
                      "status": "success",
                      "data": {
                        "_id": "65660bf97f916888ccc2f4ca",
                        "meta": {
                          "callToActionButtons": [
                            {
                              "url": "https://speakai.co",
                              "label": "Speak Ai"
                            }
                          ],
                          "features": [
                            {
                              "name": "labels",
                              "isActive": true
                            }
                          ],
                          "isDataVizDownloadable": false,
                          "isDescription": false,
                          "isSEOIndexing": false,
                          "isRemarks": true,
                          "isPromptAsk": true,
                          "isPromptHistory": true,
                          "isTitle": true,
                          "primaryColor": "#c42860"
                        },
                        "mediaId": "3afc714552cd",
                        "folderIds": [],
                        "mediaType": "video",
                        "token": "how-to-edit-the-transcript-79a590aa126b",
                        "privacyMode": "private",
                        "page": "",
                        "iframe": ""
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      },
      "get": {
        "tags": [
          "Media Embed"
        ],
        "summary": "Check Embed",
        "operationId": "media-embed-check-embed",
        "description": "Checks if an embed already exits and returns status and token id.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ID of the media file to check for an embed"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "meta": {
                          "type": "object",
                          "properties": {
                            "backgroundImg": {
                              "type": "string"
                            },
                            "logo": {
                              "type": "string"
                            },
                            "primaryColor": {
                              "type": "string"
                            },
                            "isDataVizDownloadable": {
                              "type": "boolean"
                            },
                            "isSEOIndexing": {
                              "type": "boolean"
                            },
                            "isTitle": {
                              "type": "boolean"
                            },
                            "isDescription": {
                              "type": "boolean"
                            },
                            "callToActionButtons": {
                              "type": "array",
                              "items": {}
                            },
                            "features": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "type": "string"
                                  },
                                  "isActive": {
                                    "type": "boolean"
                                  }
                                }
                              }
                            }
                          }
                        },
                        "_id": {
                          "type": "string"
                        },
                        "mediaId": {
                          "type": "string"
                        },
                        "token": {
                          "type": "string"
                        },
                        "privacyMode": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "200": {
                    "summary": "200",
                    "value": {
                      "status": "success",
                      "data": {
                        "meta": {
                          "backgroundImg": "",
                          "logo": "",
                          "primaryColor": "",
                          "isDataVizDownloadable": true,
                          "isSEOIndexing": true,
                          "isTitle": true,
                          "isDescription": true,
                          "callToActionButtons": [],
                          "features": [
                            {
                              "name": "transcript",
                              "isActive": true
                            }
                          ]
                        },
                        "_id": "61280763ec13780791f004b2",
                        "mediaId": "e4e3079e3da9",
                        "token": "daily-standup-august-23-2021-239819a49b2d",
                        "privacyMode": "public"
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/embed/{embedId}": {
      "put": {
        "tags": [
          "Media Embed"
        ],
        "summary": "Update Embed",
        "operationId": "media-embed-update-embed",
        "description": "Update an existing Embed Media Player.\n\n- Make sure to pass in path `embedId` to update your existing player\n\n**Request rules.** The embedId value in the path is required and must be a string. Nothing in the body is required on its own, but only meta, privacyMode, password and mediaId change anything. Password handling runs only when privacyMode is present: private stores the trimmed password you send, or an empty one if you send none, and any other privacy value clears the password. The media file's own privacy mode is changed only when mediaId is present and not empty, and a media id that matches no media file in your workspace returns 404. Inside meta.callToActionButtons every item must carry both url and label. Inside meta.features every item must carry both name and isActive. An embed id that matches no embed returns 404.",
        "parameters": [
          {
            "name": "embedId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "65660bf97f916888ccc2f4ca"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "meta": {
                    "type": "object",
                    "description": "The look and behavior of the embedded player. Every top level key you send is applied on its own, so keys you leave out keep their current values. Arrays and the lead capture group are the exception: sending one replaces the stored value in full. Optional. Unknown keys inside it are rejected with 400.",
                    "properties": {
                      "backgroundImg": {
                        "type": "string",
                        "description": "The background image shown behind the player. Send an empty string to clear it. If you send a signed delivery URL it is converted back to its underlying storage location before being saved, and a delivery URL that cannot be converted leaves the current image unchanged. Optional. An empty string is allowed and clears the image. Null is accepted but ignored, so it leaves the current image unchanged."
                      },
                      "logo": {
                        "type": "string",
                        "description": "The logo shown on the player. Send an empty string to remove it. As with the background image, a signed delivery URL is converted back to its storage location before being saved, and one that cannot be converted leaves the current logo unchanged. Optional. An empty string is allowed and clears the logo. Null is accepted but ignored, so it leaves the current logo unchanged."
                      },
                      "callToActionButtons": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "url": {
                              "type": "string",
                              "description": "Where the button sends the viewer. Required on every button you send."
                            },
                            "label": {
                              "type": "string",
                              "description": "The text shown on the button. Required on every button you send."
                            }
                          }
                        },
                        "description": "The buttons shown to viewers alongside the media. Send the full list you want, because this replaces any buttons already set. Send an empty array to remove them all. Optional. Each item must have both url and label, and both must be strings."
                      },
                      "features": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "type": "string",
                              "description": "The insight category this entry controls. Use the same name the insight is reported under, for example keywords, topics or sentiment. Custom categories you have created use their own names. Required on every feature you send."
                            },
                            "isActive": {
                              "type": "boolean",
                              "description": "Set it to true to show this category to viewers and false to hide it. Required on every feature you send."
                            },
                            "isCustom": {
                              "type": "boolean",
                              "description": "Accepted on a feature entry but not saved. Only the name and the active state of each feature are stored, so sending this has no effect. Optional."
                            }
                          }
                        },
                        "description": "Which insight categories are switched on in the player, such as keywords, topics or sentiment. Send the full list you want, because this replaces the stored list. The list an embed starts with is built from the insights found on its media. Optional. Each item must have name and isActive. Only the name and the active state of each entry are stored. The list also carries rows that are not insights: on a shared dashboard, `{ \"name\": \"fieldsFocus\", \"isActive\": false }` stops recordings opened from the dashboard leading with their fields, and with no `fieldsFocus` row they do. Keep such rows when you resend the list."
                      },
                      "isTitle": {
                        "type": "boolean",
                        "description": "Set it to true to show the media title in the player and false to hide it. Optional. A new embed inherits this from your workspace player settings, which start it on."
                      },
                      "isDescription": {
                        "type": "boolean",
                        "description": "Set it to true to show the media description in the player and false to hide it. Optional. A new embed inherits this from your workspace player settings, which start it on."
                      },
                      "isRemarks": {
                        "type": "boolean",
                        "description": "Set it to true to let viewers see remarks and comments left on the media. Optional. A new embed inherits this from your workspace player settings, which start it off."
                      },
                      "isSEOIndexing": {
                        "type": "boolean",
                        "description": "Set it to true to let search engines index the shared page and false to keep it out of search results. Optional. A new embed inherits this from your workspace player settings, which start it on."
                      },
                      "isDataVizDownloadable": {
                        "type": "boolean",
                        "description": "Set it to true to let viewers download the charts and visualizations shown in the player. Optional. A new embed inherits this from your workspace player settings, which start it on."
                      },
                      "isMediaExport": {
                        "type": "boolean",
                        "description": "Set it to true to let viewers export or download the media itself. Optional. A new embed inherits this from your workspace player settings, which start it off."
                      },
                      "isPromptAsk": {
                        "type": "boolean",
                        "description": "Set it to true to let viewers ask the AI assistant questions about the media from inside the player. Optional. A new embed inherits this from your workspace player settings, which start it off."
                      },
                      "isPromptHistory": {
                        "type": "boolean",
                        "description": "Set it to true to show viewers the earlier questions and answers from the assistant, and false to start every visitor with a clean slate. Optional. A new embed inherits this from your workspace player settings, which start it off."
                      },
                      "chatWelcomeMessage": {
                        "type": "string",
                        "description": "The greeting the AI assistant opens with in the player. Send an empty string to use no greeting. Optional. An empty string is allowed, and null is accepted and stored as no greeting."
                      },
                      "assistantTemplateId": {
                        "type": "string",
                        "description": "The saved assistant template the player's AI chat answers with, so viewers get the tone and instructions you have already set up. Send an empty string to fall back to the default assistant. Optional. An empty string is allowed, and null is accepted and stored as no template."
                      },
                      "primaryColor": {
                        "type": "string",
                        "description": "The accent color used for controls and highlights in the player. Send a CSS color value such as a hex code. Optional. An empty string is allowed. A new embed inherits this from your workspace player settings, which start it at a dark grey. The value is stored as sent and is not checked for a valid color."
                      },
                      "titleColor": {
                        "type": "string",
                        "description": "The color of the title text in the player. Send a CSS color value such as a hex code. Optional. An empty string is allowed. A new embed inherits this from your workspace player settings, which start it at a dark grey. The value is stored as sent and is not checked for a valid color."
                      },
                      "logoDark": {
                        "type": "string",
                        "maxLength": 2048,
                        "description": "A shared dashboard's logo for viewers in dark mode. It must be an image already stored in Speak AI as a logo; any other link returns 400. When empty, the dashboard uses `logo`. Optional. An empty string or null clears it."
                      },
                      "theme": {
                        "type": "string",
                        "enum": [
                          "light",
                          "dark",
                          ""
                        ],
                        "description": "Forces a shared dashboard into `light` or `dark` for every viewer and hides their theme switch. An empty string lets each viewer choose. Optional. Null clears it."
                      },
                      "backgroundColor": {
                        "type": "string",
                        "description": "A hex color (`#rgb` or `#rrggbb`) for a shared dashboard's page background. Pair it with `theme` so text stays readable. Optional. An empty string or null clears it."
                      },
                      "fontFamily": {
                        "type": "string",
                        "maxLength": 60,
                        "description": "A Google Fonts family name for a shared dashboard, such as `Arimo`: letters, digits and spaces, up to 60 characters. Anything else returns 400. It overrides your account font for this embed. Optional. An empty string or null falls back to the account font."
                      },
                      "leadCapture": {
                        "type": "object",
                        "description": "Asks viewers for their email before they can watch, so you can see who is viewing. Send the full set of lead capture values you want, because sending this replaces the whole group rather than merging into it. It stays inactive until you switch it on. Optional. Unknown keys inside it are rejected with 400.",
                        "properties": {
                          "isEnabled": {
                            "type": "boolean",
                            "description": "The main switch. Set it to true to prompt viewers for their details, and while it is false no prompt appears no matter what the other lead capture values say. Optional. New embeds start with this off."
                          },
                          "collectName": {
                            "type": "boolean",
                            "description": "Set it to true to ask viewers for their name as well as their email. Optional. New embeds start with this off."
                          },
                          "requireConsent": {
                            "type": "boolean",
                            "description": "Set it to true to make viewers tick a consent box before they can submit their details. Optional. New embeds start with this off."
                          },
                          "consentText": {
                            "type": "string",
                            "description": "The wording shown next to the consent box. Write your own so it matches your privacy policy. Optional. An empty string is allowed, and null is accepted."
                          }
                        }
                      },
                      "isLabels": {
                        "type": "boolean",
                        "description": "Set it to true to show the media's labels read-only in a media or folder embed. Viewers can never add or change labels. Optional. Off by default."
                      },
                      "isComments": {
                        "type": "boolean",
                        "description": "Set it to true to show the media's comment threads read-only in a media or folder embed. Viewers can never comment. Optional. Off by default."
                      }
                    }
                  },
                  "privacyMode": {
                    "type": "string",
                    "description": "Controls whether viewers need a password. Send private together with the password you want, or send public to remove password protection. Leave this out and the current password is left alone, so an update that only changes appearance cannot wipe it. When you also send a media id, the media file itself is switched to the same privacy mode. Optional. An empty string is allowed. The value is not checked against the list, and anything other than private is treated as public and clears the password.",
                    "enum": [
                      "public",
                      "private"
                    ]
                  },
                  "password": {
                    "type": "string",
                    "description": "The password viewers must enter. It is used only when you also send a privacy mode of private, and surrounding spaces are trimmed. Send private with no password, or with an empty string, and the embed ends up with no password at all. Optional. An empty string is allowed. Ignored unless privacyMode is present."
                  },
                  "mediaId": {
                    "type": "string",
                    "description": "The media file behind this embed. Send it when you are changing the privacy mode, so the media file is switched over too. It does not move the embed to a different media file. Optional. An empty string is allowed and is treated as not sent. A non-empty value that does not match a media file in your workspace returns 404."
                  },
                  "folderIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Accepted but ignored. This endpoint does not change which folders a library embed covers, so sending different folder ids has no effect. Optional. A list of folder ids."
                  },
                  "mediaType": {
                    "type": "string",
                    "description": "Accepted but ignored. The media type is set when the embed is created and this endpoint does not change it. Optional. An empty string is allowed. The value is not checked against the list.",
                    "enum": [
                      "audio",
                      "video",
                      "text",
                      "media",
                      "csv"
                    ]
                  },
                  "embedType": {
                    "type": "string",
                    "description": "Accepted but ignored. Whether the embed is a single media player, a folder library or a dashboard is decided when it is created and cannot be switched here. Optional. An empty string is allowed. The value is not checked against the list.",
                    "enum": [
                      "mediaPlayer",
                      "repository",
                      "dashboard"
                    ]
                  },
                  "size": {
                    "type": "string",
                    "description": "Accepted but ignored. The stored iframe size is not changed by this endpoint. Optional. An empty string is allowed."
                  },
                  "isActive": {
                    "type": "boolean",
                    "description": "Accepted but ignored. This endpoint does not turn an embed on or off. Optional."
                  },
                  "_id": {
                    "type": "string",
                    "description": "The embed's own id. The Speak app sends it when it posts a whole embed object back. The embed that gets updated is always the one named in the path, so you can leave this out."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "_id": {
                          "type": "string"
                        },
                        "meta": {
                          "type": "object",
                          "properties": {
                            "backgroundImg": {
                              "type": "string"
                            },
                            "callToActionButtons": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "url": {
                                    "type": "string"
                                  },
                                  "label": {
                                    "type": "string"
                                  }
                                }
                              }
                            },
                            "features": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "type": "string"
                                  },
                                  "isActive": {
                                    "type": "boolean"
                                  }
                                }
                              }
                            },
                            "isDataVizDownloadable": {
                              "type": "boolean"
                            },
                            "isDescription": {
                              "type": "boolean"
                            },
                            "isSEOIndexing": {
                              "type": "boolean"
                            },
                            "isRemarks": {
                              "type": "boolean"
                            },
                            "isPromptAsk": {
                              "type": "boolean"
                            },
                            "isPromptHistory": {
                              "type": "boolean"
                            },
                            "isTitle": {
                              "type": "boolean"
                            },
                            "logo": {
                              "type": "string"
                            },
                            "primaryColor": {
                              "type": "string"
                            }
                          }
                        },
                        "mediaId": {
                          "type": "string"
                        },
                        "folderIds": {
                          "type": "array",
                          "items": {}
                        },
                        "embedType": {
                          "type": "string"
                        },
                        "isActive": {
                          "type": "boolean"
                        },
                        "isDeleted": {
                          "type": "boolean"
                        },
                        "analytics": {
                          "type": "array",
                          "items": {}
                        },
                        "companyId": {
                          "type": "string"
                        },
                        "userId": {
                          "type": "string"
                        },
                        "mediaType": {
                          "type": "string"
                        },
                        "token": {
                          "type": "string"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "__v": {
                          "type": "integer"
                        },
                        "password": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "update-embed": {
                    "summary": "Update Embed",
                    "value": {
                      "status": "success",
                      "data": {
                        "_id": "65660bf97f916888ccc2f4ca",
                        "meta": {
                          "backgroundImg": "",
                          "callToActionButtons": [
                            {
                              "url": "https://speakai.co",
                              "label": "Speak Ai"
                            }
                          ],
                          "features": [
                            {
                              "name": "keywords",
                              "isActive": true
                            }
                          ],
                          "isDataVizDownloadable": true,
                          "isDescription": true,
                          "isSEOIndexing": true,
                          "isRemarks": true,
                          "isPromptAsk": false,
                          "isPromptHistory": true,
                          "isTitle": true,
                          "logo": "",
                          "primaryColor": "#c42860"
                        },
                        "mediaId": "3afc714552cd",
                        "folderIds": [],
                        "embedType": "mediaPlayer",
                        "isActive": true,
                        "isDeleted": false,
                        "analytics": [],
                        "companyId": "5e21c8dd2d77242c64214816",
                        "userId": "5d03a9d5d4bca272e9c8cf89",
                        "mediaType": "video",
                        "token": "how-to-edit-the-transcript-79a590aa126b",
                        "createdAt": "2023-11-28T15:49:13.511Z",
                        "updatedAt": "2023-11-28T15:55:58.403Z",
                        "__v": 0,
                        "password": ""
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/embed/privacyState": {
      "get": {
        "tags": [
          "Media Embed"
        ],
        "summary": "Check Embed Privacy Mode",
        "operationId": "media-embed-check-embed-privacy-mode",
        "description": "### Endpoint Description\n\nThis endpoint retrieves the privacy state of the application based on the provided token. It is primarily used to check whether the current privacy settings are secure.\n\n### Request\n\n- **Method**: GET\n\n- **URL**: `{{url}}/v1/embed/privacyState?token={token}`\n\n\n#### Query Parameters\n\n- `token` (string): A unique token that identifies the user's session or request. This parameter is required for the request to be processed.\n\n\n### Response\n\nThe response will contain the following structure:\n\n- **status** (string): A status message indicating the result of the request.\n\n- **data** (object): An object containing the privacy state information.\n\n - **isSecure** (boolean): A boolean value indicating whether the privacy settings are secure (`true` or `false`).\n\n\n### Example Response\n\n``` json\n{\n \"status\": \"\",\n \"data\": {\n \"isSecure\": true\n }\n}\n\n ```\n\nThis response indicates that the privacy settings are currently secure.",
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "isSecure": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "check-embed-privacy-mode": {
                    "summary": "Check Embed Privacy Mode",
                    "value": {
                      "status": "success",
                      "data": {
                        "isSecure": false
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/embed/iframe": {
      "get": {
        "tags": [
          "Media Embed"
        ],
        "summary": "Get Iframe URL",
        "operationId": "media-embed-get-iframe-url",
        "description": "Get Embed Iframe and Page URL\n\nEither pass `mediaId` for individaul file.\n\nOR\n\nPass `folderId` for a repository URLs.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Either Folder ID or Media ID",
            "example": "''"
          },
          {
            "name": "folderId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Either Folder ID or Media ID",
            "x-postman-disabled": true
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "iframe": {
                          "type": "string"
                        },
                        "page": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "get-iframe-url": {
                    "summary": "Get Iframe URL",
                    "value": {
                      "status": "success",
                      "data": {
                        "iframe": "<iframe style=\"height: 800px !important; width: 960px !important;\" src=\"https://embed.speakai.co/iframe/how-to-find-your-first-analyzed-video-edq6fuxmemn\" frameborder=\"0\" scrolling...",
                        "page": "https://embed.speakai.co/how-to-find-your-first-analyzed-video-edq6fuxmemn"
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/embed/sessions/{embedId}": {
      "get": {
        "tags": [
          "Media Embed"
        ],
        "summary": "List Embed Sessions",
        "operationId": "media-embed-list-sessions",
        "description": "List the viewing sessions on one embed, newest first by default. A session is one visit to the embed page by one browser: when it started and ended, how long the viewer was active, what they opened and watched, how many questions they asked, and where they came from.\n\nFilter by date range, traffic type, identified or anonymous viewers, device, country, a single viewer or visitor, or a media file the session opened. Members without access to all folders only see embeds for media and folders they can open. Any other embed, or an embed that is deleted or in another workspace, returns 404.",
        "parameters": [
          {
            "name": "embedId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{24}$"
            },
            "description": "The `_id` of the embed, as returned when you create or check an embed. Must be a 24 character hex id.",
            "example": "6650a1b2c3d4e5f6a7b8c9d0"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only sessions started at or after this time, as an ISO 8601 date. Optional. Leave it out for no lower bound.",
            "example": "2026-09-01T00:00:00.000Z"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only sessions started at or before this time, as an ISO 8601 date. Optional. Leave it out for no upper bound.",
            "example": "2026-09-30T23:59:59.999Z"
          },
          {
            "name": "traffic",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "people",
                "bots"
              ],
              "default": "all"
            },
            "description": "Which visits to count: everyone, only people, or only detected bots and crawlers. Optional. Defaults to `all`.",
            "example": "people"
          },
          {
            "name": "includeOwner",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Count visits by members of your own workspace. Optional. Defaults to `false`.",
            "example": "false"
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Page to return, starting at 0. Optional. Defaults to 0.",
            "example": 0
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Sessions per page, from 1 to 100. Optional. Defaults to 25.",
            "example": 25
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Match sessions whose viewer email contains this text, or whose visitor id starts with it. Not case sensitive. Optional. At most 100 characters. An empty string is ignored."
          },
          {
            "name": "viewer",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identified",
                "anonymous"
              ],
              "default": "all"
            },
            "description": "Only sessions where the viewer entered an email (`identified`), only those where they did not (`anonymous`), or both. Optional. Defaults to `all`. Ignored when `viewerId` is sent.",
            "example": "identified"
          },
          {
            "name": "device",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "desktop",
                "mobile",
                "tablet"
              ],
              "default": "all"
            },
            "description": "Only sessions on this kind of device. `desktop` means anything that is not a phone or tablet. Optional. Defaults to `all`.",
            "example": "desktop"
          },
          {
            "name": "country",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Only sessions from this country, by name as returned by the countries endpoint, such as `Canada`. Optional. An empty string is ignored."
          },
          {
            "name": "includeLegacy",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Include visits recorded before session tracking, which carry no timing, media or question numbers. Optional. Defaults to `false`.",
            "example": "false"
          },
          {
            "name": "viewerId",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{32}$"
            },
            "description": "Only sessions from this identified viewer. Optional. 32 lowercase hex characters, as returned in `viewerId`."
          },
          {
            "name": "visitorId",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9-]{16,64}$"
            },
            "description": "Only sessions from this browser. Optional. 16 to 64 letters, digits or dashes, as returned in `visitorId`."
          },
          {
            "name": "mediaId",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Only sessions that opened this media file. Optional."
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "startedAt:desc",
                "startedAt:asc",
                "activeMs:desc",
                "watchedMs:desc",
                "questions:desc"
              ],
              "default": "startedAt:desc"
            },
            "description": "Order of the results. Optional. Defaults to `startedAt:desc`.",
            "example": "startedAt:desc"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "sessions": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "The session's id. Use it with the session detail endpoint."
                              },
                              "sessionId": {
                                "type": "string",
                                "description": "The id the browser gave the session."
                              },
                              "isLegacy": {
                                "type": "boolean",
                                "description": "True for a visit recorded before session tracking. Its timing, media and question numbers are null."
                              },
                              "isOwner": {
                                "type": "boolean",
                                "description": "True when the visit came from a member of your workspace."
                              },
                              "isLive": {
                                "type": "boolean",
                                "description": "True when the viewer was active in the last minute and the session has not ended."
                              },
                              "visitorId": {
                                "type": "string",
                                "description": "Anonymous id kept in the viewer's browser. Absent on some legacy visits."
                              },
                              "viewerId": {
                                "type": "string",
                                "description": "Present when the viewer entered their email on the embed."
                              },
                              "email": {
                                "type": "string",
                                "description": "The email the viewer entered, when they did."
                              },
                              "name": {
                                "type": "string",
                                "description": "The name the viewer entered, when they did."
                              },
                              "startedAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "lastActiveAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "Last time the viewer interacted. Absent when unknown."
                              },
                              "endedAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "When the session ended. Absent while it is still open. A session with no activity for 30 minutes counts as ended at its last activity."
                              },
                              "durationMs": {
                                "type": "integer",
                                "nullable": true,
                                "description": "Wall clock time from start to last activity, in milliseconds. Null on legacy visits."
                              },
                              "activeMs": {
                                "type": "integer",
                                "nullable": true,
                                "description": "Time the viewer was active on the page, in milliseconds. Null on legacy visits."
                              },
                              "mediaOpened": {
                                "type": "integer",
                                "nullable": true,
                                "description": "Media files opened. Null on legacy visits."
                              },
                              "watchedMs": {
                                "type": "integer",
                                "nullable": true,
                                "description": "Media playback time, in milliseconds. Null on legacy visits."
                              },
                              "questions": {
                                "type": "integer",
                                "nullable": true,
                                "description": "Questions asked to the AI chat. Null on legacy visits."
                              },
                              "client": {
                                "type": "object",
                                "properties": {
                                  "country": {
                                    "type": "string",
                                    "description": "Country name."
                                  },
                                  "region": {
                                    "type": "string"
                                  },
                                  "city": {
                                    "type": "string"
                                  },
                                  "continent": {
                                    "type": "string"
                                  },
                                  "timeZone": {
                                    "type": "string"
                                  },
                                  "browser": {
                                    "type": "string"
                                  },
                                  "os": {
                                    "type": "string"
                                  },
                                  "referer": {
                                    "type": "string"
                                  },
                                  "referrerHost": {
                                    "type": "string",
                                    "description": "Host of the referring page."
                                  },
                                  "screen": {
                                    "type": "string"
                                  },
                                  "language": {
                                    "type": "string"
                                  },
                                  "embedded": {
                                    "type": "boolean",
                                    "description": "True when the embed was loaded inside another site's page."
                                  },
                                  "deviceType": {
                                    "type": "string",
                                    "description": "The device type the browser reports, such as `mobile` or `tablet`. Usually absent on desktop browsers."
                                  }
                                },
                                "description": "Where the visit came from and on what device, when known. Every field is optional."
                              },
                              "campaign": {
                                "type": "object",
                                "properties": {
                                  "utmSource": {
                                    "type": "string"
                                  },
                                  "utmMedium": {
                                    "type": "string"
                                  },
                                  "utmCampaign": {
                                    "type": "string"
                                  }
                                },
                                "description": "UTM tags on the visit, when present. Every field is optional."
                              },
                              "bot": {
                                "type": "object",
                                "description": "Present when the visit was a detected bot or crawler.",
                                "properties": {
                                  "kind": {
                                    "type": "string",
                                    "enum": [
                                      "render",
                                      "crawler"
                                    ]
                                  },
                                  "name": {
                                    "type": "string"
                                  }
                                }
                              }
                            }
                          },
                          "description": "One page of sessions, sorted by `sort`. Bot visits also carry `bot` with `kind` (`render` or `crawler`) and an optional `name`."
                        },
                        "totalCount": {
                          "type": "integer",
                          "description": "Sessions matching the filters, across all pages."
                        },
                        "page": {
                          "type": "integer",
                          "description": "The page returned, starting at 0."
                        },
                        "pageSize": {
                          "type": "integer",
                          "description": "The page size used."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "list-sessions": {
                    "value": {
                      "status": "success",
                      "data": {
                        "sessions": [
                          {
                            "_id": "6650b2c3d4e5f6a7b8c9d0e1",
                            "sessionId": "8c1f0e7a-5b2d-4c9e-a1f3-6d7e8f9a0b1c",
                            "isLegacy": false,
                            "isOwner": false,
                            "isLive": false,
                            "visitorId": "3d2c1b0a-9f8e-4d7c-b6a5-4f3e2d1c0b9a",
                            "viewerId": "0f1e2d3c4b5a69788796a5b4c3d2e1f0",
                            "email": "viewer@example.com",
                            "name": "Sam Viewer",
                            "startedAt": "2026-09-14T13:02:11.000Z",
                            "lastActiveAt": "2026-09-14T13:19:45.000Z",
                            "endedAt": "2026-09-14T13:20:02.000Z",
                            "durationMs": 1071000,
                            "activeMs": 812000,
                            "mediaOpened": 2,
                            "watchedMs": 540000,
                            "questions": 1,
                            "client": {
                              "country": "Canada",
                              "region": "Ontario",
                              "city": "Toronto",
                              "continent": "North America",
                              "timeZone": "America/Toronto",
                              "browser": "Chrome",
                              "os": "macOS",
                              "referer": "https://www.example.com/research",
                              "referrerHost": "www.example.com",
                              "screen": "1512x982",
                              "language": "en-CA",
                              "embedded": true
                            },
                            "campaign": {
                              "utmSource": "newsletter",
                              "utmMedium": "email",
                              "utmCampaign": "september-update"
                            }
                          }
                        ],
                        "totalCount": 42,
                        "page": 0,
                        "pageSize": 25
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "A query parameter failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Embed not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Error: Embed details not found!",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/embed/sessions/{embedId}/summary": {
      "get": {
        "tags": [
          "Media Embed"
        ],
        "summary": "Embed Session Summary",
        "operationId": "media-embed-session-summary",
        "description": "Headline numbers for one embed over a date range: sessions, unique and returning visitors, identified viewers, active time, media opens, watch time and questions, plus a daily series, the top referring sites and a page of per media file numbers.\n\nLegacy visits recorded before session tracking are always included here. Members without access to all folders only see embeds for media and folders they can open. Any other embed, or an embed that is deleted or in another workspace, returns 404.",
        "parameters": [
          {
            "name": "embedId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{24}$"
            },
            "description": "The `_id` of the embed, as returned when you create or check an embed. Must be a 24 character hex id.",
            "example": "6650a1b2c3d4e5f6a7b8c9d0"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only sessions started at or after this time, as an ISO 8601 date. Optional. Leave it out for no lower bound.",
            "example": "2026-09-01T00:00:00.000Z"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only sessions started at or before this time, as an ISO 8601 date. Optional. Leave it out for no upper bound.",
            "example": "2026-09-30T23:59:59.999Z"
          },
          {
            "name": "traffic",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "people",
                "bots"
              ],
              "default": "all"
            },
            "description": "Which visits to count: everyone, only people, or only detected bots and crawlers. Optional. Defaults to `all`.",
            "example": "people"
          },
          {
            "name": "includeOwner",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Count visits by members of your own workspace. Optional. Defaults to `false`.",
            "example": "false"
          },
          {
            "name": "tz",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 100,
              "default": "UTC"
            },
            "description": "IANA time zone used to group the daily series, such as `America/Toronto`. Optional. Defaults to `UTC`. At most 100 characters. An unknown zone returns 400.",
            "example": "America/Toronto"
          },
          {
            "name": "mediaPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Page of the `media` list to return, starting at 0. Optional. Defaults to 0.",
            "example": 0
          },
          {
            "name": "mediaPageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "description": "Media files per page, from 1 to 100. Optional. Defaults to 25.",
            "example": 25
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "kpis": {
                          "type": "object",
                          "properties": {
                            "sessions": {
                              "type": "integer",
                              "description": "Visits in the range. Legacy visits by an identified viewer are not counted again here."
                            },
                            "uniqueVisitors": {
                              "type": "integer",
                              "description": "Distinct visitors in the range."
                            },
                            "returningVisitors": {
                              "type": "integer",
                              "description": "Visitors with more than one visit in the range, or a visit before it."
                            },
                            "identifiedViewers": {
                              "type": "integer",
                              "description": "Distinct viewers who entered an email."
                            },
                            "avgActiveMs": {
                              "type": "integer",
                              "description": "Average active time per session, in milliseconds. Legacy visits are left out of the average."
                            },
                            "mediaOpens": {
                              "type": "integer",
                              "description": "Media files opened, across all sessions."
                            },
                            "watchedMs": {
                              "type": "integer",
                              "description": "Total media playback time, in milliseconds."
                            },
                            "questions": {
                              "type": "integer",
                              "description": "Questions asked to the AI chat."
                            },
                            "sessionsWithQuestions": {
                              "type": "integer",
                              "description": "Sessions with at least one question."
                            }
                          }
                        },
                        "overTime": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": {
                                "type": "string",
                                "description": "Day as `YYYY-MM-DD`."
                              },
                              "sessions": {
                                "type": "integer"
                              },
                              "visitors": {
                                "type": "integer"
                              }
                            }
                          },
                          "description": "One entry per day that had visits, in the requested time zone. Days with no visits are left out."
                        },
                        "sources": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "source": {
                                "type": "string"
                              },
                              "sessions": {
                                "type": "integer"
                              }
                            }
                          },
                          "description": "Up to 10 referring hosts with the most visits. An empty `source` means no referrer."
                        },
                        "media": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "mediaId": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string",
                                "description": "Absent when the media file no longer exists."
                              },
                              "durationSec": {
                                "type": "integer",
                                "description": "Absent when unknown."
                              },
                              "opens": {
                                "type": "integer"
                              },
                              "uniqueViewers": {
                                "type": "integer"
                              },
                              "plays": {
                                "type": "integer"
                              },
                              "watchedMs": {
                                "type": "integer",
                                "description": "Total playback time for this file, in milliseconds."
                              },
                              "avgWatchedMs": {
                                "type": "integer",
                                "description": "Playback time per session that opened this file, in milliseconds."
                              },
                              "completionRate": {
                                "type": "number",
                                "description": "Sessions that played this file to the end divided by sessions that opened it, from 0 to 1."
                              },
                              "questions": {
                                "type": "integer",
                                "description": "Questions asked about this file."
                              },
                              "downloads": {
                                "type": "integer",
                                "description": "Transcript downloads, media downloads and exports for this file."
                              }
                            }
                          },
                          "description": "One page of media files, most opened first."
                        },
                        "mediaPage": {
                          "type": "integer",
                          "description": "The media page returned, starting at 0."
                        },
                        "mediaPageSize": {
                          "type": "integer",
                          "description": "The media page size used."
                        },
                        "mediaTotal": {
                          "type": "integer",
                          "description": "Distinct media files opened in the range, across all pages."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "session-summary": {
                    "value": {
                      "status": "success",
                      "data": {
                        "kpis": {
                          "sessions": 318,
                          "uniqueVisitors": 204,
                          "returningVisitors": 41,
                          "identifiedViewers": 57,
                          "avgActiveMs": 246000,
                          "mediaOpens": 512,
                          "watchedMs": 86400000,
                          "questions": 133,
                          "sessionsWithQuestions": 72
                        },
                        "overTime": [
                          {
                            "date": "2026-09-14",
                            "sessions": 19,
                            "visitors": 15
                          }
                        ],
                        "sources": [
                          {
                            "source": "www.example.com",
                            "sessions": 120
                          }
                        ],
                        "media": [
                          {
                            "mediaId": "3afc714552cd",
                            "name": "Quarterly customer interview",
                            "durationSec": 1820,
                            "opens": 96,
                            "uniqueViewers": 71,
                            "plays": 88,
                            "watchedMs": 14400000,
                            "avgWatchedMs": 160000,
                            "completionRate": 0.22,
                            "questions": 18,
                            "downloads": 4
                          }
                        ],
                        "mediaPage": 0,
                        "mediaPageSize": 25,
                        "mediaTotal": 12
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "A query parameter failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Embed not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Error: Embed details not found!",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/embed/sessions/{embedId}/detail/{id}": {
      "get": {
        "tags": [
          "Media Embed"
        ],
        "summary": "Get Embed Session",
        "operationId": "media-embed-get-session",
        "description": "Read one viewing session in full: the same fields as the session list, plus each media file opened, each question asked to the AI chat, and a page of the session's events in time order. Use `eventsPage` and `eventsPageSize` to walk through long sessions.\n\nReturns 404 when the session does not belong to this embed. Members without access to all folders only see embeds for media and folders they can open. Any other embed, or an embed that is deleted or in another workspace, returns 404.",
        "parameters": [
          {
            "name": "embedId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{24}$"
            },
            "description": "The `_id` of the embed, as returned when you create or check an embed. Must be a 24 character hex id.",
            "example": "6650a1b2c3d4e5f6a7b8c9d0"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{24}$"
            },
            "description": "The session's `_id`, as returned by the session list. Must be a 24 character hex id.",
            "example": "6650b2c3d4e5f6a7b8c9d0e1"
          },
          {
            "name": "eventsPage",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Page of events to return, starting at 0. Optional. Defaults to 0.",
            "example": 0
          },
          {
            "name": "eventsPageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 200
            },
            "description": "Events per page, from 1 to 500. Optional. Defaults to 200.",
            "example": 200
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "session": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "The session's id. Use it with the session detail endpoint."
                            },
                            "sessionId": {
                              "type": "string",
                              "description": "The id the browser gave the session."
                            },
                            "isLegacy": {
                              "type": "boolean",
                              "description": "True for a visit recorded before session tracking. Its timing, media and question numbers are null."
                            },
                            "isOwner": {
                              "type": "boolean",
                              "description": "True when the visit came from a member of your workspace."
                            },
                            "isLive": {
                              "type": "boolean",
                              "description": "True when the viewer was active in the last minute and the session has not ended."
                            },
                            "visitorId": {
                              "type": "string",
                              "description": "Anonymous id kept in the viewer's browser. Absent on some legacy visits."
                            },
                            "viewerId": {
                              "type": "string",
                              "description": "Present when the viewer entered their email on the embed."
                            },
                            "email": {
                              "type": "string",
                              "description": "The email the viewer entered, when they did."
                            },
                            "name": {
                              "type": "string",
                              "description": "The name the viewer entered, when they did."
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "lastActiveAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "Last time the viewer interacted. Absent when unknown."
                            },
                            "endedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "When the session ended. Absent while it is still open. A session with no activity for 30 minutes counts as ended at its last activity."
                            },
                            "durationMs": {
                              "type": "integer",
                              "nullable": true,
                              "description": "Wall clock time from start to last activity, in milliseconds. Null on legacy visits."
                            },
                            "activeMs": {
                              "type": "integer",
                              "nullable": true,
                              "description": "Time the viewer was active on the page, in milliseconds. Null on legacy visits."
                            },
                            "mediaOpened": {
                              "type": "integer",
                              "nullable": true,
                              "description": "Media files opened. Null on legacy visits."
                            },
                            "watchedMs": {
                              "type": "integer",
                              "nullable": true,
                              "description": "Media playback time, in milliseconds. Null on legacy visits."
                            },
                            "questions": {
                              "type": "integer",
                              "nullable": true,
                              "description": "Questions asked to the AI chat. Null on legacy visits."
                            },
                            "client": {
                              "type": "object",
                              "properties": {
                                "country": {
                                  "type": "string",
                                  "description": "Country name."
                                },
                                "region": {
                                  "type": "string"
                                },
                                "city": {
                                  "type": "string"
                                },
                                "continent": {
                                  "type": "string"
                                },
                                "timeZone": {
                                  "type": "string"
                                },
                                "browser": {
                                  "type": "string"
                                },
                                "os": {
                                  "type": "string"
                                },
                                "referer": {
                                  "type": "string"
                                },
                                "referrerHost": {
                                  "type": "string",
                                  "description": "Host of the referring page."
                                },
                                "screen": {
                                  "type": "string"
                                },
                                "language": {
                                  "type": "string"
                                },
                                "embedded": {
                                  "type": "boolean",
                                  "description": "True when the embed was loaded inside another site's page."
                                },
                                "deviceType": {
                                  "type": "string",
                                  "description": "The device type the browser reports, such as `mobile` or `tablet`. Usually absent on desktop browsers."
                                }
                              },
                              "description": "Where the visit came from and on what device, when known. Every field is optional."
                            },
                            "campaign": {
                              "type": "object",
                              "properties": {
                                "utmSource": {
                                  "type": "string"
                                },
                                "utmMedium": {
                                  "type": "string"
                                },
                                "utmCampaign": {
                                  "type": "string"
                                }
                              },
                              "description": "UTM tags on the visit, when present. Every field is optional."
                            },
                            "media": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "mediaId": {
                                    "type": "string"
                                  },
                                  "opens": {
                                    "type": "integer"
                                  },
                                  "activeMs": {
                                    "type": "integer",
                                    "description": "Time the viewer was active while this file was open, in milliseconds."
                                  },
                                  "playedMs": {
                                    "type": "integer",
                                    "description": "Playback time, in milliseconds."
                                  },
                                  "plays": {
                                    "type": "integer"
                                  },
                                  "seeks": {
                                    "type": "integer"
                                  },
                                  "maxPositionPct": {
                                    "type": "integer",
                                    "description": "Furthest point reached, as a percentage of the file."
                                  },
                                  "completed": {
                                    "type": "boolean",
                                    "description": "True when the viewer reached 95% of the file."
                                  },
                                  "firstOpenedAt": {
                                    "type": "string",
                                    "format": "date-time"
                                  },
                                  "name": {
                                    "type": "string",
                                    "description": "Absent when the media file no longer exists."
                                  },
                                  "durationSec": {
                                    "type": "integer",
                                    "description": "Absent when unknown."
                                  }
                                }
                              },
                              "description": "Each media file opened in the session."
                            },
                            "chat": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "promptId": {
                                    "type": "string"
                                  },
                                  "messageId": {
                                    "type": "string"
                                  },
                                  "askedAt": {
                                    "type": "string",
                                    "format": "date-time"
                                  },
                                  "mediaIds": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "question": {
                                    "type": "string",
                                    "description": "The question text. Absent when the chat message no longer exists."
                                  },
                                  "state": {
                                    "type": "string",
                                    "description": "State of the answer. Absent when the chat message no longer exists."
                                  },
                                  "feedbackScore": {
                                    "type": "integer",
                                    "description": "The viewer's rating of the answer, when they gave one."
                                  }
                                }
                              },
                              "description": "Each question asked to the AI chat in the session."
                            },
                            "events": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "t": {
                                    "type": "integer",
                                    "description": "When the event happened in the browser, in milliseconds since the Unix epoch."
                                  },
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "session_start",
                                      "session_resume",
                                      "session_end",
                                      "page_view",
                                      "dashboard_view",
                                      "widget_open",
                                      "media_open",
                                      "media_close",
                                      "citation_open",
                                      "search",
                                      "transcript_download",
                                      "transcript_copy",
                                      "media_download",
                                      "export",
                                      "play",
                                      "pause",
                                      "seek",
                                      "ended",
                                      "rate_change",
                                      "chat_question",
                                      "chat_feedback",
                                      "hidden",
                                      "idle",
                                      "gate_shown",
                                      "lead_captured"
                                    ]
                                  },
                                  "category": {
                                    "type": "string",
                                    "enum": [
                                      "lifecycle",
                                      "navigation",
                                      "playback",
                                      "chat",
                                      "engagement",
                                      "identity",
                                      "sharing"
                                    ]
                                  },
                                  "mediaId": {
                                    "type": "string",
                                    "description": "Present on events about a media file."
                                  },
                                  "data": {
                                    "type": "object",
                                    "properties": {
                                      "source": {
                                        "type": "string"
                                      }
                                    },
                                    "description": "Extra details for the event, such as the playback position or export format. Keys vary by event type."
                                  },
                                  "receivedAt": {
                                    "type": "string",
                                    "format": "date-time",
                                    "description": "When the server received the event."
                                  },
                                  "promptId": {
                                    "type": "string",
                                    "description": "Present on events about an AI chat question."
                                  }
                                }
                              },
                              "description": "One page of the session's events, oldest first."
                            },
                            "eventsPage": {
                              "type": "integer",
                              "description": "The events page returned, starting at 0."
                            },
                            "eventsPageSize": {
                              "type": "integer",
                              "description": "The events page size used."
                            },
                            "eventsTotal": {
                              "type": "integer",
                              "description": "Events in the session, across all pages."
                            },
                            "bot": {
                              "type": "object",
                              "description": "Present when the visit was a detected bot or crawler.",
                              "properties": {
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "render",
                                    "crawler"
                                  ]
                                },
                                "name": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        },
                        "visitorSessions": {
                          "type": "integer",
                          "description": "Sessions on this embed from the same viewer, or from the same browser when the viewer is anonymous, including this one."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "session-detail": {
                    "value": {
                      "status": "success",
                      "data": {
                        "session": {
                          "_id": "6650b2c3d4e5f6a7b8c9d0e1",
                          "sessionId": "8c1f0e7a-5b2d-4c9e-a1f3-6d7e8f9a0b1c",
                          "isLegacy": false,
                          "isOwner": false,
                          "isLive": false,
                          "visitorId": "3d2c1b0a-9f8e-4d7c-b6a5-4f3e2d1c0b9a",
                          "viewerId": "0f1e2d3c4b5a69788796a5b4c3d2e1f0",
                          "email": "viewer@example.com",
                          "name": "Sam Viewer",
                          "startedAt": "2026-09-14T13:02:11.000Z",
                          "lastActiveAt": "2026-09-14T13:19:45.000Z",
                          "endedAt": "2026-09-14T13:20:02.000Z",
                          "durationMs": 1071000,
                          "activeMs": 812000,
                          "mediaOpened": 2,
                          "watchedMs": 540000,
                          "questions": 1,
                          "client": {
                            "country": "Canada",
                            "region": "Ontario",
                            "city": "Toronto",
                            "continent": "North America",
                            "timeZone": "America/Toronto",
                            "browser": "Chrome",
                            "os": "macOS",
                            "referer": "https://www.example.com/research",
                            "referrerHost": "www.example.com",
                            "screen": "1512x982",
                            "language": "en-CA",
                            "embedded": true
                          },
                          "campaign": {
                            "utmSource": "newsletter",
                            "utmMedium": "email",
                            "utmCampaign": "september-update"
                          },
                          "media": [
                            {
                              "mediaId": "3afc714552cd",
                              "opens": 1,
                              "activeMs": 402000,
                              "playedMs": 360000,
                              "plays": 2,
                              "seeks": 3,
                              "maxPositionPct": 64,
                              "completed": false,
                              "firstOpenedAt": "2026-09-14T13:04:30.000Z",
                              "name": "Quarterly customer interview",
                              "durationSec": 1820
                            }
                          ],
                          "chat": [
                            {
                              "promptId": "b7e4c2a1-0d3f-4e5a-8b9c-1d2e3f4a5b6c",
                              "messageId": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
                              "askedAt": "2026-09-14T13:12:05.000Z",
                              "mediaIds": [
                                "3afc714552cd"
                              ],
                              "question": "What did the customer say about onboarding?",
                              "state": "completed",
                              "feedbackScore": 1
                            }
                          ],
                          "events": [
                            {
                              "t": 1789391071000,
                              "type": "media_open",
                              "category": "navigation",
                              "mediaId": "3afc714552cd",
                              "data": {
                                "source": "list"
                              },
                              "receivedAt": "2026-09-14T13:04:31.000Z"
                            }
                          ],
                          "eventsPage": 0,
                          "eventsPageSize": 200,
                          "eventsTotal": 37
                        },
                        "visitorSessions": 3
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "A query parameter failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Embed or session not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Error: Embed session not found!",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/embed/sessions/{embedId}/countries": {
      "get": {
        "tags": [
          "Media Embed"
        ],
        "summary": "List Embed Session Countries",
        "operationId": "media-embed-session-countries",
        "description": "Count sessions by country for one embed, most sessions first. Sessions with no known country are left out. Use a returned `country` value as the `country` filter on the session list. Members without access to all folders only see embeds for media and folders they can open. Any other embed, or an embed that is deleted or in another workspace, returns 404.",
        "parameters": [
          {
            "name": "embedId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{24}$"
            },
            "description": "The `_id` of the embed, as returned when you create or check an embed. Must be a 24 character hex id.",
            "example": "6650a1b2c3d4e5f6a7b8c9d0"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only sessions started at or after this time, as an ISO 8601 date. Optional. Leave it out for no lower bound.",
            "example": "2026-09-01T00:00:00.000Z"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only sessions started at or before this time, as an ISO 8601 date. Optional. Leave it out for no upper bound.",
            "example": "2026-09-30T23:59:59.999Z"
          },
          {
            "name": "traffic",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "people",
                "bots"
              ],
              "default": "all"
            },
            "description": "Which visits to count: everyone, only people, or only detected bots and crawlers. Optional. Defaults to `all`.",
            "example": "people"
          },
          {
            "name": "includeOwner",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Count visits by members of your own workspace. Optional. Defaults to `false`.",
            "example": "false"
          },
          {
            "name": "includeLegacy",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Include visits recorded before session tracking, which carry no timing, media or question numbers. Optional. Defaults to `false`.",
            "example": "false"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "countries": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "country": {
                                "type": "string",
                                "description": "Country name."
                              },
                              "sessions": {
                                "type": "integer"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "session-countries": {
                    "value": {
                      "status": "success",
                      "data": {
                        "countries": [
                          {
                            "country": "Canada",
                            "sessions": 120
                          },
                          {
                            "country": "United States",
                            "sessions": 87
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A query parameter failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Embed not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Error: Embed details not found!",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/embed/sessions/{embedId}/live": {
      "get": {
        "tags": [
          "Media Embed"
        ],
        "summary": "Get Live Embed Sessions",
        "operationId": "media-embed-session-live",
        "description": "How many people are on one embed right now: sessions active in the last minute, sessions still open but idle, and the time of the most recent activity. Legacy visits are never counted. Members without access to all folders only see embeds for media and folders they can open. Any other embed, or an embed that is deleted or in another workspace, returns 404.",
        "parameters": [
          {
            "name": "embedId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{24}$"
            },
            "description": "The `_id` of the embed, as returned when you create or check an embed. Must be a 24 character hex id.",
            "example": "6650a1b2c3d4e5f6a7b8c9d0"
          },
          {
            "name": "traffic",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "people",
                "bots"
              ],
              "default": "all"
            },
            "description": "Which visits to count: everyone, only people, or only detected bots and crawlers. Optional. Defaults to `all`.",
            "example": "people"
          },
          {
            "name": "includeOwner",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Count visits by members of your own workspace. Optional. Defaults to `false`.",
            "example": "false"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "liveNow": {
                          "type": "integer",
                          "description": "Open sessions with activity in the last minute."
                        },
                        "idleOpen": {
                          "type": "integer",
                          "description": "Open sessions with no activity in the last minute whose page is still open."
                        },
                        "lastActivityAt": {
                          "type": "string",
                          "nullable": true,
                          "format": "date-time",
                          "description": "Most recent activity on the embed. Null when there has been none."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "session-live": {
                    "value": {
                      "status": "success",
                      "data": {
                        "liveNow": 2,
                        "idleOpen": 1,
                        "lastActivityAt": "2026-09-30T16:41:07.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A query parameter failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Embed not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Error: Embed details not found!",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/prompt": {
      "get": {
        "tags": [
          "AI Chat"
        ],
        "summary": "All AI Chats",
        "operationId": "ai-chat-all-ai-chats",
        "description": "Get AI Chat History.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "totalCount": {
                          "type": "integer"
                        },
                        "pages": {
                          "type": "integer"
                        },
                        "history": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "prompt": {
                                "type": "string"
                              },
                              "answer": {
                                "type": "string"
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "assistantType": {
                                "type": "string"
                              },
                              "mediaName": {
                                "type": "string"
                              },
                              "mediaIds": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "state": {
                                "type": "string"
                              },
                              "link": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "list-of-prompts": {
                    "summary": "List of Prompts",
                    "value": {
                      "status": "success",
                      "data": {
                        "totalCount": 2,
                        "pages": 1,
                        "history": [
                          {
                            "id": "64b04ce76db5f05cba07a3ff",
                            "prompt": "Identify the top 5 action items to prioritize for maximum impact",
                            "answer": "",
                            "createdAt": "2023-07-13T19:13:43.953Z",
                            "assistantType": "general",
                            "mediaName": "How To Upload A Video File On Desktop",
                            "mediaIds": [
                              "de737309a4e9"
                            ],
                            "state": "failed",
                            "link": "https://app.speakai.co/media/insight/MEDIA_URL"
                          }
                        ]
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "AI Chat"
        ],
        "summary": "Ask AI Chat",
        "operationId": "ai-chat-ask-ai-chat",
        "description": "AI Chat API allows you to run your own prompt via API.\n\n`Prompt` (**required**) - It will be your query - please be as descriptive as possible to get an accurate output\n\n`assistantType` (**default: general**) - Allow values are - general, researcher, marketer, sales, recruiter\n\n`mediaIds` (**required**) - You can pass multiple `mediaIds` to run your prompt OR pass a single mediaId in an array\n\n**Request rules.** `prompt` is the only field you must send. `assistantTemplateId` becomes required when you set `assistantType` to `custom`; for every other value it is optional. You do not have to send `folderId` or `mediaIds`: a body with only `prompt` is accepted. Send one of them anyway, or the assistant has no material to read.\n\n**Streaming.** Send `isStream: true` to get the answer as Server-Sent Events instead of one JSON body. The response comes back as `text/event-stream` with `Cache-Control: no-cache` and `Connection: keep-alive`. Every frame is written as `data: <json>` followed by a blank line, with no `event:` or `id:` field, so read them as default message events. The stream ends on an `end` frame, or an `error` frame if it failed, and there is no `[DONE]` sentinel. The `end` frame carries `promptId`, `messageId` and `references`, the same `references` array the non-streaming response returns, so a streaming client can show the sources without a second request. `isStream: true` cannot be combined with `isIndividualPrompt: true`; that returns 400 with errorCode `STREAMING_NOT_SUPPORTED_FOR_INDIVIDUAL`.\n\n**Audio and video analysis.** Send `analysisMediaId` and `analysisInput` together to have the model take in the recording itself rather than only its transcript. `analysisMediaId` must be one of `mediaIds`. This is a premium feature billed in credits per hour of media on top of the normal chat cost, so price it with `GET /prompt/analysisQuote` before you commit to a run. When the file turns out to be ineligible the chat still answers from the transcript rather than failing, and no analysis credits are charged.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "The question or instruction you want the AI to answer. Send a non-empty string, and be specific to get a useful answer. Required. the schema.required rejects an empty string. No maximum length."
                  },
                  "isStream": {
                    "type": "boolean",
                    "description": "Set this to true to stream the answer back as Server-Sent Events instead of waiting for one JSON response. Optional. Schema default is false, but see the note on defaults. When true, send an Accept header of text/event-stream. Cannot be combined with isIndividualPrompt set to true: the route returns 400 with errorCode STREAMING_NOT_SUPPORTED_FOR_INDIVIDUAL."
                  },
                  "folderId": {
                    "type": "string",
                    "description": "The folder you want the AI to read from. Everything in that folder becomes the context for your prompt. Optional. Accepts an empty string or null. Schema default is an empty string."
                  },
                  "mediaIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The specific media items you want the AI to read. Pass one or more media ids, even when you only have one. Optional. Accepts null and an empty array. No item cap and no per-item length limit."
                  },
                  "folderIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Several folders you want the AI to read from at once. Use this instead of folderId when the context spans more than one folder. Optional. Accepts null and an empty array. No item cap. No default."
                  },
                  "assistantType": {
                    "type": "string",
                    "description": "The assistant persona that shapes the answer. Optional, and restricted to the values listed here: any other string is rejected, and so is an empty string. Omit it to use the default persona saved on your user profile, which falls back to \"general\" when you have not saved one. Speak resolves that fallback when it creates the chat, so it fixes the persona for the whole conversation. Sending \"custom\" makes assistantTemplateId required.",
                    "enum": [
                      "researcher",
                      "marketer",
                      "sales",
                      "general",
                      "recruiter",
                      "custom"
                    ]
                  },
                  "assistantTemplateId": {
                    "type": "string",
                    "description": "The id of your custom assistant template. Send this when you set assistantType to \"custom\". Conditionally required: required when assistantType is \"custom\", otherwise optional, accepts an empty string, and carries a schema default of an empty string. Does not accept null in either branch."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Tags that narrow the media the AI reads to only items carrying those tags. Optional. Accepts null and an empty array. No item cap. No default."
                  },
                  "speakers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Speaker names that narrow the transcript content the AI reads to only those speakers. Optional. Accepts null and an empty array. No item cap. No default."
                  },
                  "promptId": {
                    "type": "string",
                    "description": "The id of an existing chat you want to continue. Leave it out to start a new chat. Optional. Accepts an empty string or null. Schema default is an empty string."
                  },
                  "fieldId": {
                    "type": "string",
                    "description": "A single field you want the AI to fill or reference. Optional. Accepts an empty string. Does not accept null. No default."
                  },
                  "fieldIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Several fields you want the AI to fill or reference. Optional. Accepts null. Schema default is null. Maximum 10 items, and each item is at most 200 characters."
                  },
                  "isIndividualPrompt": {
                    "type": "boolean",
                    "description": "Set this to true to run the prompt separately against each media item instead of once across all of them. Optional. Schema default is false. Cannot be combined with isStream set to true; that combination returns 400."
                  },
                  "filters": {
                    "type": "object",
                    "description": "Extra filters that narrow which media the AI reads. Optional. Accepts null. The object's keys are not validated, so any object is accepted at the top level. No default."
                  },
                  "startDate": {
                    "type": "string",
                    "description": "Only include media created on or after this date. Optional. Send an ISO 8601 date string or a timestamp. Accepts null and carries a schema default of null."
                  },
                  "endDate": {
                    "type": "string",
                    "description": "Only include media created on or before this date. Optional. Send an ISO 8601 date string or a timestamp. Accepts null and carries a schema default of null."
                  },
                  "modelId": {
                    "type": "string",
                    "description": "The language model you want to answer this chat. Leave it out, or send an empty string or null, to use your company default. The models Speak AI offers today are `gemini-3.7-flash`, `gemini-3-flash-preview`, `gemini-3.5-flash`, `gemini-3.8-flash`, `gpt-5.6-terra`, `gpt-5.6-sol`, `gpt-5.5`, `gpt-5.4-mini-2026-03-17`, `claude-sonnet-5`, `claude-opus-4-8`, `claude-sonnet-4-6`, `x-ai/grok-4.5` and `z-ai/glm-5.2`. The full list below also holds older model ids that are still accepted so existing integrations keep working; treat those as deprecated and do not build against them.",
                    "enum": [
                      "gpt-3.5",
                      "gpt-3.5-turbo-16k",
                      "gpt-3.5-turbo-0125",
                      "gpt-4",
                      "gpt-4-1106-preview",
                      "gpt-4-turbo",
                      "gpt-4o-2024-05-13",
                      "gpt-4o",
                      "gpt-4o-mini",
                      "gpt-4o-2024-08-06",
                      "gpt-4o-mini-2024-07-18",
                      "gpt-4.1-2025-04-14",
                      "gpt-5.1-2025-11-13",
                      "gpt-5.2",
                      "gpt-5.4",
                      "gpt-5.4-mini",
                      "gpt-5.4-mini-2026-03-17",
                      "gpt-5.4-nano",
                      "gpt-5.5",
                      "gpt-5.5-thinking",
                      "gpt-5.6-sol",
                      "gpt-5.6-terra",
                      "gpt-5.6-luna",
                      "claude-2",
                      "claude-3-5-sonnet",
                      "claude-3-5-sonnet-20241022",
                      "claude-3-7-sonnet-latest",
                      "claude-haiku-4-5",
                      "claude-sonnet-4-6",
                      "claude-sonnet-5",
                      "claude-opus-4-8",
                      "gemini-1.5-pro",
                      "gemini-1.5-flash",
                      "gemini-2.0-flash",
                      "gemini-2.5-pro",
                      "gemini-2.5-flash",
                      "gemini-2.5-flash-lite",
                      "gemini-3-flash-preview",
                      "gemini-3.1-flash-lite",
                      "gemini-3.1-pro-preview",
                      "gemini-3.5-flash",
                      "gemini-3.7-flash",
                      "gemini-3.8-flash",
                      "x-ai/grok-4.5",
                      "z-ai/glm-5.2"
                    ]
                  },
                  "attachments": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "description": "The kind of file you are attaching. Required on every attachment.",
                          "enum": [
                            "image",
                            "pdf"
                          ]
                        },
                        "path": {
                          "type": "string",
                          "description": "The URL of the attached file, which must be a file your company owns. Required on every attachment. Must be a valid URI, and surrounding whitespace is trimmed. Ownership is checked after validation."
                        },
                        "mimeType": {
                          "type": "string",
                          "description": "The MIME type of the attached file. Optional. Accepts an empty string or null. Whitespace is trimmed. Not restricted to a value list on this endpoint."
                        },
                        "name": {
                          "type": "string",
                          "description": "A display name for the attached file. Optional. Accepts an empty string or null. Whitespace is trimmed."
                        }
                      }
                    },
                    "description": "Images or PDFs you want the AI to look at alongside your prompt. Optional. Accepts null. Maximum 10 items. Each item is an object with the keys described below, and unknown keys inside an item are rejected. After schema validation the route checks that every attachment path is an S3 URL under your company's prefix and returns 400 if it is not."
                  },
                  "analysisMediaId": {
                    "type": "string",
                    "description": "The media item you want the model to listen to or watch, instead of only reading its transcript. Optional. Accepts an empty string or null. Must also appear in mediaIds, and must be sent together with analysisInput. Sending one without the other is rejected with \"analysisMediaId and analysisInput must be provided together\". Sending an id that is not in mediaIds is rejected with \"analysisMediaId must be one of mediaIds\". Audio and video analysis is a premium feature: an account that is not enabled for it gets a 400. Call GET /prompt/analysisQuote first to check eligibility and price."
                  },
                  "analysisInput": {
                    "type": "string",
                    "description": "What the model should take in for analysisMediaId. Send \"audio\" to have it hear the recording, or \"video\" to have it watch the file. Optional. Accepts an empty string or null. Must be sent together with analysisMediaId. Asking for \"video\" on an audio-only file analyzes the audio instead of failing, and the turn is charged at the audio rate. Asking for \"audio\" on a video extracts the audio track first, which makes the request run longer. Omit both fields for a normal transcript-only chat.",
                    "enum": [
                      "audio",
                      "video"
                    ]
                  }
                },
                "required": [
                  "prompt"
                ]
              },
              "example": {
                "prompt": "Tell me how my speaking pace was. Did I speak too fast, at a good pace or too slowly? A good pace is between 140 and 170 words per minute. Less than 140 words per minute is too slow and more than 170",
                "mediaIds": [
                  "923884998a91"
                ],
                "assistantType": "general"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "promptId": {
                          "type": "string",
                          "description": "The chat this answer belongs to, a 12-character hex id such as `a3f19c47be02`. Pass it back as `promptId` to ask a follow-up question in the same chat."
                        },
                        "messageId": {
                          "type": "string",
                          "description": "The message within that chat, a 12-character hex id such as `7d2e845b1fa9`. Use it to retry, export or give feedback on this answer."
                        },
                        "state": {
                          "type": "string"
                        },
                        "answer": {
                          "type": "string"
                        },
                        "totalMedia": {
                          "type": "integer"
                        },
                        "references": {
                          "type": "array",
                          "items": {}
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "success-response": {
                    "summary": "Success Response",
                    "value": {
                      "status": "success",
                      "data": {
                        "promptId": "a3f19c47be02",
                        "messageId": "7d2e845b1fa9",
                        "state": "completed",
                        "answer": "Main discussion points:\n\n- The video demonstrates how to upload a video file through Speak.\n- The process involves signing in, accessing the dashboard, and hitting the upload butto...",
                        "totalMedia": 1,
                        "references": []
                      }
                    },
                    "x-abridged": true
                  }
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "object",
                  "description": "One SSE frame, written as `data: <json>` followed by a blank line.",
                  "properties": {
                    "type": {
                      "type": "string",
                      "enum": [
                        "start",
                        "chunk",
                        "end",
                        "error",
                        "media-count",
                        "step",
                        "resource_updated"
                      ],
                      "description": "What this frame carries. `chunk` holds a piece of the answer text. `end` closes a successful stream and `error` closes a failed one."
                    },
                    "promptId": {
                      "type": "string",
                      "description": "The chat this answer belongs to. Pass it back as `promptId` to continue the chat."
                    },
                    "messageId": {
                      "type": "string",
                      "description": "The message within that chat."
                    },
                    "content": {
                      "type": "string",
                      "description": "The text of this piece of the answer. Present on `chunk` frames."
                    },
                    "toolName": {
                      "type": "string",
                      "description": "The tool the assistant ran, when a step involved one."
                    },
                    "action": {
                      "type": "string",
                      "description": "A follow-up for the client. `add-balance` means the account ran out of credit."
                    },
                    "error": {
                      "type": "string",
                      "description": "Why the stream failed. Present on `error` frames."
                    },
                    "resource": {
                      "type": "string",
                      "enum": [
                        "transcript"
                      ],
                      "description": "A resource the server changed mid-stream, so you can refresh it."
                    },
                    "mediaId": {
                      "type": "string",
                      "description": "The media whose resource changed."
                    },
                    "references": {
                      "type": "array",
                      "description": "Where the answer came from, so you can link back into the recording.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "text": {
                            "type": "string",
                            "description": "The quoted passage."
                          },
                          "mediaId": {
                            "type": "string",
                            "description": "The media it came from."
                          },
                          "mediaName": {
                            "type": "string",
                            "description": "That media's name."
                          },
                          "timestamp": {
                            "type": "number",
                            "description": "Seconds into the recording where the passage starts."
                          },
                          "endTimestamp": {
                            "type": "number",
                            "description": "Seconds where it ends."
                          }
                        }
                      }
                    },
                    "metadata": {
                      "type": "object",
                      "description": "Present on the `end` frame.",
                      "properties": {
                        "responseTime": {
                          "type": "number",
                          "description": "How long the answer took, in milliseconds."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "started",
                            "executing",
                            "completed",
                            "failed"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/prompt/analysisQuote": {
      "get": {
        "tags": [
          "AI Chat"
        ],
        "summary": "Analysis Quote",
        "operationId": "ai-chat-analysis-quote",
        "description": "Check whether a media item can be analysed as audio or video, and what that will cost, before running a chat with `analysisInput`.\n\nThis is the only check that reflects both the account's premium opt-in and the platform-wide switch, so treat it as the answer on whether a run will work. An ineligible file is a normal `200` with `eligible: false` and a plain-English `reason`, not an error.\n\nThe quote shares its eligibility rules, duration cap, model resolution and credit conversion with the run itself, so the figure you get back is the figure the run is charged against.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The media item you want to price. Must belong to your company.",
            "example": "de737309a4e9"
          },
          {
            "name": "analysisInput",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "audio",
                "video"
              ]
            },
            "description": "What the model would take in. Use \"audio\" to have it hear the recording, or \"video\" to have it watch the file. Audio on a video file is priced for the extracted audio track, which costs a fraction of a video pass and reaches longer files.",
            "example": "audio"
          },
          {
            "name": "modelId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "gpt-3.5",
                "gpt-3.5-turbo-16k",
                "gpt-3.5-turbo-0125",
                "gpt-4",
                "gpt-4-1106-preview",
                "gpt-4-turbo",
                "gpt-4o-2024-05-13",
                "gpt-4o",
                "gpt-4o-mini",
                "gpt-4o-2024-08-06",
                "gpt-4o-mini-2024-07-18",
                "gpt-4.1-2025-04-14",
                "gpt-5.1-2025-11-13",
                "gpt-5.2",
                "gpt-5.4",
                "gpt-5.4-mini",
                "gpt-5.4-mini-2026-03-17",
                "gpt-5.4-nano",
                "gpt-5.5",
                "gpt-5.5-thinking",
                "gpt-5.6-sol",
                "gpt-5.6-terra",
                "gpt-5.6-luna",
                "claude-2",
                "claude-3-5-sonnet",
                "claude-3-5-sonnet-20241022",
                "claude-3-7-sonnet-latest",
                "claude-haiku-4-5",
                "claude-sonnet-4-6",
                "claude-sonnet-5",
                "claude-opus-4-8",
                "gemini-1.5-pro",
                "gemini-1.5-flash",
                "gemini-2.0-flash",
                "gemini-2.5-pro",
                "gemini-2.5-flash",
                "gemini-2.5-flash-lite",
                "gemini-3-flash-preview",
                "gemini-3.1-flash-lite",
                "gemini-3.1-pro-preview",
                "gemini-3.5-flash",
                "gemini-3.7-flash",
                "gemini-3.8-flash",
                "x-ai/grok-4.5",
                "z-ai/glm-5.2"
              ]
            },
            "description": "Price the run against a specific model. Optional. Leave it out and your company default is used, which is what the run itself would use.",
            "example": "gemini-3.7-flash"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "eligible": {
                          "type": "boolean",
                          "description": "Whether this file can be analysed with this analysisInput right now."
                        },
                        "reason": {
                          "type": "string",
                          "description": "Why the file cannot be analysed, in language you can show a user. Present only when eligible is false."
                        },
                        "credits": {
                          "type": "number",
                          "description": "Credits the analysis would cost, on top of the normal chat cost. Zero when the file is not eligible."
                        },
                        "seconds": {
                          "type": "number",
                          "description": "Duration of the media the quote was priced on, in seconds. Zero when the file is not eligible."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "eligible-file": {
                    "summary": "Eligible",
                    "value": {
                      "status": "success",
                      "data": {
                        "eligible": true,
                        "credits": 42,
                        "seconds": 1830
                      }
                    }
                  },
                  "ineligible-file": {
                    "summary": "Ineligible - too long for this account",
                    "value": {
                      "status": "success",
                      "data": {
                        "eligible": false,
                        "reason": "The file is longer than the analysis limit on this account. Raise the limit or trim the file.",
                        "credits": 0,
                        "seconds": 0
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "analysis-quote-media-not-found": {
                    "summary": "Analysis Quote - Media not found",
                    "value": {
                      "status": "failed",
                      "requestId": "ca665625-645e-438a-867d-366a6e3f133a",
                      "code": 404,
                      "message": "Requested media not found",
                      "hints": [
                        "Requested media not found"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/meeting-assistant/events": {
      "get": {
        "tags": [
          "Meeting Assistant Events"
        ],
        "summary": "Events List",
        "operationId": "meeting-assistant-events-events-list",
        "description": "Get All the Meeting Assistants Events.\n\nYou can have more flexibily by passing query params.\n\n`page` - Page number. Default is 0.\n\n`pageSize` - Total records per page. Default is 25.\n\n`platformType` - Default value is `\"\"`\n\nPlease ensure to pass the correct platformType from the list below:\n\n```\ngoogleMeet\nzoom\nmicrosoftTeams\nwebex\n\n ```\n\n`meetingStatus` - Default value is `\"\"`\n\nPlease ensure to pass the correct meetingStatus from the list below:\n\n```\nwillJoin\nscheduled\ncancelled\nready\njoiningCall\ninCallRecording\ncallEnded\n\n ```",
        "parameters": [
          {
            "name": "platformType",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "meetingStatus",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "example": "0"
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "example": "25"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "totalCount": {
                          "type": "integer"
                        },
                        "events": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "source": {
                                "type": "string"
                              },
                              "_id": {
                                "type": "string"
                              },
                              "currentStatus": {
                                "type": "string"
                              },
                              "companyId": {
                                "type": "string"
                              },
                              "userId": {
                                "type": "string"
                              },
                              "platform": {
                                "type": "string"
                              },
                              "title": {
                                "type": "string"
                              },
                              "meetingURL": {
                                "type": "string"
                              },
                              "startTime": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "meetingAssistantEventId": {
                                "type": "string"
                              },
                              "attendees": {
                                "type": "array",
                                "items": {}
                              },
                              "history": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "status": {
                                      "type": "string"
                                    },
                                    "createdAt": {
                                      "type": "string",
                                      "format": "date-time"
                                    }
                                  }
                                }
                              },
                              "chatMessages": {
                                "type": "array",
                                "description": "Messages in the meeting chat, oldest first, covering both what the assistant posted and the replies participants typed back. Present from 2026-08-18; older events recorded before that date have none.",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "messageType": {
                                      "type": "string",
                                      "description": "Which message this was. Use participant for a reply someone typed in the meeting chat.",
                                      "enum": [
                                        "welcome",
                                        "consent",
                                        "summary",
                                        "notify",
                                        "embedMediaPlayer",
                                        "leave",
                                        "participant"
                                      ]
                                    },
                                    "message": {
                                      "type": "string"
                                    },
                                    "createdAt": {
                                      "type": "string",
                                      "format": "date-time"
                                    },
                                    "direction": {
                                      "type": "string",
                                      "description": "Who sent the message. outbound is the assistant posting into the chat, inbound is a participant replying. Messages stored before this field existed read as outbound.",
                                      "enum": [
                                        "outbound",
                                        "inbound"
                                      ],
                                      "default": "outbound"
                                    },
                                    "sender": {
                                      "type": "string",
                                      "description": "Display name of the participant who sent an inbound message, as the meeting platform reports it. Absent on the assistant's own messages."
                                    }
                                  }
                                }
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "__v": {
                                "type": "integer"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "events-list": {
                    "summary": "Events List",
                    "value": {
                      "status": "success",
                      "data": {
                        "totalCount": 1,
                        "events": [
                          {
                            "source": "instant",
                            "_id": "64d2633e0d3c560cd10c73fd",
                            "currentStatus": "callEnded",
                            "companyId": "5e21xxxxx772xxxxxxx",
                            "userId": "5d0xxxxxxbca272xxxxxx",
                            "platform": "zoom",
                            "title": "Speak Ai Test Meeting",
                            "meetingURL": "{{vault:zoom-meeting-link}}",
                            "startTime": "2023-08-08T15:45:41.629Z",
                            "meetingAssistantEventId": "84f8f7d1cb13",
                            "attendees": [],
                            "history": [
                              {
                                "status": "joiningCall",
                                "createdAt": "2023-08-08T15:46:10.004Z"
                              }
                            ],
                            "chatMessages": [
                              {
                                "messageType": "consent",
                                "message": "This meeting is being recorded and transcribed by Speak AI. By staying in the meeting you consent to being recorded.",
                                "createdAt": "2023-08-08T15:46:12.220Z",
                                "direction": "outbound"
                              }
                            ],
                            "createdAt": "2023-08-08T15:46:06.570Z",
                            "updatedAt": "2023-08-08T16:31:15.046Z",
                            "__v": 0
                          }
                        ]
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Meeting Assistant Events"
        ],
        "summary": "Delete Scheduled Assistant",
        "operationId": "meeting-assistant-events-delete-scheduled-assistant",
        "description": "Delete `scheduled` assistant for an event.",
        "parameters": [
          {
            "name": "meetingAssistantEventId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "required field",
            "example": "7c583b090b1f"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string"
                        },
                        "data": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "delete-a-scheduled-meeting-assistant": {
                    "summary": "Delete a Scheduled Meeting Assistant",
                    "value": {
                      "status": "success",
                      "data": {
                        "status": "success",
                        "data": "Event Deleted Successfully"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/meeting-assistant/events/schedule": {
      "post": {
        "tags": [
          "Meeting Assistant Events"
        ],
        "summary": "Schedule Event",
        "operationId": "meeting-assistant-events-schedule-event",
        "description": "### Schedule Meeting Event\n\nThis endpoint allows you to schedule a meeting event by providing the meeting details.\n\n**Request Body**\n\n- `meetingDate` (optional): The date and time for the scheduled meeting. If not provided, the meeting will be joined instantly.\n\n- `meetingLanguage` (optional): The language for the meeting. Default is en-US.\n\n- `meetingURL` (required): The URL of the meeting.\n\n- `title` (required): The title of the meeting.\n\n- `tags` (optional): You can pass comma seprated values to store as tags for your media files.\n\n\n**Response**\n\n- `status`: The status of the response.\n\n- `data`: An object containing details of the scheduled meeting event, including the company ID, user ID, meeting assistant ID, platform, source, meeting URL, start time, title, meeting language, current status, event ID, attendees, history, chat messages, creation and update timestamps, and version.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "meetingURL": {
                    "type": "string",
                    "description": "The URL of the meeting you want the assistant to join. Required. Sent as a plain string. The format is not checked. The controller resolves the meeting platform from this URL and returns 400 with \"Invalid meeting url\" if it cannot."
                  },
                  "title": {
                    "type": "string",
                    "description": "The title you want to give the scheduled meeting and the media it produces. Optional. An empty string or null is treated as absent and the server falls back to \"Scheduled Meeting\". The title is trimmed before it is stored."
                  },
                  "meetingDate": {
                    "type": "string",
                    "description": "The date and time you want the assistant to join the meeting. Optional and nullable. Send an ISO 8601 date-time string. If you omit it, the assistant joins about one second from now."
                  },
                  "meetingLanguage": {
                    "type": "string",
                    "description": "The language code you want the meeting transcribed in. Optional and nullable. Must be one of the 137 supported transcription language codes, which include auto and multi. The list is too long to pin as an enum in the spec, so call GET /supported-languages for the current set. If you omit it, the server uses en-US."
                  },
                  "folderId": {
                    "type": "string",
                    "description": "The ID of the folder you want the resulting recording filed into. Optional. Empty string and null are both accepted. The folder is only attached when the value is non-empty."
                  }
                },
                "required": [
                  "meetingURL"
                ]
              },
              "example": {
                "title": "Team Standup",
                "meetingURL": "https://meet.google.com/abc-defg-hij",
                "meetingLanguage": "en-US",
                "meetingDate": "2026-06-01T10:00:00.000Z"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "companyId": {
                          "type": "string"
                        },
                        "userId": {
                          "type": "string"
                        },
                        "platform": {
                          "type": "string"
                        },
                        "source": {
                          "type": "string"
                        },
                        "meetingURL": {
                          "type": "string"
                        },
                        "startTime": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "title": {
                          "type": "string"
                        },
                        "meetingLanguage": {
                          "type": "string"
                        },
                        "currentStatus": {
                          "type": "string"
                        },
                        "_id": {
                          "type": "string"
                        },
                        "meetingAssistantEventId": {
                          "type": "string"
                        },
                        "attendees": {
                          "type": "array",
                          "items": {}
                        },
                        "history": {
                          "type": "array",
                          "items": {}
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "__v": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "schedule-event": {
                    "summary": "Schedule Event",
                    "value": {
                      "status": "success",
                      "data": {
                        "companyId": "5e28dd2d77242c222222222",
                        "userId": "5d03a9d225d42a272e9c229",
                        "platform": "googleMeet",
                        "source": "instant",
                        "meetingURL": "https://meet.google.com/ctg-wcqv-xxxx",
                        "startTime": "2023-12-19T20:20:06.823Z",
                        "title": "Meeting Title",
                        "meetingLanguage": "en-US",
                        "currentStatus": "scheduled",
                        "_id": "6581faf3e7435ce0e78ad6b0",
                        "meetingAssistantEventId": "89c69e5afcc3",
                        "attendees": [],
                        "history": [],
                        "createdAt": "2023-12-19T20:20:03.208Z",
                        "updatedAt": "2023-12-19T20:20:03.208Z",
                        "__v": 0,
                        "message": "Meeting scheduled Successfully"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/meeting-assistant/events/remove": {
      "post": {
        "tags": [
          "Meeting Assistant Events"
        ],
        "summary": "Remove Assistant from Meeting",
        "operationId": "meeting-assistant-events-remove-assistant-from-meeting",
        "description": "Remove the assistant from a meeting. POST with `meetingAssistantEventId` in the JSON body.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "meetingAssistantEventId": {
                    "type": "string",
                    "description": "The ID of the meeting assistant event you want the assistant removed from. Required."
                  }
                },
                "required": [
                  "meetingAssistantEventId"
                ]
              },
              "example": {
                "meetingAssistantEventId": "your_event_id_here"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string"
                        },
                        "data": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "remove-a-assistant-from-meeting": {
                    "summary": "Remove a Assistant From Meeting",
                    "value": {
                      "status": "success",
                      "data": {
                        "status": "success",
                        "data": "Meeting Assistant Removed Successfully"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/fields": {
      "get": {
        "tags": [
          "Fields"
        ],
        "summary": "Get All Fields",
        "operationId": "fields-get-all-fields",
        "description": "### Retrieve Fields\n\nThis endpoint makes an HTTP GET request to retrieve a list of fields.\n\n#### Request\n\nThe request does not require a request body. It simply makes a GET request to the endpoint `{{url}}/v1/fields`.\n\n#### Response\n\nThe response will be a JSON object representing the list of fields. Below is a JSON schema representing the structure of the response:\n\n``` json\n{\n \"type\": \"object\",\n \"properties\": {\n \"fields\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"fieldId\": {\n \"type\": \"string\"\n },\n \"name\": {\n \"type\": \"string\"\n },\n \"type\": {\n \"type\": \"string\"\n },\n \"description\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n}\n\n ```\n\nThe `fields` array contains objects with `fieldId`, `name`, `type`, and `description` properties, representing the details of each field.",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "get-all-fields": {
                    "summary": "Get All Fields",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Fields"
        ],
        "summary": "Create Field",
        "operationId": "fields-create-field",
        "description": "### Add Field\n\nThis endpoint allows you to add a new field.\n\n#### Request Body\n\n- `description` (string, required): A description of the field.\n\n- `name` (string, required): The name of the field.\n\n- `type` (string, required): The type of the field.\n\n- `privacyMode` (string, required): The privacy mode of the field. \"public\" or \"private\".\n\n\n#### Response\n\nThe response will contain the details of the newly added field.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name the field. This is the label you see in the app and the name you match on when you set values later. Required. Trimmed. No minimum or maximum length. The server trims the name and looks for an existing field with the same name in your company, so a duplicate returns 409, not 400."
                  },
                  "description": {
                    "type": "string",
                    "description": "Describe what the field is for. You can send an empty string. Optional. Empty string is accepted. the schema does not trim it, but the create helper trims it before saving and stores an empty string when you leave it out."
                  },
                  "type": {
                    "type": "string",
                    "description": "Set the data type the field stores. Required. Trimmed. The schema schema writes.allow(FieldType), which passes the enum object as an extra allowed value rather than constraining the string, so the validator accepts any non-empty string. An empty string is still rejected. A value outside the list fails when the field is saved, so a value outside the list fails when the field is saved.",
                    "enum": [
                      "text",
                      "url",
                      "boolean",
                      "date",
                      "datetime",
                      "number",
                      "currency"
                    ]
                  },
                  "isActive": {
                    "type": "boolean",
                    "description": "Set whether the field is active. Leave it out and the field is created active. Optional. The declared default is true, but the middleware only reads the validation error and discards the converted value. The default that actually applies comes from the create helper, which defaults the parameter to true, matching the model default."
                  },
                  "privacyMode": {
                    "type": "string",
                    "description": "Choose whether values for this field are visible publicly or kept private. Optional. Trimmed. Same.allow(MediaPrivacyMode) pattern as type, so the validator accepts any non-empty string and the model enforces the list. Leave it out and the model default applies, which is public.",
                    "enum": [
                      "public",
                      "private"
                    ]
                  },
                  "prompt": {
                    "type": "string",
                    "description": "Give the AI an instruction for filling this field automatically. Optional. Trimmed. Empty string is accepted."
                  },
                  "allowedValues": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "List the values a user can pick for this field. Optional. Every item must be a string. No cap on the number of items. Leave it out and the field is created with an empty list."
                  },
                  "allowedValuesMode": {
                    "type": "string",
                    "description": "Choose whether a user can pick one value from allowedValues or several. Optional. This is the one property the schema really constrains, with.valid(.Object.values(AllowedValuesMode)), so anything outside the list returns 400. the schema also declares.default('multiple'), but the middleware discards converted values, so the default that applies comes from the create helper (multiple.",
                    "enum": [
                      "single",
                      "multiple"
                    ]
                  },
                  "otherValues": {
                    "type": "boolean",
                    "description": "Allow a user to enter a value that is not in allowedValues. Optional. Leave it out and it is stored as false."
                  },
                  "notApplicableValues": {
                    "type": "string",
                    "description": "Set the text that marks this field as not applicable for a piece of media. Optional. Empty string is accepted. Leave it out and it is stored as an empty string."
                  }
                },
                "required": [
                  "name",
                  "type"
                ]
              },
              "example": {
                "description": "Currency",
                "name": "Currency",
                "type": "currency",
                "privacyMode": "public"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "create-field": {
                    "summary": "Create Field",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/fields/batch": {
      "post": {
        "tags": [
          "Fields"
        ],
        "summary": "Update Multiple Fields",
        "operationId": "fields-update-multiple-fields",
        "description": "Set custom field values across media. Scope with `folderId` (all media in a folder) and/or `mediaIds` (specific files). Each `fields` entry is `{ id, value }`.\n\n**Request rules.** Send either `folderId`, where an empty string counts, or a non-empty `mediaIds` array. Send neither and the request returns 400.\n\n**When nothing changes.** The endpoint compares every value against what the media already holds and writes only the differences. If no media matches your scope, or every entry you sent was dropped or already stored, the response is still `200` and its message reads `No field values changed`. Nothing else happens in that case: no `field_updated` automation runs, and no notification is raised. A request that does change something answers `Field Values are updated successfully` instead.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "folderId": {
                    "type": "string",
                    "description": "Set the values on every piece of media in this folder. Optional. Trimmed. Empty string is accepted, and the controller treats an empty string as a real target, matching media whose folderId is empty."
                  },
                  "mediaIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Set the values on these specific pieces of media. This takes precedence over folderId when you send both. Optional. Every item must be a string. No cap on the number of items. The controller checks mediaIds first, so folderId is ignored when the array is not empty."
                  },
                  "fields": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    },
                    "description": "List the field values you want to write. Required. Every item is an object with two keys: `id` (string, required, trimmed) is the field id, and `value` (required, any JSON type) is the value to store. The schema declares `value` as required with no type restriction, so a string, number, boolean, array or object is all accepted. No cap on the number of items. The controller drops any entry whose id or value is falsy, so sending an empty value, 0 or false does not clear a field."
                  }
                },
                "required": [
                  "fields"
                ]
              },
              "example": {
                "folderId": "your_folder_id_here",
                "mediaIds": [
                  "your_media_id_here"
                ],
                "fields": [
                  {
                    "id": "your_field_id_here",
                    "value": "The value you want to set"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "update-multiple-fields": {
                    "summary": "Update Multiple Fields",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/fields/{id}": {
      "put": {
        "tags": [
          "Fields"
        ],
        "summary": "Update Field By Id",
        "operationId": "fields-update-field-by-id",
        "description": "### Update Field Information\n\nThis endpoint allows you to update the information of a specific field.\n\n#### Request Body\n\n- `description` (string, required): The updated description of the field.\n\n- `name` (string, required): The new name of the field.\n\n\nExample:\n\n``` json\n{\n \"description\": \"Currency Description Updated\",\n \"name\": \"New Updated Name\",\n \"privacyMode\": \"public\"\n}\n\n ```\n\n#### Response\n\n- `status` (string): The status of the response.\n\n- `data` (object): An object containing the updated field information.\n\n - `id` (string): The ID of the field.\n\n - `name` (string): The name of the field.\n\n - `description` (string): The description of the field.\n\n - `type` (string): The type of the field.\n\n - `isActive` (boolean): Indicates if the field is active.\n\n - `privacyMode` (string): The privacy mode of the field.\n\n - `createdAt` (string): The date and time of creation.\n\n - `updatedAt` (string): The date and time of the last update.\n\n\nExample Response:\n\n``` json\n{\n \"status\": \"\",\n \"data\": {\n \"id\": \"\",\n \"name\": \"\",\n \"description\": \"\",\n \"type\": \"\",\n \"isActive\": true,\n \"privacyMode\": \"\",\n \"createdAt\": \"\",\n \"updatedAt\": \"\"\n }\n}\n\n ```\n\n#### Who can update a field\n\nAnyone in your company can update any field in it. The endpoint scopes the write to your company, not to the person who created the field.\n\n#### Sending the id in the body\n\nYou can also send `PUT {{url}}/v1/fields` with the field id in the request body instead of the path. Both forms run the same handler. Send the id in both places and the path value wins. Send it in neither and the request returns 400.\n\n#### Errors\n\n- `400` when no field id reaches the endpoint, in either the path or the body.\n- `404` when your company has no field with that id.\n- `409` when you change `name` to one that another field in your company already uses.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "0172d3abbdd1"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Identify the field to update. Optional here, because the path already carries the id. Trimmed. Send it in the body when you call `PUT /fields` with no id in the path. When you send both, the path value wins."
                  },
                  "name": {
                    "type": "string",
                    "description": "Set the field name. You have to send this key on every update, even when the name is not changing. Required, and an empty string is accepted. Unlike the create schema this one does not trim. When the name differs from the stored one the server checks for another field with that name in your company and returns 409 if it finds one."
                  },
                  "description": {
                    "type": "string",
                    "description": "Set what the field is for. You can send an empty string. Optional. Empty string is accepted. Not trimmed."
                  },
                  "privacyMode": {
                    "type": "string",
                    "description": "Choose whether values for this field are visible publicly or kept private. Optional. Trimmed. The schema schema writes.allow(MediaPrivacyMode), which does not constrain the string, so the validator accepts any non-empty string. The stored record enforces the list.",
                    "enum": [
                      "public",
                      "private"
                    ]
                  },
                  "type": {
                    "type": "string",
                    "description": "Change the data type the field stores. Optional. Trimmed. Same.allow(FieldType) pattern, so the validator accepts any non-empty string and the model enforces the list.",
                    "enum": [
                      "text",
                      "url",
                      "boolean",
                      "date",
                      "datetime",
                      "number",
                      "currency"
                    ]
                  },
                  "prompt": {
                    "type": "string",
                    "description": "Give the AI an instruction for filling this field automatically. Optional. Trimmed. Empty string is accepted."
                  },
                  "allowedValues": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Replace the list of values a user can pick for this field. Optional. Every item must be a string. No cap on the number of items."
                  },
                  "allowedValuesMode": {
                    "type": "string",
                    "description": "Choose whether a user can pick one value from allowedValues or several. Optional. Enforced by the schema with.valid(.Object.values(AllowedValuesMode)), so anything outside the list returns 400. No default on the update schema.",
                    "enum": [
                      "single",
                      "multiple"
                    ]
                  },
                  "otherValues": {
                    "type": "boolean",
                    "description": "Allow a user to enter a value that is not in allowedValues. Optional."
                  },
                  "notApplicableValues": {
                    "type": "string",
                    "description": "Set the text that marks this field as not applicable for a piece of media. Optional. Empty string is accepted."
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "description": "Currency Description Updated",
                "name": "New Updated Name",
                "privacyMode": "public"
              }
            }
          }
        },
        "responses": {
          "400": {
            "description": "No field id was supplied in either the path or the body"
          },
          "404": {
            "description": "No field with that id exists in your company"
          },
          "409": {
            "description": "Another field in your company already uses that name"
          },
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "update-field-by-id": {
                    "summary": "Update Field By Id",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/automations": {
      "get": {
        "tags": [
          "Automations"
        ],
        "summary": "Get Automations",
        "operationId": "automations-get-automations",
        "description": "The endpoint retrieves a list of automations via an HTTP GET request to {{url}}/v1/automations.\n\n### Response\n\nThe response will be in the form of a JSON schema, with the following structure:\n\n``` json\n{\n \"status\": \"\",\n \"data\": {\n \"totalCount\": 0,\n \"automationList\": [\n {\n \"trigger\": {\n \"folderIds\": [\n {\n \"name\": \"\",\n \"folderId\": \"\"\n }\n ],\n \"values\": [],\n \"type\": \"\"\n },\n \"action\": {\n \"magicPrompt\": {\n \"title\": \"\",\n \"assistantType\": \"\",\n \"prompt\": \"\"\n },\n \"type\": \"\"\n },\n \"name\": \"\",\n \"description\": \"\",\n \"runType\": \"\",\n \"isActive\": true,\n \"automationId\": \"\",\n \"actionHistory\": [\n {\n \"type\": \"\"\n }\n ],\n \"createdAt\": \"\",\n \"updatedAt\": \"\",\n \"history\": 0\n }\n ]\n }\n}\n\n ```\n\nThe response will have a status code of 200 upon successful retrieval of the automation list.\n\nFor related responses from other endpoints of this API, the data model will be largely similar, with the addition of \"email\", \"accessToken\", and \"refreshToken\" fields in the \"data\" object, and a status code of 200.",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "get-automations": {
                    "summary": "Get Automations",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Automations"
        ],
        "summary": "Create Automation",
        "operationId": "automations-create-automation",
        "description": "The API request creates an automation by sending an HTTP POST request to the specified endpoint. The request body is in JSON format and includes the name, description, runType, trigger, and action details. The trigger type is \"folders\" with specific folder IDs, and the action type is \"magic-prompt\" with associated details like title, assistantType, prompt, and assistantTemplateId.\n\nThe last call to this request used the following payload with the raw request body type:\n\n``` json\n{\n \"name\": \"First Automation\",\n \"description\": \"Test\",\n \"action\": {\n \"type\": \"magic-prompt\",\n \"magicPrompt\": {\n \"prompt\": \"Summarize my meetings\",\n \"assistantType\": \"general\"\n }\n },\n \"trigger\": {\n \"type\": \"folders\",\n \"folderIds\": [\"3711858e52a6\"]\n }\n}\n\n ```\n\nThe response to the last execution returned a 200 status code with the following content in JSON format:\n\n``` json\n{\n \"status\": \"\",\n \"data\": {\n \"automationId\": \"\",\n \"message\": \"\"\n }\n}\n\n ```\n\nAdditionally, related responses from other endpoints of this API also returned 200 status codes with similar data models, including email, access token, refresh token, totalCount, automation list, and trigger details.\n\nPlease note that the specific values (such as automationId, email, accessToken, refreshToken, folderIds, etc.) have been intentionally masked for privacy.\n\n### 1\\. **Instant Automation with AI Chat Action**\n\n**Body (JSON):**\n\n``` json\n{\n \"name\": \"Instant Folder Analysis\",\n \"description\": \"Automatically analyze documents in specific folders using AI assistant\",\n \"runType\": \"instant\",\n \"trigger\": {\n \"type\": \"folders\",\n \"folderIds\": [\"folder123\", \"folder456\"]\n },\n \"action\": {\n \"type\": \"magic-prompt\",\n \"magicPrompt\": {\n \"title\": \"Document Analysis\",\n \"assistantType\": \"researcher\",\n \"prompt\": \"Analyze the document content and provide key insights, main topics, and actionable recommendations.\",\n \"assistantTemplateId\": \"template123\"\n }\n },\n \"fieldId\": \"field789\"\n}\n\n ```\n\n### 2\\. **Scheduled Automation with Translation Action**\n\n**Method:** `POST`\n\n**Body (JSON):**\n\n``` json\n{\n \"name\": \"Weekly Document Translation\",\n \"description\": \"Translate documents in selected folders every week\",\n \"runType\": \"schedule\",\n \"schedule\": {\n \"timePeriod\": \"last7days\",\n \"repeatAt\": \"09:00\"\n },\n \"trigger\": {\n \"type\": \"folders\",\n \"folderIds\": [\"folder789\", \"folder101\"]\n },\n \"action\": {\n \"type\": \"translation\",\n \"translation\": {\n \"targetLanguage\": \"spanish\"\n }\n }\n}\n\n ```\n\n### 3\\. **Instant Automation with Custom AI Chat**\n\n**Method:** `POST`\n\n**Body (JSON):**\n\n``` json\n{\n \"name\": \"Sales Lead Analysis\",\n \"description\": \"Analyze potential leads and generate sales insights\",\n \"runType\": \"instant\",\n \"trigger\": {\n \"type\": \"folders\",\n \"folderIds\": [\"leads-folder\"]\n },\n \"action\": {\n \"type\": \"magic-prompt\",\n \"magicPrompt\": {\n \"title\": \"Sales Intelligence\",\n \"assistantType\": \"sales\",\n \"prompt\": \"Review the lead information and provide: 1) Lead quality score (1-10), 2) Key pain points identified, 3) Recommended follow-up strategy, 4) Potential deal size estimate\",\n \"assistantTemplateId\": \"\"\n }\n }\n}\n\n ```\n\n### 4\\. **Scheduled Automation with Marketing Analysis**\n\n**Method:** `POST`\n\n**Body (JSON):**\n\n``` json\n{\n \"name\": \"Daily Marketing Report\",\n \"description\": \"Generate daily marketing insights from campaign data\",\n \"runType\": \"schedule\",\n \"schedule\": {\n \"timePeriod\": \"yesterday\",\n \"repeatAt\": \"08:00\"\n },\n \"trigger\": {\n \"type\": \"folders\",\n \"folderIds\": [\"marketing-data\", \"campaign-reports\"]\n },\n \"action\": {\n \"type\": \"magic-prompt\",\n \"magicPrompt\": {\n \"title\": \"Marketing Daily Digest\",\n \"assistantType\": \"marketer\",\n \"prompt\": \"Analyze yesterday's marketing data and provide: 1) Top performing campaigns, 2) Key metrics summary, 3) Trends identified, 4) Recommendations for today\",\n \"assistantTemplateId\": \"marketing-template-001\"\n }\n },\n \"fieldId\": \"marketing-field-123\"\n}\n\n ```\n\n## **Available Enum Values:**\n\n**Run Types:**\n\n- `\"instant\"` - Executes immediately when triggered\n\n- `\"schedule\"` - Executes based on schedule configuration\n\n\n**Trigger Types:**\n\n- `\"folders\"` - Triggered by folder changes\n\n- `\"tags\"` - Triggered by tag changes\n\n- `\"keywords\"` - Triggered by keyword matches\n\n\n**Action Types:**\n\n- `\"magic-prompt\"` - AI-powered content analysis\n\n- `\"translation\"` - Document translation\n\n\n**Assistant Types (for magic-prompt):**\n\n- `\"researcher\"`, `\"marketer\"`, `\"sales\"`, `\"general\"`, `\"recruiter\"`, `\"custom\"`\n\n\n**Schedule Time Periods:**\n\n- `\"today\"`, `\"yesterday\"`, `\"last7days\"`, `\"last14days\"`, `\"thisWeek\"`\n\n\nThese examples cover both instant and scheduled automation types with different actions. Make sure to replace the placeholder values (folder IDs, template IDs, etc.) with actual values from your system.\n\n**Request rules.** `schedule` is required only when `runType` is `schedule`, and then both `schedule.timePeriod` and `schedule.repeatAt` are required too. For any other `runType`, `schedule` is optional. Each step's config object has to match that step's `stepType`; a mismatched config is rejected with a 400.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name the automation. This is what you see in the automations list. required, max length 150"
                  },
                  "description": {
                    "type": "string",
                    "description": "Describe what the automation does. You can send an empty string. optional, max length 1000, empty string allowed"
                  },
                  "isActive": {
                    "type": "boolean",
                    "description": "Set whether the automation runs after you create it. Leave it out and the automation is created active. optional. The schema.default(true) is not what produces this: the controller writes isActive only when you send a boolean, and the stored record defaults to true."
                  },
                  "runOnceOnly": {
                    "type": "string",
                    "description": "Ignore this field. The server accepts it and then never reads it, so whatever you send has no effect. optional. unconstrained.strip, so any JSON type passes validation. The.strip has no runtime effect here because RequestValidation discards the validated value; the field is simply never read by the controller, so it is never persisted.",
                    "deprecated": true
                  },
                  "trigger": {
                    "type": "object",
                    "description": "Define the single event that starts the automation. required, unknown keys rejected",
                    "properties": {
                      "type": {
                        "type": "string",
                        "description": "Pick the kind of event that starts the automation. required inside trigger; values come from the AutomationTrigger list",
                        "enum": [
                          "folders",
                          "tags",
                          "keywords",
                          "composio",
                          "webhook"
                        ]
                      },
                      "folderIds": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "List the folders the trigger watches. Folder triggers need this; other trigger types do not send it. optional. The item schema is unconstrained: the code is the schema.optional with no.items, so any item type passes."
                      },
                      "values": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Send the secondary list a trigger needs, such as the field IDs for a field-updated event. The server saves it verbatim. optional, items must be strings, empty strings allowed as items"
                      },
                      "provider": {
                        "type": "string",
                        "description": "Say which system owns the trigger. optional; the two values are written inline in the schema, not drawn from an enum",
                        "enum": [
                          "speak",
                          "composio"
                        ]
                      },
                      "app": {
                        "type": "string",
                        "description": "Name the third-party app for a Composio trigger. optional, empty string allowed, no length cap"
                      },
                      "triggerSlug": {
                        "type": "string",
                        "description": "Give the provider's slug for the specific trigger you picked. optional, empty string allowed, no length cap"
                      },
                      "webhookId": {
                        "type": "string",
                        "description": "Attach an inbound webhook to the trigger by its ID. optional, empty string allowed, no length cap"
                      },
                      "childKey": {
                        "type": "string",
                        "description": "Point the trigger at a nested key inside the incoming payload. optional, empty string allowed, no length cap"
                      },
                      "connectedAccountId": {
                        "type": "string",
                        "description": "Identify the connected account the trigger authenticates through. optional, empty string allowed. Unlike triggers[].connectedAccountId this one is not trimmed and has no max length."
                      },
                      "fieldValueMatches": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "fieldId": {
                              "type": "string",
                              "description": "Identify the field to match on. required inside each entry, trimmed, min length 1, max length 100"
                            },
                            "values": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "List the values that count as a match. Send an empty array to match any value. required inside each entry, max 50 items, each item max length 200, empty strings allowed"
                            }
                          }
                        },
                        "description": "Only fire the trigger when the named fields hold the values you list. optional, max 20 entries"
                      },
                      "fieldMatchLogic": {
                        "type": "string",
                        "description": "Choose whether every fieldValueMatches entry has to match or just one. Leaving it out behaves like OR. optional",
                        "enum": [
                          "AND",
                          "OR"
                        ]
                      },
                      "triggerConfig": {
                        "type": "object",
                        "description": "Pass provider-specific trigger settings, such as a watched folder ID. The server stores this object as sent and the provider catalog decides its shape. optional, unconstrained object"
                      }
                    }
                  },
                  "triggers": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "description": "Pick the kind of event for this alternative trigger. optional here, unlike trigger.type which is required",
                          "enum": [
                            "folders",
                            "tags",
                            "keywords",
                            "composio",
                            "webhook"
                          ]
                        },
                        "folderIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "List the folders this alternative trigger watches. optional, item schema unconstrained (the schema with no.items)"
                        },
                        "values": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Send the secondary list this alternative trigger needs. optional, items must be strings, empty strings allowed as items"
                        },
                        "provider": {
                          "type": "string",
                          "description": "Say which system owns this alternative trigger. optional",
                          "enum": [
                            "speak",
                            "composio"
                          ]
                        },
                        "app": {
                          "type": "string",
                          "description": "Name the third-party app for this alternative Composio trigger. optional, empty string allowed"
                        },
                        "triggerSlug": {
                          "type": "string",
                          "description": "Give the provider's slug for this alternative trigger. optional, empty string allowed"
                        },
                        "fieldValueMatches": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          },
                          "description": "Only fire this alternative trigger when the named fields hold the values you list. optional, max 20 entries, same fieldId and values shape as trigger.fieldValueMatches"
                        },
                        "fieldMatchLogic": {
                          "type": "string",
                          "description": "Choose whether every fieldValueMatches entry has to match or just one for this alternative trigger. optional",
                          "enum": [
                            "AND",
                            "OR"
                          ]
                        },
                        "triggerConfig": {
                          "type": "object",
                          "description": "Pass provider-specific settings for this alternative trigger. optional, unconstrained object"
                        },
                        "connectedAccountId": {
                          "type": "string",
                          "description": "Identify the connected account this alternative trigger authenticates through. optional, trimmed, max length 100, empty string allowed"
                        }
                      }
                    },
                    "description": "Add extra alternative triggers. The automation runs when any one of them fires. Leave it out or send an empty array for a single-trigger automation. optional, max 10 entries"
                  },
                  "steps": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "stepId": {
                          "type": "string",
                          "description": "Give the step an ID that is unique within this automation. Other steps reference it through dependsOn. required, trimmed, min length 1, max length 100"
                        },
                        "stepType": {
                          "type": "string",
                          "description": "Say what kind of work the step does. This decides which config object the step must carry. required; values come from the AutomationStepType list",
                          "enum": [
                            "trigger",
                            "magic-prompt",
                            "translation",
                            "composio-action",
                            "filter",
                            "speak-upload",
                            "notify",
                            "outbound-webhook",
                            "condition"
                          ]
                        },
                        "magicPrompt": {
                          "type": "object",
                          "description": "Configure an AI prompt step. required when stepType is \"magic-prompt\", rejected for any other stepType. One step extracts at most 25 fields through fieldIds; send more and the request is rejected with 400. Split a longer rubric across several magic-prompt steps.",
                          "properties": {
                            "title": {
                              "type": "string",
                              "description": "Title the prompt so you can recognize its output later. optional, empty string allowed, no length cap"
                            },
                            "modelId": {
                              "type": "string",
                              "description": "Override the model for this step. Send an empty string or null to clear it and fall back to your company default. optional; all 43 values copied verbatim from LLMModels.ts. '' and null are coerced to absent. empty(the schema) and are not enum members. The enum's header comment states that within each provider the DEPRECATED models are grouped first and the LIVE ones follow, but it carries no per-value flag, so no individual value can be marked deprecated from the code.",
                              "enum": [
                                "gpt-3.5",
                                "gpt-3.5-turbo-16k",
                                "gpt-3.5-turbo-0125",
                                "gpt-4",
                                "gpt-4-1106-preview",
                                "gpt-4-turbo",
                                "gpt-4o-2024-05-13",
                                "gpt-4o",
                                "gpt-4o-mini",
                                "gpt-4o-2024-08-06",
                                "gpt-4o-mini-2024-07-18",
                                "gpt-4.1-2025-04-14",
                                "gpt-5.1-2025-11-13",
                                "gpt-5.2",
                                "gpt-5.4",
                                "gpt-5.4-mini",
                                "gpt-5.4-mini-2026-03-17",
                                "gpt-5.4-nano",
                                "gpt-5.5",
                                "gpt-5.5-thinking",
                                "gpt-5.6-sol",
                                "gpt-5.6-terra",
                                "gpt-5.6-luna",
                                "claude-2",
                                "claude-3-5-sonnet",
                                "claude-3-5-sonnet-20241022",
                                "claude-3-7-sonnet-latest",
                                "claude-haiku-4-5",
                                "claude-sonnet-4-6",
                                "claude-sonnet-5",
                                "claude-opus-4-8",
                                "gemini-1.5-pro",
                                "gemini-1.5-flash",
                                "gemini-2.0-flash",
                                "gemini-2.5-pro",
                                "gemini-2.5-flash",
                                "gemini-2.5-flash-lite",
                                "gemini-3-flash-preview",
                                "gemini-3.1-flash-lite",
                                "gemini-3.1-pro-preview",
                                "gemini-3.5-flash",
                                "gemini-3.7-flash",
                                "gemini-3.8-flash",
                                "x-ai/grok-4.5",
                                "z-ai/glm-5.2"
                              ]
                            },
                            "prompt": {
                              "type": "string",
                              "description": "Write the instruction the model follows. max length 20000; required unless fieldIds is present with at least one entry, in which case an empty string is accepted. The declared default is '' on that branch but the default is never persisted, because the controller reads raw req.body."
                            },
                            "assistantType": {
                              "type": "string",
                              "description": "Pick the assistant persona that answers the prompt. Optional, and restricted to the values listed here: any other string is rejected. Omitting it stores no value on the step. When the step runs, the persona falls back to the default saved on the user profile the run belongs to, and to 'general' when none is saved.",
                              "enum": [
                                "researcher",
                                "marketer",
                                "sales",
                                "general",
                                "recruiter",
                                "custom"
                              ]
                            },
                            "assistantTemplateId": {
                              "type": "string",
                              "description": "Identify your custom assistant template. required when assistantType is \"custom\"; otherwise optional and accepts '' or null. The declared default is '' on the otherwise branch but the default is not persisted."
                            },
                            "isIndividualFolder": {
                              "type": "boolean",
                              "description": "Run the prompt separately per folder instead of once across everything. optional. The declared default is false but the default is not persisted; the model carries no default either."
                            },
                            "allowedValues": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Restrict the answer to this list of values. optional, items must be strings, no item cap"
                            },
                            "allowedValuesMode": {
                              "type": "string",
                              "description": "Choose whether the answer may pick one allowed value or several. optional; values come from the AllowedValuesMode list. The declared default is 'multiple' but the default is not persisted.",
                              "enum": [
                                "single",
                                "multiple"
                              ]
                            },
                            "otherValues": {
                              "type": "boolean",
                              "description": "Let the answer fall outside the allowed values list. optional"
                            },
                            "notApplicableValues": {
                              "type": "string",
                              "description": "Say what the model should answer when nothing applies. optional, empty string allowed"
                            },
                            "fieldId": {
                              "type": "string",
                              "description": "Write the answer into this single field. optional, accepts '' or null"
                            },
                            "fieldIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Extract several fields in one step. Sending at least one field ID makes prompt optional. optional, max 25 items. Over the cap the request is rejected with 400 and the message \"A single AI step can extract at most 25 fields. Split the rest into another AI step.\""
                            }
                          }
                        },
                        "translation": {
                          "type": "object",
                          "description": "Configure a translation step. required when stepType is \"translation\", rejected for any other stepType",
                          "properties": {
                            "targetLanguage": {
                              "type": "string",
                              "description": "Pick the language to translate into. required inside translation. The accepted set is TranslationLanguageCodes, defined by mapping the static TranslationLanguages array (lines 6-118) to its transcriptionCode. That array holds 111 entries, so there are exactly 111 accepted values, listed here in source order. Reached through translationLanguageCode.",
                              "enum": [
                                "en-US",
                                "fr-FR",
                                "af-ZA",
                                "ar-SA",
                                "hy-AM",
                                "bg-BG",
                                "ca-ES",
                                "hr-HR",
                                "cs-CZ",
                                "da-DK",
                                "nl-NL",
                                "et-EE",
                                "fa-IR",
                                "fi-FI",
                                "de-DE",
                                "el-GR",
                                "gu-IN",
                                "he-IL",
                                "hi-IN",
                                "ht-HT",
                                "hu-HU",
                                "id-ID",
                                "is-IS",
                                "it-IT",
                                "ga-IE",
                                "ja-JP",
                                "kn-IN",
                                "ko-KR",
                                "lt-LT",
                                "lv-LV",
                                "ml-IN",
                                "ms-MY",
                                "nb-NO",
                                "pl-PL",
                                "pt-PT",
                                "ro-RO",
                                "ru-RU",
                                "es-ES",
                                "sk-SK",
                                "sl-SI",
                                "sv-SE",
                                "ta-IN",
                                "te-IN",
                                "th-TH",
                                "tr-TR",
                                "uk-UA",
                                "vi-VN",
                                "as-IN",
                                "ay-BO",
                                "bm-ML",
                                "eu-ES",
                                "be-BY",
                                "bho-IN",
                                "ceb-PH",
                                "co-FR",
                                "dv-MV",
                                "doi-IN",
                                "eo-XX",
                                "ee-GH",
                                "fil-PH",
                                "fy-NL",
                                "gl-ES",
                                "gn-PY",
                                "haw-US",
                                "hmn-CN",
                                "ig-NG",
                                "ilo-PH",
                                "jv-ID",
                                "km-KH",
                                "rw-RW",
                                "gom-IN",
                                "kri-SL",
                                "ku-TR",
                                "ckb-IQ",
                                "ky-KG",
                                "lo-LA",
                                "la-VA",
                                "ln-CG",
                                "lg-UG",
                                "lb-LU",
                                "mai-IN",
                                "mg-MG",
                                "mi-NZ",
                                "mni-IN",
                                "lus-IN",
                                "my-MM",
                                "ne-NP",
                                "ny-MW",
                                "or-IN",
                                "om-ET",
                                "qu-PE",
                                "sm-WS",
                                "sa-IN",
                                "gd-GB",
                                "nso-ZA",
                                "st-ZA",
                                "sn-ZW",
                                "sd-PK",
                                "si-LK",
                                "su-ID",
                                "tg-TJ",
                                "tt-RU",
                                "ti-ER",
                                "ts-ZA",
                                "tk-TM",
                                "ak-GH",
                                "ug-CN",
                                "xh-ZA",
                                "yi-XX",
                                "yo-NG",
                                "zu-ZA"
                              ]
                            }
                          }
                        },
                        "filter": {
                          "type": "object",
                          "description": "Configure a filter step that stops the run when its rules do not match. required when stepType is \"filter\", rejected for any other stepType. Declared inline in automationStep, not as a shared fragment.",
                          "properties": {
                            "logic": {
                              "type": "string",
                              "description": "Choose whether every rule has to match or just one. optional. The declared default is 'AND' but the default is not persisted, because the controller reads raw req.body and the model carries no default.",
                              "enum": [
                                "AND",
                                "OR"
                              ]
                            },
                            "rules": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "field": {
                                    "type": "string",
                                    "description": "Name the field the rule reads. required, trimmed, min length 1, max length 100"
                                  },
                                  "op": {
                                    "type": "string",
                                    "description": "Pick how the rule compares the field to the value. required; the eight values are written inline in the schema, not drawn from an enum",
                                    "enum": [
                                      "eq",
                                      "neq",
                                      "contains",
                                      "ncontains",
                                      "startsWith",
                                      "gt",
                                      "lt",
                                      "exists"
                                    ]
                                  },
                                  "value": {
                                    "type": "string",
                                    "description": "Give the value to compare against. You can send a string or a number. optional. Declared as a union.max(1000).allow(''), the schema), so the real type is a string-or-number union that a single OpenAPI type cannot express."
                                  }
                                }
                              },
                              "description": "List the conditions the filter checks. required, min 1 entry, max 20 entries"
                            }
                          }
                        },
                        "condition": {
                          "type": "object",
                          "description": "Configure a branching step that sends the run down a true or false path. required when stepType is \"condition\", rejected for any other stepType. Declared inline with the identical logic and rules shape as steps[].filter.",
                          "properties": {
                            "logic": {
                              "type": "string",
                              "description": "Choose whether every rule has to match or just one. optional. The declared default is 'AND' but the default is not persisted.",
                              "enum": [
                                "AND",
                                "OR"
                              ]
                            },
                            "rules": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              },
                              "description": "List the conditions the branch evaluates. required, min 1 entry, max 20 entries, same field, op and value shape as filter rules"
                            }
                          }
                        },
                        "composio": {
                          "type": "object",
                          "description": "Configure a step that runs a Composio app action. required when stepType is \"composio-action\", rejected for any other stepType",
                          "properties": {
                            "app": {
                              "type": "string",
                              "description": "Name the Composio app to act on. required, trimmed, min length 1, max length 100"
                            },
                            "action": {
                              "type": "string",
                              "description": "Name the action to run in that app. required, trimmed, min length 1, max length 200"
                            },
                            "connectedAccountId": {
                              "type": "string",
                              "description": "Identify the connected account the action runs as. optional, trimmed, max length 100, empty string allowed"
                            },
                            "argsTemplate": {
                              "type": "object",
                              "description": "Pass the action's arguments. Values may contain tokens, so the server accepts any shape. optional, unconstrained object"
                            },
                            "destructive": {
                              "type": "boolean",
                              "description": "Mark the action as destructive so it asks for confirmation. optional"
                            },
                            "acknowledged": {
                              "type": "boolean",
                              "description": "Confirm you accept a destructive action. optional"
                            }
                          }
                        },
                        "speakUpload": {
                          "type": "object",
                          "description": "Configure a step that uploads media into Speak. required when stepType is \"speak-upload\", rejected for any other stepType",
                          "properties": {
                            "name": {
                              "type": "string",
                              "description": "Name the uploaded media. optional, max length 500, empty string allowed"
                            },
                            "folderId": {
                              "type": "string",
                              "description": "Choose the folder the upload lands in. In dynamic routing this becomes the fallback folder instead. required (trimmed, min length 1, max length 100) unless folderRouting.mode is \"dynamic\", in which case it is optional (trimmed, max 100, empty string allowed)"
                            },
                            "sourceMode": {
                              "type": "string",
                              "description": "Say whether the upload comes from a URL or from a file already in the run. required",
                              "enum": [
                                "url",
                                "file"
                              ]
                            },
                            "sourceUrl": {
                              "type": "string",
                              "description": "Give the URL to fetch the media from. max length 2000; required when sourceMode is \"url\", otherwise optional and may be an empty string. Not validated as a URI, because it may carry {{tokens}}."
                            },
                            "fieldsMap": {
                              "type": "object",
                              "description": "Map field names to values to set on the uploaded media. optional, declared as the schema.pattern(the schema, the schema), so keys and values must both be strings"
                            },
                            "language": {
                              "type": "string",
                              "description": "Set the language for the upload. You can send a language code or a token that resolves at run time, so known codes are not enforced. optional, max length 100, empty string allowed"
                            },
                            "waitForProcessing": {
                              "type": "boolean",
                              "description": "Hold the automation until the uploaded media finishes processing before the next step runs. optional"
                            },
                            "folderRouting": {
                              "type": "object",
                              "description": "Route the upload to a folder chosen from the incoming payload instead of a fixed one. optional",
                              "properties": {
                                "mode": {
                                  "type": "string",
                                  "description": "Choose between the fixed folderId and a folder picked from the payload. required inside folderRouting, so sending folderRouting without mode returns a 400",
                                  "enum": [
                                    "static",
                                    "dynamic"
                                  ]
                                },
                                "sourceKey": {
                                  "type": "string",
                                  "description": "Name the payload key that holds the folder to route to. required (trimmed, min length 1, max length 500) when mode is \"dynamic\"; otherwise optional, trimmed, max length 500, empty string allowed"
                                },
                                "onNoMatch": {
                                  "type": "string",
                                  "description": "Say what to do when no folder matches: create one, or fall back to the folderId. required when mode is \"dynamic\", otherwise optional. Same two values on both branches.",
                                  "enum": [
                                    "create",
                                    "default"
                                  ]
                                }
                              }
                            }
                          }
                        },
                        "notify": {
                          "type": "object",
                          "description": "Configure a notification step. required when stepType is \"notify\", rejected for any other stepType",
                          "properties": {
                            "channel": {
                              "type": "string",
                              "description": "Pick where the notification goes. required; the three values are written inline in the schema",
                              "enum": [
                                "in_app",
                                "email",
                                "slack"
                              ]
                            },
                            "target": {
                              "type": "string",
                              "description": "Name the recipient, such as an email address or a Slack channel. optional, max length 500, empty string allowed"
                            },
                            "message": {
                              "type": "string",
                              "description": "Write the notification body. It may contain {{tokens}}, so the server accepts any text. optional, max length 20000, empty string allowed. The in_app and slack channels use this field while email uses emailContent, but the schema leaves both optional and the pairing is enforced in the client and at run time."
                            },
                            "emailContent": {
                              "type": "string",
                              "description": "For the email channel, choose what the email carries. optional",
                              "enum": [
                                "transcript",
                                "ai_response"
                              ]
                            }
                          }
                        },
                        "outboundWebhook": {
                          "type": "object",
                          "description": "Configure a step that calls a URL of yours. required when stepType is \"outbound-webhook\", rejected for any other stepType",
                          "properties": {
                            "url": {
                              "type": "string",
                              "description": "Give the URL to call. It may contain {{tokens}}, so it is validated as plain text rather than as a URI. required, trimmed, min length 1, max length 2000, no uri format check"
                            },
                            "method": {
                              "type": "string",
                              "description": "Choose the HTTP method for the call. optional (no.required, and.default('POST') makes the schema treat it as present). The 'POST' default is not persisted, because the controller reads raw req.body and the model carries no default.",
                              "enum": [
                                "GET",
                                "POST",
                                "PUT",
                                "PATCH",
                                "DELETE"
                              ]
                            },
                            "headers": {
                              "type": "object",
                              "description": "Set request headers for the call. optional, declared as the schema.pattern(the schema, the schema), so keys and values must both be strings"
                            },
                            "bodyTemplate": {
                              "type": "string",
                              "description": "Set the request body. Send either a string template or a JSON object. optional. Declared as a union.max(20000).allow(''), the schema), so the real type is a string-or-object union that a single OpenAPI type cannot express."
                            }
                          }
                        },
                        "dependsOn": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "List the stepId values that must finish before this step runs. optional, items must be strings, no cap"
                        },
                        "branch": {
                          "type": "string",
                          "description": "For a step under a condition, say which branch it belongs to. optional. These are the strings \"true\" and \"false\", not booleans, so sending true instead of \"true\" returns a 400.",
                          "enum": [
                            "true",
                            "false"
                          ]
                        }
                      }
                    },
                    "description": "List the steps the automation runs, in order. required, min 1 entry, max 20 entries"
                  },
                  "runType": {
                    "type": "string",
                    "description": "Choose whether the automation runs as soon as its trigger fires or on a schedule. optional, empty string accepted. Values come from AutomationRunType plus an explicit ''. The declared default is 'instant', and although that default is not what reaches the controller, the effect holds anyway: createAutomation writes SCHEDULE only when runType strictly equals \"schedule\" and writes INSTANT otherwise.",
                    "enum": [
                      "instant",
                      "schedule",
                      ""
                    ]
                  },
                  "fieldId": {
                    "type": "string",
                    "description": "Ignore this field. The server validates it and then never reads it, so setting it has no effect. optional, no length cap. Neither createAutomation nor updateAutomation destructures a top-level fieldId from req.body, so it is never persisted. Field targeting is done per step through magicPrompt.fieldId and magicPrompt.fieldIds.",
                    "deprecated": true
                  },
                  "isUpdated": {
                    "type": "boolean",
                    "description": "Ignore this field. The server always marks a newly created automation as updated for the scheduler, whatever you send. optional. The controller does not read the client value; it hardcodes isUpdated: true on the new document.",
                    "deprecated": true
                  },
                  "schedule": {
                    "type": "object",
                    "description": "Set when a scheduled automation runs. required when runType is \"schedule\", otherwise optional",
                    "properties": {
                      "timePeriod": {
                        "type": "string",
                        "description": "Choose the window of media the scheduled run covers. required when runType is \"schedule\"; otherwise optional and an empty string is also accepted. Values come from AutomationScheduleTimePeriod.",
                        "enum": [
                          "today",
                          "yesterday",
                          "last7days",
                          "last14days",
                          "thisWeek"
                        ]
                      },
                      "repeatAt": {
                        "type": "string",
                        "description": "Set the time of day the scheduled run fires. required (trimmed, min length 1) when runType is \"schedule\"; otherwise optional and an empty string is accepted. No format is enforced by the schema."
                      }
                    }
                  }
                },
                "required": [
                  "name",
                  "trigger",
                  "steps"
                ]
              },
              "example": {
                "name": "Daily Marketing Report",
                "description": "Generate daily marketing insights from campaign data",
                "runType": "schedule",
                "schedule": {
                  "timePeriod": "yesterday",
                  "repeatAt": "08:00"
                },
                "trigger": {
                  "type": "folders",
                  "folderIds": [
                    "marketing-data",
                    "campaign-reports"
                  ]
                },
                "fieldId": "marketing-field-123",
                "steps": [
                  {
                    "stepId": "step-1",
                    "stepType": "magic-prompt",
                    "magicPrompt": {
                      "promptId": "prompt-123",
                      "name": "Weekly summary"
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "create-automation": {
                    "summary": "Create Automation",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/automations/{automationId}": {
      "get": {
        "tags": [
          "Automations"
        ],
        "summary": "Get Automation",
        "operationId": "automations-get-automation",
        "description": "The endpoint makes an HTTP GET request to retrieve a list of automations from the specified URL.\n\nThe response of this request can be documented as a JSON schema:\n\n``` json\n{\n \"type\": \"object\",\n \"properties\": {\n \"status\": {\n \"type\": \"string\"\n },\n \"data\": {\n \"type\": \"object\",\n \"properties\": {\n \"totalCount\": {\n \"type\": \"integer\"\n },\n \"automationList\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"trigger\": {\n \"type\": \"object\",\n \"properties\": {\n \"type\": {\n \"type\": \"string\"\n },\n \"folderIds\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"folderId\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"values\": {\n \"type\": \"array\"\n }\n }\n },\n \"action\": {\n \"type\": \"object\",\n \"properties\": {\n \"magicPrompt\": {\n \"type\": \"object\",\n \"properties\": {\n \"title\": {\n \"type\": \"string\"\n },\n \"assistantType\": {\n \"type\": \"string\"\n },\n \"assistantTemplateId\": {\n \"type\": \"string\"\n },\n \"prompt\": {\n \"type\": \"string\"\n }\n }\n },\n \"type\": {\n \"type\": \"string\"\n }\n }\n },\n \"name\": {\n \"type\": \"string\"\n },\n \"description\": {\n \"type\": \"string\"\n },\n \"runType\": {\n \"type\": \"string\"\n },\n \"isActive\": {\n \"type\": \"boolean\"\n },\n \"automationId\": {\n \"type\": \"string\"\n },\n \"actionHistory\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"type\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"createdAt\": {\n \"type\": \"string\"\n },\n \"updatedAt\": {\n \"type\": \"string\"\n },\n \"history\": {\n \"type\": \"integer\"\n }\n }\n }\n }\n }\n }\n }\n}\n\n ```",
        "parameters": [
          {
            "name": "automationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "97c57afd7ff1"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "get-automation": {
                    "summary": "Get Automation",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Automations"
        ],
        "summary": "Delete Automation",
        "operationId": "automations-delete-automation",
        "description": "### DELETE Automation\n\nThis endpoint is used to delete a specific automation identified by its unique `automationId`. By sending a DELETE request to this endpoint, you can remove an automation from the system.\n\n#### Request Format\n\n- **Method**: DELETE\n\n- **Endpoint**: `{{url}}/v1/automations/:automationId`\n\n- **Path Parameter**:\n\n - `automationId` (string): The unique identifier of the automation that you wish to delete. This parameter is required and should be included in the URL.\n\n\n#### Response Structure\n\nUpon successful deletion of the automation, the server will respond with a confirmation message. The expected response is typically structured as follows:\n\n- **Status Code**: `204 No Content`\n\n - Indicates that the request was successful and there is no additional content to send in the response body.\n\n\nIn case of an error, the server may return a different status code along with an error message detailing the issue encountered.\n\nEnsure to handle responses appropriately based on the status code received.",
        "parameters": [
          {
            "name": "automationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": null
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "delete-automation": {
                    "summary": "Delete Automation",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Automations"
        ],
        "summary": "Update Automation",
        "operationId": "automations-update-automation",
        "description": "## Update Automation\n\n**Body (JSON):**\n\n``` json\n{\n \"name\": \"Updated Marketing Analysis\",\n \"description\": \"Enhanced automation with schedule and new assistant type\",\n \"isActive\": true,\n \"runType\": \"schedule\",\n \"schedule\": {\n \"timePeriod\": \"last7days\",\n \"repeatAt\": \"09:30\"\n },\n \"trigger\": {\n \"type\": \"folders\",\n \"folderIds\": [\"folder123\", \"folder456\"]\n },\n \"action\": {\n \"type\": \"magic-prompt\",\n \"magicPrompt\": {\n \"title\": \"Weekly Marketing Report\",\n \"assistantType\": \"marketer\",\n \"prompt\": \"Analyze marketing data and provide insights, trends, and recommendations\",\n \"assistantTemplateId\": \"marketing-template-001\"\n }\n },\n \"fieldId\": \"marketing-field-123\"\n}\n\n ```\n\n## **Key Points:**\n\n\u2022 **Path Parameter Required:** `automationId` must be included in the URL path\n\u2022 **Partial Updates Supported:** You can update only specific fields, not all fields are required\n\u2022 **Run Type Changes:** When changing to `\"schedule\"`, include the `schedule` object with `timePeriod` and `repeatAt`\n\u2022 **Trigger & Action Required:** Both `trigger` and `action` objects appear to be required in the request body\n\u2022 **Assistant Type:** The `assistantType` is for custom Assistant selected\n\u2022 **Status Control:** Use `isActive: true/false` to enable or disable the automation\n\u2022 **Optional Fields:** `fieldId` is optional and only used with magic-prompt actions\n\u2022 **Schedule Time Periods:** Available options - `\"today\"`, `\"yesterday\"`, `\"last7days\"`, `\"last14days\"`, `\"thisWeek\"`\n\u2022 **Action Types:** Support for `\"magic-prompt\"` and `\"translation\"` action types\n\u2022 **Trigger Types:** Support for `\"folders\"`, `\"tags\"`, and `\"keywords\"` trigger types\n\u2022 **Assistant Types:** Available options - `\"researcher\"`, `\"marketer\"`, `\"sales\"`, `\"general\"`, `\"recruiter\"`, `\"custom\"`\n\n**Request rules.** The same rules as creating an automation. `schedule` is required only when `runType` is `schedule`, and then both `schedule.timePeriod` and `schedule.repeatAt` are required. Each step's config object has to match that step's `stepType`.",
        "parameters": [
          {
            "name": "automationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name the automation. This is what you see in the automations list. required, max length 150"
                  },
                  "description": {
                    "type": "string",
                    "description": "Describe what the automation does. You can send an empty string. optional, max length 1000, empty string allowed"
                  },
                  "isActive": {
                    "type": "boolean",
                    "description": "Turn the automation on or off. Leave it out and the automation keeps whatever active state it already has. optional. The declared default is true, but that default never reaches the controller, which does if (isActive !== undefined) setter.$set.isActive = isActive. Omitting the field therefore leaves the stored value untouched; it does NOT reactivate a paused automation."
                  },
                  "runOnceOnly": {
                    "type": "string",
                    "description": "Ignore this field. The server accepts it and then never reads it, so whatever you send has no effect. optional. unconstrained.strip, so any JSON type passes validation. The controller reads runOnceOnly only off the existing stored record, never off your request body, so you cannot set or clear it through this endpoint.",
                    "deprecated": true
                  },
                  "trigger": {
                    "type": "object",
                    "description": "Define the single event that starts the automation. required, unknown keys rejected",
                    "properties": {
                      "type": {
                        "type": "string",
                        "description": "Pick the kind of event that starts the automation. required inside trigger; values come from the AutomationTrigger list",
                        "enum": [
                          "folders",
                          "tags",
                          "keywords",
                          "composio",
                          "webhook"
                        ]
                      },
                      "folderIds": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "List the folders the trigger watches. optional, item schema is unconstrained (the schema with no.items)"
                      },
                      "values": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Send the secondary list a trigger needs, such as the field IDs for a field-updated event. optional, items must be strings, empty strings allowed as items"
                      },
                      "provider": {
                        "type": "string",
                        "description": "Say which system owns the trigger. optional",
                        "enum": [
                          "speak",
                          "composio"
                        ]
                      },
                      "app": {
                        "type": "string",
                        "description": "Name the third-party app for a Composio trigger. optional, empty string allowed"
                      },
                      "triggerSlug": {
                        "type": "string",
                        "description": "Give the provider's slug for the specific trigger you picked. optional, empty string allowed"
                      },
                      "webhookId": {
                        "type": "string",
                        "description": "Attach an inbound webhook to the trigger by its ID. optional, empty string allowed"
                      },
                      "childKey": {
                        "type": "string",
                        "description": "Point the trigger at a nested key inside the incoming payload. optional, empty string allowed"
                      },
                      "connectedAccountId": {
                        "type": "string",
                        "description": "Identify the connected account the trigger authenticates through. optional, empty string allowed, not trimmed and no max length"
                      },
                      "fieldValueMatches": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "fieldId": {
                              "type": "string",
                              "description": "Identify the field to match on. required inside each entry, trimmed, min length 1, max length 100"
                            },
                            "values": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "List the values that count as a match. Send an empty array to match any value. required inside each entry, max 50 items, each item max length 200, empty strings allowed"
                            }
                          }
                        },
                        "description": "Only fire the trigger when the named fields hold the values you list. optional, max 20 entries"
                      },
                      "fieldMatchLogic": {
                        "type": "string",
                        "description": "Choose whether every fieldValueMatches entry has to match or just one. Leaving it out behaves like OR. optional",
                        "enum": [
                          "AND",
                          "OR"
                        ]
                      },
                      "triggerConfig": {
                        "type": "object",
                        "description": "Pass provider-specific trigger settings. The server stores this object as sent. optional, unconstrained object"
                      }
                    }
                  },
                  "triggers": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "description": "Pick the kind of event for this alternative trigger. optional here, unlike trigger.type which is required",
                          "enum": [
                            "folders",
                            "tags",
                            "keywords",
                            "composio",
                            "webhook"
                          ]
                        },
                        "folderIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "List the folders this alternative trigger watches. optional, item schema unconstrained"
                        },
                        "values": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Send the secondary list this alternative trigger needs. optional, items must be strings, empty strings allowed as items"
                        },
                        "provider": {
                          "type": "string",
                          "description": "Say which system owns this alternative trigger. optional",
                          "enum": [
                            "speak",
                            "composio"
                          ]
                        },
                        "app": {
                          "type": "string",
                          "description": "Name the third-party app for this alternative Composio trigger. optional, empty string allowed"
                        },
                        "triggerSlug": {
                          "type": "string",
                          "description": "Give the provider's slug for this alternative trigger. optional, empty string allowed"
                        },
                        "fieldValueMatches": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          },
                          "description": "Only fire this alternative trigger when the named fields hold the values you list. optional, max 20 entries, same fieldId and values shape as trigger.fieldValueMatches"
                        },
                        "fieldMatchLogic": {
                          "type": "string",
                          "description": "Choose whether every fieldValueMatches entry has to match or just one for this alternative trigger. optional",
                          "enum": [
                            "AND",
                            "OR"
                          ]
                        },
                        "triggerConfig": {
                          "type": "object",
                          "description": "Pass provider-specific settings for this alternative trigger. optional, unconstrained object"
                        },
                        "connectedAccountId": {
                          "type": "string",
                          "description": "Identify the connected account this alternative trigger authenticates through. optional, trimmed, max length 100, empty string allowed"
                        }
                      }
                    },
                    "description": "Add extra alternative triggers. The automation runs when any one of them fires. optional, max 10 entries"
                  },
                  "steps": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "stepId": {
                          "type": "string",
                          "description": "Give the step an ID that is unique within this automation. Other steps reference it through dependsOn. required, trimmed, min length 1, max length 100"
                        },
                        "stepType": {
                          "type": "string",
                          "description": "Say what kind of work the step does. This decides which config object the step must carry. required; values come from the AutomationStepType list",
                          "enum": [
                            "trigger",
                            "magic-prompt",
                            "translation",
                            "composio-action",
                            "filter",
                            "speak-upload",
                            "notify",
                            "outbound-webhook",
                            "condition"
                          ]
                        },
                        "magicPrompt": {
                          "type": "object",
                          "description": "Configure an AI prompt step. required when stepType is \"magic-prompt\", rejected for any other stepType. One step extracts at most 25 fields through fieldIds; send more and the request is rejected with 400. Split a longer rubric across several magic-prompt steps.",
                          "properties": {
                            "title": {
                              "type": "string",
                              "description": "Title the prompt so you can recognize its output later. optional, empty string allowed"
                            },
                            "modelId": {
                              "type": "string",
                              "description": "Override the model for this step. Send an empty string or null to clear it and fall back to your company default. optional; all 43 values copied verbatim from LLMModels. '' and null coerce to absent. empty(the schema) and are not enum members. The enum's header comment says DEPRECATED models are grouped first within each provider and LIVE ones follow, but there is no per-value flag, so no individual value can be marked deprecated from the code.",
                              "enum": [
                                "gpt-3.5",
                                "gpt-3.5-turbo-16k",
                                "gpt-3.5-turbo-0125",
                                "gpt-4",
                                "gpt-4-1106-preview",
                                "gpt-4-turbo",
                                "gpt-4o-2024-05-13",
                                "gpt-4o",
                                "gpt-4o-mini",
                                "gpt-4o-2024-08-06",
                                "gpt-4o-mini-2024-07-18",
                                "gpt-4.1-2025-04-14",
                                "gpt-5.1-2025-11-13",
                                "gpt-5.2",
                                "gpt-5.4",
                                "gpt-5.4-mini",
                                "gpt-5.4-mini-2026-03-17",
                                "gpt-5.4-nano",
                                "gpt-5.5",
                                "gpt-5.5-thinking",
                                "gpt-5.6-sol",
                                "gpt-5.6-terra",
                                "gpt-5.6-luna",
                                "claude-2",
                                "claude-3-5-sonnet",
                                "claude-3-5-sonnet-20241022",
                                "claude-3-7-sonnet-latest",
                                "claude-haiku-4-5",
                                "claude-sonnet-4-6",
                                "claude-sonnet-5",
                                "claude-opus-4-8",
                                "gemini-1.5-pro",
                                "gemini-1.5-flash",
                                "gemini-2.0-flash",
                                "gemini-2.5-pro",
                                "gemini-2.5-flash",
                                "gemini-2.5-flash-lite",
                                "gemini-3-flash-preview",
                                "gemini-3.1-flash-lite",
                                "gemini-3.1-pro-preview",
                                "gemini-3.5-flash",
                                "gemini-3.7-flash",
                                "gemini-3.8-flash",
                                "x-ai/grok-4.5",
                                "z-ai/glm-5.2"
                              ]
                            },
                            "prompt": {
                              "type": "string",
                              "description": "Write the instruction the model follows. max length 20000; required unless fieldIds is present with at least one entry, in which case an empty string is accepted. The schema.default('') on that branch is not persisted."
                            },
                            "assistantType": {
                              "type": "string",
                              "description": "Pick the assistant persona that answers the prompt. Optional, and restricted to the values listed here: any other string is rejected. Omitting it stores no value on the step. When the step runs, the persona falls back to the default saved on the user profile the run belongs to, and to 'general' when none is saved.",
                              "enum": [
                                "researcher",
                                "marketer",
                                "sales",
                                "general",
                                "recruiter",
                                "custom"
                              ]
                            },
                            "assistantTemplateId": {
                              "type": "string",
                              "description": "Identify your custom assistant template. required when assistantType is \"custom\"; otherwise optional and accepts '' or null. The schema.default('') is not persisted."
                            },
                            "isIndividualFolder": {
                              "type": "boolean",
                              "description": "Run the prompt separately per folder instead of once across everything. optional. The schema.default(false) is not persisted."
                            },
                            "allowedValues": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Restrict the answer to this list of values. optional, items must be strings, no item cap"
                            },
                            "allowedValuesMode": {
                              "type": "string",
                              "description": "Choose whether the answer may pick one allowed value or several. optional; values come from AllowedValuesMode. The schema.default('multiple') is not persisted.",
                              "enum": [
                                "single",
                                "multiple"
                              ]
                            },
                            "otherValues": {
                              "type": "boolean",
                              "description": "Let the answer fall outside the allowed values list. optional"
                            },
                            "notApplicableValues": {
                              "type": "string",
                              "description": "Say what the model should answer when nothing applies. optional, empty string allowed"
                            },
                            "fieldId": {
                              "type": "string",
                              "description": "Write the answer into this single field. optional, accepts '' or null"
                            },
                            "fieldIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Extract several fields in one step. Sending at least one field ID makes prompt optional. optional, max 25 items. Over the cap the request is rejected with 400 and the message \"A single AI step can extract at most 25 fields. Split the rest into another AI step.\""
                            }
                          }
                        },
                        "translation": {
                          "type": "object",
                          "description": "Configure a translation step. required when stepType is \"translation\", rejected for any other stepType",
                          "properties": {
                            "targetLanguage": {
                              "type": "string",
                              "description": "Pick the language to translate into. required inside translation. The accepted set is TranslationLanguageCodes, defined by mapping the static TranslationLanguages array (lines 6-118) to its transcriptionCode. That array holds 111 entries, so there are exactly 111 accepted values, listed here in source order.",
                              "enum": [
                                "en-US",
                                "fr-FR",
                                "af-ZA",
                                "ar-SA",
                                "hy-AM",
                                "bg-BG",
                                "ca-ES",
                                "hr-HR",
                                "cs-CZ",
                                "da-DK",
                                "nl-NL",
                                "et-EE",
                                "fa-IR",
                                "fi-FI",
                                "de-DE",
                                "el-GR",
                                "gu-IN",
                                "he-IL",
                                "hi-IN",
                                "ht-HT",
                                "hu-HU",
                                "id-ID",
                                "is-IS",
                                "it-IT",
                                "ga-IE",
                                "ja-JP",
                                "kn-IN",
                                "ko-KR",
                                "lt-LT",
                                "lv-LV",
                                "ml-IN",
                                "ms-MY",
                                "nb-NO",
                                "pl-PL",
                                "pt-PT",
                                "ro-RO",
                                "ru-RU",
                                "es-ES",
                                "sk-SK",
                                "sl-SI",
                                "sv-SE",
                                "ta-IN",
                                "te-IN",
                                "th-TH",
                                "tr-TR",
                                "uk-UA",
                                "vi-VN",
                                "as-IN",
                                "ay-BO",
                                "bm-ML",
                                "eu-ES",
                                "be-BY",
                                "bho-IN",
                                "ceb-PH",
                                "co-FR",
                                "dv-MV",
                                "doi-IN",
                                "eo-XX",
                                "ee-GH",
                                "fil-PH",
                                "fy-NL",
                                "gl-ES",
                                "gn-PY",
                                "haw-US",
                                "hmn-CN",
                                "ig-NG",
                                "ilo-PH",
                                "jv-ID",
                                "km-KH",
                                "rw-RW",
                                "gom-IN",
                                "kri-SL",
                                "ku-TR",
                                "ckb-IQ",
                                "ky-KG",
                                "lo-LA",
                                "la-VA",
                                "ln-CG",
                                "lg-UG",
                                "lb-LU",
                                "mai-IN",
                                "mg-MG",
                                "mi-NZ",
                                "mni-IN",
                                "lus-IN",
                                "my-MM",
                                "ne-NP",
                                "ny-MW",
                                "or-IN",
                                "om-ET",
                                "qu-PE",
                                "sm-WS",
                                "sa-IN",
                                "gd-GB",
                                "nso-ZA",
                                "st-ZA",
                                "sn-ZW",
                                "sd-PK",
                                "si-LK",
                                "su-ID",
                                "tg-TJ",
                                "tt-RU",
                                "ti-ER",
                                "ts-ZA",
                                "tk-TM",
                                "ak-GH",
                                "ug-CN",
                                "xh-ZA",
                                "yi-XX",
                                "yo-NG",
                                "zu-ZA"
                              ]
                            }
                          }
                        },
                        "filter": {
                          "type": "object",
                          "description": "Configure a filter step that stops the run when its rules do not match. required when stepType is \"filter\", rejected for any other stepType",
                          "properties": {
                            "logic": {
                              "type": "string",
                              "description": "Choose whether every rule has to match or just one. optional. The schema.default('AND') is not persisted.",
                              "enum": [
                                "AND",
                                "OR"
                              ]
                            },
                            "rules": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "field": {
                                    "type": "string",
                                    "description": "Name the field the rule reads. required, trimmed, min length 1, max length 100"
                                  },
                                  "op": {
                                    "type": "string",
                                    "description": "Pick how the rule compares the field to the value. required",
                                    "enum": [
                                      "eq",
                                      "neq",
                                      "contains",
                                      "ncontains",
                                      "startsWith",
                                      "gt",
                                      "lt",
                                      "exists"
                                    ]
                                  },
                                  "value": {
                                    "type": "string",
                                    "description": "Give the value to compare against. You can send a string or a number. optional. Declared as a union.max(1000).allow(''), the schema), a string-or-number union."
                                  }
                                }
                              },
                              "description": "List the conditions the filter checks. required, min 1 entry, max 20 entries"
                            }
                          }
                        },
                        "condition": {
                          "type": "object",
                          "description": "Configure a branching step that sends the run down a true or false path. required when stepType is \"condition\", rejected for any other stepType; identical shape to steps[].filter",
                          "properties": {
                            "logic": {
                              "type": "string",
                              "description": "Choose whether every rule has to match or just one. optional. The schema.default('AND') is not persisted.",
                              "enum": [
                                "AND",
                                "OR"
                              ]
                            },
                            "rules": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              },
                              "description": "List the conditions the branch evaluates. required, min 1 entry, max 20 entries, same field, op and value shape as filter rules"
                            }
                          }
                        },
                        "composio": {
                          "type": "object",
                          "description": "Configure a step that runs a Composio app action. required when stepType is \"composio-action\", rejected for any other stepType",
                          "properties": {
                            "app": {
                              "type": "string",
                              "description": "Name the Composio app to act on. required, trimmed, min length 1, max length 100"
                            },
                            "action": {
                              "type": "string",
                              "description": "Name the action to run in that app. required, trimmed, min length 1, max length 200"
                            },
                            "connectedAccountId": {
                              "type": "string",
                              "description": "Identify the connected account the action runs as. optional, trimmed, max length 100, empty string allowed"
                            },
                            "argsTemplate": {
                              "type": "object",
                              "description": "Pass the action's arguments. Values may contain tokens, so the server accepts any shape. optional, unconstrained object"
                            },
                            "destructive": {
                              "type": "boolean",
                              "description": "Mark the action as destructive so it asks for confirmation. optional"
                            },
                            "acknowledged": {
                              "type": "boolean",
                              "description": "Confirm you accept a destructive action. optional"
                            }
                          }
                        },
                        "speakUpload": {
                          "type": "object",
                          "description": "Configure a step that uploads media into Speak. required when stepType is \"speak-upload\", rejected for any other stepType",
                          "properties": {
                            "name": {
                              "type": "string",
                              "description": "Name the uploaded media. optional, max length 500, empty string allowed"
                            },
                            "folderId": {
                              "type": "string",
                              "description": "Choose the folder the upload lands in. In dynamic routing this becomes the fallback folder instead. required (trimmed, min length 1, max length 100) unless folderRouting.mode is \"dynamic\", in which case it is optional (trimmed, max 100, empty string allowed)"
                            },
                            "sourceMode": {
                              "type": "string",
                              "description": "Say whether the upload comes from a URL or from a file already in the run. required",
                              "enum": [
                                "url",
                                "file"
                              ]
                            },
                            "sourceUrl": {
                              "type": "string",
                              "description": "Give the URL to fetch the media from. max length 2000; required when sourceMode is \"url\", otherwise optional and may be an empty string. Not validated as a URI, because it may carry {{tokens}}."
                            },
                            "fieldsMap": {
                              "type": "object",
                              "description": "Map field names to values to set on the uploaded media. optional, keys and values must both be strings"
                            },
                            "language": {
                              "type": "string",
                              "description": "Set the language for the upload. You can send a language code or a token that resolves at run time, so known codes are not enforced. optional, max length 100, empty string allowed"
                            },
                            "waitForProcessing": {
                              "type": "boolean",
                              "description": "Hold the automation until the uploaded media finishes processing before the next step runs. optional"
                            },
                            "folderRouting": {
                              "type": "object",
                              "description": "Route the upload to a folder chosen from the incoming payload instead of a fixed one. optional",
                              "properties": {
                                "mode": {
                                  "type": "string",
                                  "description": "Choose between the fixed folderId and a folder picked from the payload. required inside folderRouting",
                                  "enum": [
                                    "static",
                                    "dynamic"
                                  ]
                                },
                                "sourceKey": {
                                  "type": "string",
                                  "description": "Name the payload key that holds the folder to route to. required (trimmed, min length 1, max length 500) when mode is \"dynamic\"; otherwise optional, trimmed, max length 500, empty string allowed"
                                },
                                "onNoMatch": {
                                  "type": "string",
                                  "description": "Say what to do when no folder matches: create one, or fall back to the folderId. required when mode is \"dynamic\", otherwise optional",
                                  "enum": [
                                    "create",
                                    "default"
                                  ]
                                }
                              }
                            }
                          }
                        },
                        "notify": {
                          "type": "object",
                          "description": "Configure a notification step. required when stepType is \"notify\", rejected for any other stepType",
                          "properties": {
                            "channel": {
                              "type": "string",
                              "description": "Pick where the notification goes. required",
                              "enum": [
                                "in_app",
                                "email",
                                "slack"
                              ]
                            },
                            "target": {
                              "type": "string",
                              "description": "Name the recipient, such as an email address or a Slack channel. optional, max length 500, empty string allowed"
                            },
                            "message": {
                              "type": "string",
                              "description": "Write the notification body. It may contain {{tokens}}, so the server accepts any text. optional, max length 20000, empty string allowed"
                            },
                            "emailContent": {
                              "type": "string",
                              "description": "For the email channel, choose what the email carries. optional",
                              "enum": [
                                "transcript",
                                "ai_response"
                              ]
                            }
                          }
                        },
                        "outboundWebhook": {
                          "type": "object",
                          "description": "Configure a step that calls a URL of yours. required when stepType is \"outbound-webhook\", rejected for any other stepType",
                          "properties": {
                            "url": {
                              "type": "string",
                              "description": "Give the URL to call. It may contain {{tokens}}, so it is validated as plain text rather than as a URI. required, trimmed, min length 1, max length 2000, no uri format check"
                            },
                            "method": {
                              "type": "string",
                              "description": "Choose the HTTP method for the call. optional. The schema.default('POST') is not persisted.",
                              "enum": [
                                "GET",
                                "POST",
                                "PUT",
                                "PATCH",
                                "DELETE"
                              ]
                            },
                            "headers": {
                              "type": "object",
                              "description": "Set request headers for the call. optional, keys and values must both be strings"
                            },
                            "bodyTemplate": {
                              "type": "string",
                              "description": "Set the request body. Send either a string template or a JSON object. optional. Declared as a union.max(20000).allow(''), the schema), a string-or-object union."
                            }
                          }
                        },
                        "dependsOn": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "List the stepId values that must finish before this step runs. optional, items must be strings"
                        },
                        "branch": {
                          "type": "string",
                          "description": "For a step under a condition, say which branch it belongs to. optional. These are the strings \"true\" and \"false\", not booleans.",
                          "enum": [
                            "true",
                            "false"
                          ]
                        }
                      }
                    },
                    "description": "List the steps the automation runs, in order. This replaces the existing steps rather than merging with them. required, min 1 entry, max 20 entries"
                  },
                  "runType": {
                    "type": "string",
                    "description": "Choose whether the automation runs as soon as its trigger fires or on a schedule. optional, empty string accepted. The controller writes SCHEDULE only when runType strictly equals \"schedule\" and writes INSTANT otherwise, so omitting it on a scheduled automation converts it back to instant and unsets its schedule.",
                    "enum": [
                      "instant",
                      "schedule",
                      ""
                    ]
                  },
                  "fieldId": {
                    "type": "string",
                    "description": "Ignore this field. The server validates it and then never reads it, so setting it has no effect. optional. updateAutomation does not destructure a top-level fieldId from req.body.",
                    "deprecated": true
                  },
                  "isUpdated": {
                    "type": "boolean",
                    "description": "Ignore this field. The server always flags the automation as updated for the scheduler on every update, whatever you send. optional. The controller hardcodes isUpdated: true in its $set and never reads the client value.",
                    "deprecated": true
                  },
                  "schedule": {
                    "type": "object",
                    "description": "Set when a scheduled automation runs. required when runType is \"schedule\", otherwise optional. When runType is not \"schedule\" the controller unsets any stored schedule.",
                    "properties": {
                      "timePeriod": {
                        "type": "string",
                        "description": "Choose the window of media the scheduled run covers. required when runType is \"schedule\"; otherwise optional and an empty string is also accepted. Values come from AutomationScheduleTimePeriod.",
                        "enum": [
                          "today",
                          "yesterday",
                          "last7days",
                          "last14days",
                          "thisWeek"
                        ]
                      },
                      "repeatAt": {
                        "type": "string",
                        "description": "Set the time of day the scheduled run fires. required (trimmed, min length 1) when runType is \"schedule\"; otherwise optional and an empty string is accepted. No format is enforced."
                      }
                    }
                  }
                },
                "required": [
                  "name",
                  "trigger",
                  "steps"
                ]
              },
              "example": {
                "name": "Updated Marketing Analysis",
                "description": "Enhanced automation with schedule and new assistant type",
                "isActive": true,
                "runType": "schedule",
                "schedule": {
                  "timePeriod": "last7days",
                  "repeatAt": "09:30"
                },
                "trigger": {
                  "type": "folders",
                  "folderIds": [
                    "folder123",
                    "folder456"
                  ]
                },
                "fieldId": "marketing-field-123",
                "steps": [
                  {
                    "stepId": "step-1",
                    "stepType": "magic-prompt",
                    "magicPrompt": {
                      "promptId": "prompt-123",
                      "name": "Weekly summary"
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "update-automation": {
                    "summary": "Update Automation",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/automations/status/{automationId}": {
      "put": {
        "tags": [
          "Automations"
        ],
        "summary": "Enable or Disable Automation",
        "operationId": "automations-enable-or-disable-automation",
        "description": "# Update Automation Status\n\nThis endpoint allows you to update the status of a specific automation to enable or disable by providing the automation ID in the URL path.\n\n## Request Body\n\nThe request body should contain the following parameters:\n\n- `status`: (string) The new status for the automation.\n\n- `message`: (string) An optional message related to the status update.\n\n\n## Response\n\nThe response will have a status code of 200 and a JSON body with the following structure:\n\n- `status`: (string) Indicates the status of the request.\n\n- `message`: (string) Provides additional information about the status.\n\n\n## Sample Response\n\n``` json\n{\n \"status\": \"\",\n \"message\": \"\"\n}\n\n ```",
        "parameters": [
          {
            "name": "automationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "97c57afd7ff1"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "enable-or-disable-automation": {
                    "summary": "Enable or Disable Automation",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/admin/user": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Create New User",
        "operationId": "admin-create-new-user",
        "description": "## Add User Endpoint\n\nThis endpoint allows administrators to add a new user to the system. The request requires a JSON payload containing user details.\n\n### Request Parameters\n\nThe request body should be in JSON format and include the following parameters:\n\n- `firstName` (string): The first name of the user.\n\n- `lastName` (string): The last name of the user.\n\n- `email` (string): The email address of the user.\n\n- `isActive` (boolean): Indicates whether the user account is active.\n\n- `isVerified` (boolean): Indicates whether the user's email has been verified.\n\n- `permission` (object): An object specifying the permissions granted to the user:\n\n - `audio` (boolean): Permission to access audio features.\n\n - `video` (boolean): Permission to access video features.\n\n - `text` (boolean): Permission to access text features.\n\n - `addPayment` (boolean): Permission to manage payment options.\n\n - `userManagement` (boolean): Permission to manage other users.\n\n\n### Expected Response\n\nUpon a successful request, the server will respond with a confirmation of the user creation, typically including the user ID and any other relevant details about the newly created user.\n\n### Notes\n\n- Ensure that the email provided is unique and valid to avoid conflicts.\n\n- Permissions should be assigned based on the user's role within the organization.\n\n- This endpoint is restricted to users with administrative privileges.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "_id": {
                    "type": "string",
                    "description": "Pass an existing user id. Leave it out when you are creating a new team member. Optional. Empty string is accepted. The create controller never reads it, so it has no effect on this endpoint."
                  },
                  "email": {
                    "type": "string",
                    "description": "Give the email address to invite. This is the only property the server always requires. Required. Must be a valid email address. Lowercased and trimmed. An empty string is rejected."
                  },
                  "firstName": {
                    "type": "string",
                    "description": "Give the new member's first name. Optional. Trimmed. No minimum or maximum length."
                  },
                  "lastName": {
                    "type": "string",
                    "description": "Give the new member's last name. Optional. Trimmed. No minimum or maximum length."
                  },
                  "isActive": {
                    "type": "boolean",
                    "description": "Accepted for compatibility. The create endpoint ignores it, and the new account is created through the invite flow. Optional. The declared default is true, but the middleware discards the converted value, and the create controller never reads this key."
                  },
                  "isVerified": {
                    "type": "boolean",
                    "description": "Accepted for compatibility. The create endpoint ignores it. Optional. The declared default is false, and the same caveat about discarded conversions applies. The create controller never reads this key."
                  },
                  "permission": {
                    "type": "object",
                    "description": "Set what the new member can do. Anything you leave out falls back to the defaults for their role. Optional object with a fixed key set, defined. Unknown keys are rejected. Accepted keys: `role` (string, one of owner, admin, member); `folder` object with create, delete, download, share, assign, accessAll; `recorder` object with create, edit, delete, download, accessAll; `media` object with delete, edit, download, share; `payment` object with manageCards, manageInvoices; `teamManagement` object with manageMembers, manageGroups; `developer` object with accessKeys; `profileSettings` object with accountPreferences, accountCustomization, dataManagement; `meetingAssistant` object with customizeAssistant, shareMeetings, routeMeetings, excludeMeetings, globalSettings. Every leaf key is a boolean. The controller reads permission.role, falls back to member, and merges what you send over the role defaults."
                  }
                },
                "required": [
                  "email"
                ]
              },
              "example": {
                "firstName": "Vatsal",
                "lastName": "Shah",
                "email": "test@abc.com",
                "isActive": true,
                "isVerified": true,
                "permission": {
                  "audio": true,
                  "video": true,
                  "text": true,
                  "addPayment": false,
                  "userManagement": false
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "create-new-user": {
                    "summary": "Create New User",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Admin"
        ],
        "summary": "Update User",
        "operationId": "admin-update-user",
        "description": "## Update User Details\n\nThis endpoint allows administrators to update the details of a user in the system. It is a PUT request that modifies the user's information based on the provided payload.\n\n### Request Parameters\n\nThe request body should be a JSON object with the following parameters:\n\n- **_id** (string): The unique identifier of the user to be updated.\n\n- **email** (string): The email address of the user. This field can be left empty if no change is required.\n\n- **firstName** (string): The first name of the user.\n\n- **lastName** (string): The last name of the user.\n\n- **isActive** (boolean): Indicates whether the user account is active.\n\n- **isVerified** (boolean): Indicates whether the user's email has been verified.\n\n- **permission** (object): An object that defines the permissions for the user with the following keys:\n\n - **audio** (boolean): Permission to access audio features.\n\n - **video** (boolean): Permission to access video features.\n\n - **text** (boolean): Permission to access text features.\n\n - **addPayment** (boolean): Permission to add payment methods.\n\n - **userManagement** (boolean): Permission to manage other users.\n\n\n### Expected Response\n\nUpon a successful update, the API will return a response indicating the status of the operation. The response typically includes a success message and may also return the updated user details.\n\n### Notes\n\n- Ensure that the user ID provided in the request is valid and corresponds to an existing user in the system.\n\n- The permissions object allows for fine-grained control over what the user can access, so be sure to set these values according to your application's requirements.\n\n- If any required fields are missing or invalid, the API will return an error response with details about the issue.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "_id": {
                    "type": "string",
                    "description": "Give the id of the user you are updating. The validator treats it as optional, but the update fails without it. Optional in the schema, and unlike the create schema it does not allow an empty string. The controller calls User.findById(_id) and returns 404 when nothing matches, so omitting it returns 404 rather than 400."
                  },
                  "email": {
                    "type": "string",
                    "description": "Give the user's email address. You have to send a valid one on every update, even though the update ignores it. Required. Must be a valid email address. Lowercased and trimmed. An empty string is rejected. The controller never reads this key, so you cannot use it to change the address."
                  },
                  "firstName": {
                    "type": "string",
                    "description": "Set the user's first name. Leave it out to keep the stored value. Optional. Trimmed. No minimum or maximum length. Omitted keys are stripped from the update, so they keep their stored values (keys you leave out are not written)."
                  },
                  "lastName": {
                    "type": "string",
                    "description": "Set the user's last name. Leave it out to keep the stored value. Optional. Trimmed. No minimum or maximum length. Omitted keys are stripped from the update, so they keep their stored values."
                  },
                  "isActive": {
                    "type": "boolean",
                    "description": "Set whether the account stays active. Send false to deactivate the user, which also disconnects their calendars. Optional. The declared default is true, but the middleware discards the converted value, so no default is applied to the request and leaving it out keeps the current state. Sending false for a currently active user triggers a calendar disconnect."
                  },
                  "isVerified": {
                    "type": "boolean",
                    "description": "Accepted for compatibility. The update endpoint ignores it. Optional. The declared default is true, with the same discarded-conversion caveat. The update controller never reads this key."
                  },
                  "permission": {
                    "type": "object",
                    "description": "Set what the user can do. The validator treats this as optional, but the update fails without it. Same fixed key set as the create endpoint, defined. Unknown keys are rejected. Accepted keys: `role` (string, one of owner, admin, member); `folder` object with create, delete, download, share, assign, accessAll; `recorder` object with create, edit, delete, download, accessAll; `media` object with delete, edit, download, share; `payment` object with manageCards, manageInvoices; `teamManagement` object with manageMembers, manageGroups; `developer` object with accessKeys; `profileSettings` object with accountPreferences, accountCustomization, dataManagement; `meetingAssistant` object with customizeAssistant, shareMeetings, routeMeetings, excludeMeetings, globalSettings. Every leaf key is a boolean. The controller reads permission.role without a null check, and the resulting error is caught at:237-240, so omitting permission returns 500 rather than 400. Setting meetingAssistant.customizeAssistant to false also deletes the user's meeting assistant settings (:214-224)."
                  }
                },
                "required": [
                  "email"
                ]
              },
              "example": {
                "_id": "string",
                "email": "",
                "firstName": "Vatsal",
                "lastName": "Shah",
                "isActive": true,
                "isVerified": true,
                "permission": {
                  "audio": true,
                  "video": true,
                  "text": true,
                  "addPayment": false,
                  "userManagement": false
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "update-user": {
                    "summary": "Update User",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/admin/users": {
      "get": {
        "tags": [
          "Admin"
        ],
        "summary": "List users",
        "operationId": "admin-list-users",
        "description": "## Get Users\n\nThis endpoint retrieves a list of users from the admin panel. It is primarily used by administrators to access user information stored in the system.\n\n### Request\n\n- **Method**: GET\n\n- **Endpoint**: `{{url}}/v1/admin/users`\n\n\n### Response\n\nThe response will contain a JSON object with the following structure:\n\n- **users**: An array of user objects, where each user object includes:\n\n - **id**: Unique identifier for the user.\n\n - **name**: The name of the user.\n\n - **email**: The email address of the user.\n\n - **role**: The role assigned to the user (e.g., admin, user).\n\n - **status**: The current status of the user (e.g., active, inactive).\n\n\n### Example Response\n\n``` json\n{\n \"users\": [\n {\n \"id\": \"123\",\n \"name\": \"John Doe\",\n \"email\": \"john.doe@example.com\",\n \"role\": \"admin\",\n \"status\": \"active\"\n },\n {\n \"id\": \"124\",\n \"name\": \"Jane Smith\",\n \"email\": \"jane.smith@example.com\",\n \"role\": \"user\",\n \"status\": \"inactive\"\n }\n ]\n}\n\n ```\n\n### Notes\n\n- Ensure that appropriate authentication and authorization headers are included in the request to access this endpoint.\n\n- The response may vary based on the user's permissions and the number of users in the system.",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "list-users": {
                    "summary": "List users",
                    "value": ""
                  }
                }
              }
            }
          }
        }
      }
    },
    "/webhook": {
      "post": {
        "tags": [
          "Webhook"
        ],
        "summary": "Create Webhook",
        "operationId": "webhook-create-webhook",
        "description": "Webhooks are the means by which you receive notification in the instant event you are subscribed to is triggered. We support several media events right now:\n\nSpeak will send you a `POST` request to the webhookUrl.\n\nWe will send you related keys in the `body` params such as `mediaId`, `recorderId`, `state`, `meetingAssistantId` or `meetingAssistantStatus`\n\n**For Media Files:**\n\n- `media.created`\n\n- `media.analyzed`\n\n- `media.reanalyzed`\n\n- `media.failed`\n\n- `media.deleted`\n\n\n**For Text Files:**\n\n- `text.created`\n\n - You will receive the foll\n\n- `text.analyzed`\n\n - You will receive following keys: `mediaId`, `state`\n\n- `text.reanalyzed`\n\n - You will receive following keys: `mediaId`, `state`\n\n- `text.failed`\n\n - You wil receive following keys: `mediaId`\n\n- `text.deleted`\n\n - You will receive the following keys: `mediaId`\n\n\n**For Embed Recorder:**\n\n- `embed_recorder.created`\n\n - You will receive following keys: `recorderId`\n\n- `embed_recorder.deleted`\n\n - You will receive following keys: `recorderId`\n\n- `embed_recorder.recording_received`\n\n - You will receive following keys: `recorderId`, `mediaId`\n\n\n**For Meeting Assistant:**\n\n- `meeting_assistant.status`\n\n - Trigger a webhook for meeting assistant status changes for following status: Joining call, Waiting room, In call not recording, In call recording, Call ended, Error.\n\n - You will receive following keys: **`mediaId, meetingAssistantId`**, and **`meetingAssistantStatus`**\n\n\n**For AI Chat:**\n\n- `chat.status`\n\n - AI Chat response with the final answer.\n\n - You will receive follwoing keys: `mediaIds, folderId, state, promptId, messageId and answer`\n\n\n**For CSV Files:**\n\n- `csv.uploaded`\n\n - When you upload the CSV file, it will return with `fileId, totalRecords, succeededRecords`\n\n- `csv.failed`\n\n - When there is a failure or few records failed, you will receive fileId\n `fileId, totalRecords, failedRecords, failedRecordsList`\n\n\nYou can subscribe to one or more events at once for one media, and then later update your webhook as needed.\nInternally, Speak Ai system will `POST` to `callbackURL` with provided `metaData` as a request body, the attempt will be recorded and you can access the results, errors and response times in [https://app.speakai.co/developers#webhooks](https://app.speakai.co/developers#webhooks)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "callbackUrl": {
                    "type": "string",
                    "description": "Give the URL Speak posts events to. required; validated as a plain string with no length cap and no uri format check"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "List the events you want this webhook to receive. optional. The array carries no.required, no.optional and no min or max item count; the schema keys are optional by default. Each item must be one of the 18 listed values, which come from the WebhookEvent list. The enum applies to the array items, not to the array itself.",
                    "enum": [
                      "embed_recorder.created",
                      "embed_recorder.deleted",
                      "embed_recorder.recording_received",
                      "media.analyzed",
                      "media.created",
                      "media.deleted",
                      "media.failed",
                      "media.reanalyzed",
                      "media.updated",
                      "text.analyzed",
                      "text.created",
                      "text.deleted",
                      "text.failed",
                      "text.reanalyzed",
                      "meeting_assistant.status",
                      "chat.status",
                      "csv.uploaded",
                      "csv.failed"
                    ]
                  },
                  "metaData": {
                    "type": "object",
                    "description": "Attach your own data to the webhook. Speak merges this object into the body of every delivery for this webhook, then adds eventType and deliveryId and the fields for the event that fired. optional, unconstrained object, any keys accepted. Delivery body is built as {.webhook.metaData, eventType, deliveryId } plus event fields, so a metaData key named eventType, deliveryId, state, mediaId, mediaIds, folderId, recorderId, promptId, messageId, prompt, answer, meetingAssistantId or meetingAssistantStatus is overwritten by Speak's own value."
                  },
                  "mediaId": {
                    "type": "string",
                    "description": "Scope the webhook to a single media item instead of your whole account. optional, empty string allowed, no length cap"
                  },
                  "description": {
                    "type": "string",
                    "description": "Describe what this webhook does on your side so you can recognize it later. optional, empty string allowed, no length cap"
                  },
                  "source": {
                    "type": "string",
                    "description": "Say which tool is creating the webhook. Leave it out and the webhook is stored as \"speak\". optional; values come from the WebhookEventSource list. The schema.default('speak') is not what applies it: the controller passes source through untouched and the stored record defaults to 'speak'.",
                    "enum": [
                      "speak",
                      "zapier",
                      "n8n",
                      "pipedream",
                      "make"
                    ]
                  }
                },
                "required": [
                  "callbackUrl"
                ]
              },
              "example": {
                "callbackUrl": "https://example.com/webhooks/speak",
                "metaData": {
                  "providedInternalUUID": "111222333"
                },
                "events": [
                  "media.created",
                  "media.analyzed",
                  "text.created",
                  "text.analyzed",
                  "text.reanalyzed",
                  "text.failed",
                  "text.deleted",
                  "media.reanalyzed",
                  "media.failed",
                  "media.deleted"
                ],
                "description": "This is a readable explanation of what this webhook does on your side."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "webhookId": {
                          "type": "string",
                          "description": "The id of the webhook you just created. Store it, because you need it to update, test or delete the webhook."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "webhookId": "608850ed4cb70a295c0ddf5b"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Webhook"
        ],
        "summary": "List",
        "operationId": "webhook-list",
        "description": "If you want to list all the exisitng webhooks",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "totalCount": {
                          "type": "integer",
                          "description": "How many webhooks you have in total, so you can page through them."
                        },
                        "webhooks": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "events": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "isActive": {
                                "type": "boolean"
                              },
                              "_id": {
                                "type": "string",
                                "description": "The id of this webhook. Pass it as `webhookId` to update, test or delete it."
                              },
                              "callbackUrl": {
                                "type": "string"
                              },
                              "metaData": {
                                "type": "object",
                                "properties": {
                                  "providedInternalUUID": {
                                    "type": "string"
                                  }
                                }
                              },
                              "description": {
                                "type": "string"
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "list-webhooks": {
                    "summary": "List Webhooks",
                    "value": {
                      "status": "success",
                      "data": {
                        "totalCount": 1,
                        "webhooks": [
                          {
                            "events": [
                              "media.created"
                            ],
                            "isActive": true,
                            "_id": "60884fec4cb70a295c0ddf59",
                            "callbackUrl": "https://example.com/webhooks/speak",
                            "metaData": {
                              "providedInternalUUID": "111222333"
                            },
                            "description": "This is an edited explanation.",
                            "createdAt": "2021-04-27T17:54:52.250Z"
                          }
                        ]
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          }
        }
      }
    },
    "/webhook/test/{webhookId}": {
      "post": {
        "tags": [
          "Webhook"
        ],
        "summary": "Test",
        "operationId": "webhook-test",
        "description": "Looking to test the webhook without uploading much media in your account ? Testing is made easier using this endpoint. You can trigger an event on a particular webhook and get the request\\response or error.",
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "659ee5c7350d7f6593fd36ea"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "event": {
                    "type": "string",
                    "description": "Pick the event to fire so you can see the request, the response and any error your endpoint returns. required; the 18 values come from the WebhookEvent list. No other body key is accepted, so any extra property returns a 400.",
                    "enum": [
                      "embed_recorder.created",
                      "embed_recorder.deleted",
                      "embed_recorder.recording_received",
                      "media.analyzed",
                      "media.created",
                      "media.deleted",
                      "media.failed",
                      "media.reanalyzed",
                      "media.updated",
                      "text.analyzed",
                      "text.created",
                      "text.deleted",
                      "text.failed",
                      "text.reanalyzed",
                      "meeting_assistant.status",
                      "chat.status",
                      "csv.uploaded",
                      "csv.failed"
                    ]
                  }
                },
                "required": [
                  "event"
                ]
              },
              "example": {
                "event": "media.created"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "isFirstAttempt": {
                          "type": "boolean"
                        },
                        "_id": {
                          "type": "string"
                        },
                        "webhookId": {
                          "type": "string"
                        },
                        "event": {
                          "type": "string"
                        },
                        "requestBody": {
                          "type": "string"
                        },
                        "responseBody": {
                          "type": "string"
                        },
                        "responseTime": {
                          "type": "integer"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "__v": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "isFirstAttempt": true,
                        "_id": "608854d7368c102ad3d3ad53",
                        "webhookId": "60884fec4cb70a295c0ddf59",
                        "event": "media.created",
                        "requestBody": "{\"providedInternalUUID\":\"111222333\"}",
                        "responseBody": "{\"message\":\"My UUID is 111222333.\"}",
                        "responseTime": 48,
                        "createdAt": "2021-04-27T18:15:51.686Z",
                        "__v": 0
                      }
                    }
                  },
                  "error": {
                    "summary": "Error",
                    "value": {
                      "status": "success",
                      "data": {
                        "isFirstAttempt": true,
                        "_id": "608854d7368c102ad3d3ad53",
                        "webhookId": "60884fec4cb70a295c0ddf59",
                        "event": "media.created",
                        "requestBody": "{\"providedInternalUUID\":\"111222333\"}",
                        "responseBody": "{\"message\":\"invalid json response body at https://example.com/webhooks/speak reason: Unexpected token < in JSON at position 0\",\"type\":\"invalid-json\"}",
                        "responseTime": 48,
                        "createdAt": "2021-04-27T18:15:51.686Z",
                        "__v": 0
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/webhook/{webhookId}": {
      "put": {
        "tags": [
          "Webhook"
        ],
        "summary": "Update",
        "operationId": "webhook-update",
        "description": "You can update definition of an existing webhook: change events it's subscribed to, edit description or your `metaData`.\n\nThis is a partial update. Send `callbackUrl` on every call, and send only the other fields you want to change: any field you leave out keeps its stored value. To clear a field, send it with an empty value rather than omitting it.",
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "609d7de35bde285f4c98ca63"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "callbackUrl": {
                    "type": "string",
                    "description": "Give the URL Speak posts events to. Send it on every update, even when you are only changing something else. required; validated as a plain string with no length cap and no uri format check"
                  },
                  "metaData": {
                    "type": "object",
                    "description": "Replace the data Speak merges into the body of every delivery for this webhook. Speak adds eventType, deliveryId and the fields for the event that fired on top of it. optional, unconstrained object, any keys accepted. Omit it and the stored value is left unchanged: the controller passes the destructured value into findOneAndUpdate, and an undefined key is dropped before the update is sent rather than written over what is there."
                  },
                  "mediaId": {
                    "type": "string",
                    "description": "Scope the webhook to a single media item instead of your whole account. optional, empty string allowed, no length cap"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Replace the list of events this webhook receives. explicitly.optional; no minimum or maximum item count. Each item must be one of the 18 listed values, which come from WebhookEvent.",
                    "enum": [
                      "embed_recorder.created",
                      "embed_recorder.deleted",
                      "embed_recorder.recording_received",
                      "media.analyzed",
                      "media.created",
                      "media.deleted",
                      "media.failed",
                      "media.reanalyzed",
                      "media.updated",
                      "text.analyzed",
                      "text.created",
                      "text.deleted",
                      "text.failed",
                      "text.reanalyzed",
                      "meeting_assistant.status",
                      "chat.status",
                      "csv.uploaded",
                      "csv.failed"
                    ]
                  },
                  "description": {
                    "type": "string",
                    "description": "Describe what this webhook does on your side so you can recognize it later. optional, empty string allowed, no length cap"
                  }
                },
                "required": [
                  "callbackUrl"
                ]
              },
              "example": {
                "callbackUrl": "https://example.com/webhooks/speak",
                "metaData": {
                  "providedInternalUUID": "777888999"
                },
                "events": [
                  "media.created",
                  "media.analyzed",
                  "media.deleted"
                ],
                "description": "This is an edited explanation."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "successful": {
                    "summary": "Successful",
                    "value": {
                      "status": "success",
                      "message": "Webhook updated"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Webhook"
        ],
        "summary": "Delete",
        "operationId": "webhook-delete",
        "description": "## DELETE Webhook\n\nThis endpoint allows you to delete a specific webhook identified by its unique `webhookId`.\n\n### Request Parameters\n\n- `webhookId` (path parameter): The unique identifier of the webhook you wish to delete.\n\n\n### Expected Response\n\nUpon successful deletion of the webhook, the API will return a JSON object with the following structure:\n\n- `status`: A string indicating the status of the request.\n\n- `message`: A string providing additional information about the result of the operation.\n\n\n### Notes\n\n- Ensure that the `webhookId` provided in the request is valid and corresponds to an existing webhook.\n\n- Deleting a webhook is irreversible; once deleted, the webhook cannot be recovered.",
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "609d7de35bde285f4c98ca63"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "message": "Webhook deleted!"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/voice/agents": {
      "get": {
        "tags": [
          "Voice Agents"
        ],
        "summary": "List Voice Agents",
        "operationId": "voice-agents-list",
        "description": "### List Agents\n\nReturns every non-deleted agent in your company, newest first, each annotated with its conversation count.\n\n#### Response\n\n`agents` is an array of agent objects, each with an extra `conversationCount` field: the number of conversations recorded against that agent in your company.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "agents": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "MongoDB document id, included because every document has one; use agentId to identify it."
                              },
                              "agentId": {
                                "type": "string",
                                "description": "Server-generated UUID. Immutable \u2014 sent in the body on create or update is silently dropped."
                              },
                              "companyId": {
                                "type": "string",
                                "description": "Stamped from the caller's authenticated company. Sending your own value on create or update is silently dropped; you cannot re-parent an agent."
                              },
                              "userId": {
                                "type": "string",
                                "description": "Id of the user who created the agent."
                              },
                              "name": {
                                "type": "string",
                                "description": "Required on create. Trimmed, non-empty."
                              },
                              "personality": {
                                "type": "string",
                                "description": "Required on create. Free text describing the agent's tone. Can be cleared to an empty string on update."
                              },
                              "instructions": {
                                "type": "string",
                                "description": "Required on create. The agent's system instructions. Can be cleared to an empty string on update."
                              },
                              "voice": {
                                "type": "object",
                                "description": "Required on create.",
                                "properties": {
                                  "provider": {
                                    "type": "string",
                                    "description": "TTS provider, e.g. elevenlabs or openai."
                                  },
                                  "voiceId": {
                                    "type": "string"
                                  },
                                  "model": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "provider",
                                  "voiceId"
                                ]
                              },
                              "stt": {
                                "type": "object",
                                "description": "Speech-to-text provider config. Shape is not validated beyond being an object."
                              },
                              "llm": {
                                "type": "object",
                                "properties": {
                                  "provider": {
                                    "type": "string",
                                    "description": "Must be one of the voice-agent LLM providers if sent."
                                  },
                                  "model": {
                                    "type": "string",
                                    "description": "Must be one of the voice-agent model ids if sent."
                                  }
                                }
                              },
                              "liveVoice": {
                                "type": "string",
                                "nullable": true,
                                "description": "The voice id used when llm.model is a Live (speech-to-speech) model. Rejected with a 400 listing the valid ids if it is not one of the voices the resolved Live model offers. Cleared by sending an empty string or null."
                              },
                              "avatar": {
                                "type": "object",
                                "description": "Set avatar.avatarId to attach an avatar; the server looks it up in your avatar catalog and derives avatarUrl, provider, and any provider-specific ids (e.g. Tavus faceId/palId) from that catalog row. Any of those fields sent in the request body are ignored \u2014 they cannot be set directly. An avatarId with no matching catalog row is rejected with 400, not saved.",
                                "properties": {
                                  "avatarId": {
                                    "type": "string",
                                    "description": "Required to set an avatar. Must match a row in your company's avatar catalog (your own uploads or the shared system catalog)."
                                  },
                                  "avatarUrl": {
                                    "type": "string",
                                    "description": "Read-only in practice: always overwritten from the matched catalog row."
                                  },
                                  "provider": {
                                    "type": "string",
                                    "description": "Read-only in practice: always overwritten from the matched catalog row."
                                  },
                                  "tavusFaceId": {
                                    "type": "string",
                                    "description": "Read-only: derived server-side from the catalog row's tavus.faceId. Cannot be set by the client."
                                  },
                                  "tavusPalId": {
                                    "type": "string",
                                    "description": "Read-only: derived server-side from the catalog row's tavus.palId. Cannot be set by the client."
                                  }
                                }
                              },
                              "conversationMode": {
                                "type": "string",
                                "enum": [
                                  "voice",
                                  "avatar"
                                ]
                              },
                              "status": {
                                "type": "string",
                                "description": "One of the agent status values."
                              },
                              "chatSettings": {
                                "type": "object",
                                "properties": {
                                  "welcomeMessage": {
                                    "type": "string"
                                  },
                                  "conversationStarters": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "maxResponseLength": {
                                    "type": "integer"
                                  },
                                  "topicsToAvoid": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "maxSessionLength": {
                                    "type": "integer"
                                  },
                                  "language": {
                                    "type": "string"
                                  },
                                  "responsePace": {
                                    "type": "string",
                                    "description": "One of the response-pace presets, if set."
                                  }
                                }
                              },
                              "websiteUrl": {
                                "type": "string"
                              },
                              "enableWebSearch": {
                                "type": "boolean"
                              },
                              "creativityLevel": {
                                "type": "number",
                                "minimum": 0,
                                "maximum": 1
                              },
                              "folderId": {
                                "type": "string"
                              },
                              "telephony": {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "type": "boolean"
                                  },
                                  "phoneNumberId": {
                                    "type": "string"
                                  },
                                  "handoff": {
                                    "type": "object",
                                    "properties": {
                                      "enabled": {
                                        "type": "boolean"
                                      },
                                      "targetNumber": {
                                        "type": "string"
                                      },
                                      "summaryPrompt": {
                                        "type": "string"
                                      }
                                    }
                                  },
                                  "settings": {
                                    "type": "object",
                                    "properties": {
                                      "recordCalls": {
                                        "type": "boolean"
                                      }
                                    }
                                  }
                                }
                              },
                              "isDeleted": {
                                "type": "boolean",
                                "description": "DELETE soft-deletes: this flips to true and the agent stops appearing in list/get, but the document is not removed."
                              },
                              "deletedAt": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "conversationCount": {
                                "type": "integer",
                                "description": "Count of conversations recorded against this agent."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "agents": {
                    "value": {
                      "status": "success",
                      "data": {
                        "agents": [
                          {
                            "agentId": "6a1b2c3d4e5f60718293a4b5",
                            "companyId": "6650a1b2c3d4e5f60000000a",
                            "userId": "6650a1b2c3d4e5f60000001a",
                            "name": "Support Agent",
                            "personality": "Friendly and concise",
                            "instructions": "Help callers troubleshoot billing questions.",
                            "voice": {
                              "provider": "elevenlabs",
                              "voiceId": "21m00Tcm4TlvDq8ikWAM"
                            },
                            "llm": {
                              "provider": "openai",
                              "model": "gpt-5.4"
                            },
                            "conversationMode": "voice",
                            "status": "active",
                            "chatSettings": {
                              "language": "en",
                              "maxResponseLength": 500,
                              "maxSessionLength": 1800,
                              "conversationStarters": [],
                              "topicsToAvoid": []
                            },
                            "creativityLevel": 0.7,
                            "isDeleted": false,
                            "createdAt": "2026-09-01T12:00:00.000Z",
                            "updatedAt": "2026-09-23T19:33:24.232Z",
                            "conversationCount": 42
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Agents"
      },
      "post": {
        "tags": [
          "Voice Agents"
        ],
        "summary": "Create Voice Agent",
        "operationId": "voice-agents-create",
        "description": "### Create Agent\n\nRequires the OWNER or ADMIN role.\n\n#### Request Body\n\n`name`, `personality`, `instructions`, and `voice` (with `voice.provider` and `voice.voiceId`) are required. Every other agent field can be set on create.\n\nSet `avatar.avatarId` to attach an avatar from your catalog \u2014 the server resolves `avatarUrl`, `provider`, and any Tavus ids from that catalog row itself; you cannot set those directly.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "_id": {
                    "type": "string",
                    "description": "MongoDB document id, included because every document has one; use agentId to identify it."
                  },
                  "agentId": {
                    "type": "string",
                    "description": "Server-generated UUID. Immutable \u2014 sent in the body on create or update is silently dropped."
                  },
                  "companyId": {
                    "type": "string",
                    "description": "Stamped from the caller's authenticated company. Sending your own value on create or update is silently dropped; you cannot re-parent an agent."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Id of the user who created the agent."
                  },
                  "name": {
                    "type": "string",
                    "description": "Required on create. Trimmed, non-empty."
                  },
                  "personality": {
                    "type": "string",
                    "description": "Required on create. Free text describing the agent's tone. Can be cleared to an empty string on update."
                  },
                  "instructions": {
                    "type": "string",
                    "description": "Required on create. The agent's system instructions. Can be cleared to an empty string on update."
                  },
                  "voice": {
                    "type": "object",
                    "description": "Required on create.",
                    "properties": {
                      "provider": {
                        "type": "string",
                        "description": "TTS provider, e.g. elevenlabs or openai."
                      },
                      "voiceId": {
                        "type": "string"
                      },
                      "model": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "provider",
                      "voiceId"
                    ]
                  },
                  "stt": {
                    "type": "object",
                    "description": "Speech-to-text provider config. Shape is not validated beyond being an object."
                  },
                  "llm": {
                    "type": "object",
                    "properties": {
                      "provider": {
                        "type": "string",
                        "description": "Must be one of the voice-agent LLM providers if sent."
                      },
                      "model": {
                        "type": "string",
                        "description": "Must be one of the voice-agent model ids if sent."
                      }
                    }
                  },
                  "liveVoice": {
                    "type": "string",
                    "nullable": true,
                    "description": "The voice id used when llm.model is a Live (speech-to-speech) model. Rejected with a 400 listing the valid ids if it is not one of the voices the resolved Live model offers. Cleared by sending an empty string or null."
                  },
                  "avatar": {
                    "type": "object",
                    "description": "Set avatar.avatarId to attach an avatar; the server looks it up in your avatar catalog and derives avatarUrl, provider, and any provider-specific ids (e.g. Tavus faceId/palId) from that catalog row. Any of those fields sent in the request body are ignored \u2014 they cannot be set directly. An avatarId with no matching catalog row is rejected with 400, not saved.",
                    "properties": {
                      "avatarId": {
                        "type": "string",
                        "description": "Required to set an avatar. Must match a row in your company's avatar catalog (your own uploads or the shared system catalog)."
                      },
                      "avatarUrl": {
                        "type": "string",
                        "description": "Read-only in practice: always overwritten from the matched catalog row."
                      },
                      "provider": {
                        "type": "string",
                        "description": "Read-only in practice: always overwritten from the matched catalog row."
                      },
                      "tavusFaceId": {
                        "type": "string",
                        "description": "Read-only: derived server-side from the catalog row's tavus.faceId. Cannot be set by the client."
                      },
                      "tavusPalId": {
                        "type": "string",
                        "description": "Read-only: derived server-side from the catalog row's tavus.palId. Cannot be set by the client."
                      }
                    }
                  },
                  "conversationMode": {
                    "type": "string",
                    "enum": [
                      "voice",
                      "avatar"
                    ]
                  },
                  "status": {
                    "type": "string",
                    "description": "One of the agent status values."
                  },
                  "chatSettings": {
                    "type": "object",
                    "properties": {
                      "welcomeMessage": {
                        "type": "string"
                      },
                      "conversationStarters": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "maxResponseLength": {
                        "type": "integer"
                      },
                      "topicsToAvoid": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "maxSessionLength": {
                        "type": "integer"
                      },
                      "language": {
                        "type": "string"
                      },
                      "responsePace": {
                        "type": "string",
                        "description": "One of the response-pace presets, if set."
                      }
                    }
                  },
                  "websiteUrl": {
                    "type": "string"
                  },
                  "enableWebSearch": {
                    "type": "boolean"
                  },
                  "creativityLevel": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                  },
                  "folderId": {
                    "type": "string"
                  },
                  "telephony": {
                    "type": "object",
                    "properties": {
                      "enabled": {
                        "type": "boolean"
                      },
                      "phoneNumberId": {
                        "type": "string"
                      },
                      "handoff": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean"
                          },
                          "targetNumber": {
                            "type": "string",
                            "description": "The number the call is transferred to when the agent hands off to a person. Must be in E.164 format: a plus sign, then 2 to 15 digits, the first of which cannot be zero (for example +15551234567). Conditionally required: required when `handoff.enabled` is true, otherwise optional and an empty string is accepted. A malformed number returns 400 even when `handoff.enabled` is false."
                          },
                          "summaryPrompt": {
                            "type": "string"
                          }
                        }
                      },
                      "settings": {
                        "type": "object",
                        "properties": {
                          "recordCalls": {
                            "type": "boolean"
                          }
                        }
                      }
                    },
                    "description": "Telephony settings for the agent: whether phone calls are enabled, which of your phone numbers the agent uses, call recording, and handoff to a person. Accepted on create and, unlike most other server-managed fields, NOT stripped on update. The keys listed here are validated, so a malformed value returns 400: `enabled` and `settings.recordCalls` must be booleans, `phoneNumberId` must be a string, and `handoff.targetNumber` must be an E.164 number, required whenever `handoff.enabled` is true. Unknown keys inside the object are still accepted and stored as sent. Setting `phoneNumberId` is not the same as assigning that number to the agent: the assignment lives on the phone number's own `agentId` field and is written by the phone number endpoints, which this reference does not yet cover."
                  },
                  "isDeleted": {
                    "type": "boolean",
                    "description": "DELETE soft-deletes: this flips to true and the agent stops appearing in list/get, but the document is not removed."
                  },
                  "deletedAt": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "updatedAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                },
                "required": [
                  "name",
                  "personality",
                  "instructions",
                  "voice"
                ]
              },
              "examples": {
                "create-agent": {
                  "value": {
                    "name": "Support Agent",
                    "personality": "Friendly and concise",
                    "instructions": "Help callers troubleshoot billing questions.",
                    "voice": {
                      "provider": "elevenlabs",
                      "voiceId": "21m00Tcm4TlvDq8ikWAM"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "agent": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use agentId to identify it."
                            },
                            "agentId": {
                              "type": "string",
                              "description": "Server-generated UUID. Immutable \u2014 sent in the body on create or update is silently dropped."
                            },
                            "companyId": {
                              "type": "string",
                              "description": "Stamped from the caller's authenticated company. Sending your own value on create or update is silently dropped; you cannot re-parent an agent."
                            },
                            "userId": {
                              "type": "string",
                              "description": "Id of the user who created the agent."
                            },
                            "name": {
                              "type": "string",
                              "description": "Required on create. Trimmed, non-empty."
                            },
                            "personality": {
                              "type": "string",
                              "description": "Required on create. Free text describing the agent's tone. Can be cleared to an empty string on update."
                            },
                            "instructions": {
                              "type": "string",
                              "description": "Required on create. The agent's system instructions. Can be cleared to an empty string on update."
                            },
                            "voice": {
                              "type": "object",
                              "description": "Required on create.",
                              "properties": {
                                "provider": {
                                  "type": "string",
                                  "description": "TTS provider, e.g. elevenlabs or openai."
                                },
                                "voiceId": {
                                  "type": "string"
                                },
                                "model": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "provider",
                                "voiceId"
                              ]
                            },
                            "stt": {
                              "type": "object",
                              "description": "Speech-to-text provider config. Shape is not validated beyond being an object."
                            },
                            "llm": {
                              "type": "object",
                              "properties": {
                                "provider": {
                                  "type": "string",
                                  "description": "Must be one of the voice-agent LLM providers if sent."
                                },
                                "model": {
                                  "type": "string",
                                  "description": "Must be one of the voice-agent model ids if sent."
                                }
                              }
                            },
                            "liveVoice": {
                              "type": "string",
                              "nullable": true,
                              "description": "The voice id used when llm.model is a Live (speech-to-speech) model. Rejected with a 400 listing the valid ids if it is not one of the voices the resolved Live model offers. Cleared by sending an empty string or null."
                            },
                            "avatar": {
                              "type": "object",
                              "description": "Set avatar.avatarId to attach an avatar; the server looks it up in your avatar catalog and derives avatarUrl, provider, and any provider-specific ids (e.g. Tavus faceId/palId) from that catalog row. Any of those fields sent in the request body are ignored \u2014 they cannot be set directly. An avatarId with no matching catalog row is rejected with 400, not saved.",
                              "properties": {
                                "avatarId": {
                                  "type": "string",
                                  "description": "Required to set an avatar. Must match a row in your company's avatar catalog (your own uploads or the shared system catalog)."
                                },
                                "avatarUrl": {
                                  "type": "string",
                                  "description": "Read-only in practice: always overwritten from the matched catalog row."
                                },
                                "provider": {
                                  "type": "string",
                                  "description": "Read-only in practice: always overwritten from the matched catalog row."
                                },
                                "tavusFaceId": {
                                  "type": "string",
                                  "description": "Read-only: derived server-side from the catalog row's tavus.faceId. Cannot be set by the client."
                                },
                                "tavusPalId": {
                                  "type": "string",
                                  "description": "Read-only: derived server-side from the catalog row's tavus.palId. Cannot be set by the client."
                                }
                              }
                            },
                            "conversationMode": {
                              "type": "string",
                              "enum": [
                                "voice",
                                "avatar"
                              ]
                            },
                            "status": {
                              "type": "string",
                              "description": "One of the agent status values."
                            },
                            "chatSettings": {
                              "type": "object",
                              "properties": {
                                "welcomeMessage": {
                                  "type": "string"
                                },
                                "conversationStarters": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "maxResponseLength": {
                                  "type": "integer"
                                },
                                "topicsToAvoid": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "maxSessionLength": {
                                  "type": "integer"
                                },
                                "language": {
                                  "type": "string"
                                },
                                "responsePace": {
                                  "type": "string",
                                  "description": "One of the response-pace presets, if set."
                                }
                              }
                            },
                            "websiteUrl": {
                              "type": "string"
                            },
                            "enableWebSearch": {
                              "type": "boolean"
                            },
                            "creativityLevel": {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 1
                            },
                            "folderId": {
                              "type": "string"
                            },
                            "telephony": {
                              "type": "object",
                              "properties": {
                                "enabled": {
                                  "type": "boolean"
                                },
                                "phoneNumberId": {
                                  "type": "string"
                                },
                                "handoff": {
                                  "type": "object",
                                  "properties": {
                                    "enabled": {
                                      "type": "boolean"
                                    },
                                    "targetNumber": {
                                      "type": "string"
                                    },
                                    "summaryPrompt": {
                                      "type": "string"
                                    }
                                  }
                                },
                                "settings": {
                                  "type": "object",
                                  "properties": {
                                    "recordCalls": {
                                      "type": "boolean"
                                    }
                                  }
                                }
                              }
                            },
                            "isDeleted": {
                              "type": "boolean",
                              "description": "DELETE soft-deletes: this flips to true and the agent stops appearing in list/get, but the document is not removed."
                            },
                            "deletedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "agent": {
                    "value": {
                      "status": "success",
                      "data": {
                        "agent": {
                          "agentId": "6a1b2c3d4e5f60718293a4b5",
                          "companyId": "6650a1b2c3d4e5f60000000a",
                          "userId": "6650a1b2c3d4e5f60000001a",
                          "name": "Support Agent",
                          "personality": "Friendly and concise",
                          "instructions": "Help callers troubleshoot billing questions.",
                          "voice": {
                            "provider": "elevenlabs",
                            "voiceId": "21m00Tcm4TlvDq8ikWAM"
                          },
                          "llm": {
                            "provider": "openai",
                            "model": "gpt-5.4"
                          },
                          "conversationMode": "voice",
                          "status": "active",
                          "chatSettings": {
                            "language": "en",
                            "maxResponseLength": 500,
                            "maxSessionLength": 1800,
                            "conversationStarters": [],
                            "topicsToAvoid": []
                          },
                          "creativityLevel": 0.7,
                          "isDeleted": false,
                          "createdAt": "2026-09-01T12:00:00.000Z",
                          "updatedAt": "2026-09-23T19:33:24.232Z"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed, or avatar.avatarId does not match a catalog row",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Agents"
      }
    },
    "/voice/agents/{agentId}": {
      "get": {
        "tags": [
          "Voice Agents"
        ],
        "summary": "Get Voice Agent",
        "operationId": "voice-agents-get",
        "description": "### Get Agent\n\nFetches a single agent by id, scoped to your company. Returns 404 for an agent belonging to another company or one that has been deleted \u2014 the response does not distinguish between the two.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "agent": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use agentId to identify it."
                            },
                            "agentId": {
                              "type": "string",
                              "description": "Server-generated UUID. Immutable \u2014 sent in the body on create or update is silently dropped."
                            },
                            "companyId": {
                              "type": "string",
                              "description": "Stamped from the caller's authenticated company. Sending your own value on create or update is silently dropped; you cannot re-parent an agent."
                            },
                            "userId": {
                              "type": "string",
                              "description": "Id of the user who created the agent."
                            },
                            "name": {
                              "type": "string",
                              "description": "Required on create. Trimmed, non-empty."
                            },
                            "personality": {
                              "type": "string",
                              "description": "Required on create. Free text describing the agent's tone. Can be cleared to an empty string on update."
                            },
                            "instructions": {
                              "type": "string",
                              "description": "Required on create. The agent's system instructions. Can be cleared to an empty string on update."
                            },
                            "voice": {
                              "type": "object",
                              "description": "Required on create.",
                              "properties": {
                                "provider": {
                                  "type": "string",
                                  "description": "TTS provider, e.g. elevenlabs or openai."
                                },
                                "voiceId": {
                                  "type": "string"
                                },
                                "model": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "provider",
                                "voiceId"
                              ]
                            },
                            "stt": {
                              "type": "object",
                              "description": "Speech-to-text provider config. Shape is not validated beyond being an object."
                            },
                            "llm": {
                              "type": "object",
                              "properties": {
                                "provider": {
                                  "type": "string",
                                  "description": "Must be one of the voice-agent LLM providers if sent."
                                },
                                "model": {
                                  "type": "string",
                                  "description": "Must be one of the voice-agent model ids if sent."
                                }
                              }
                            },
                            "liveVoice": {
                              "type": "string",
                              "nullable": true,
                              "description": "The voice id used when llm.model is a Live (speech-to-speech) model. Rejected with a 400 listing the valid ids if it is not one of the voices the resolved Live model offers. Cleared by sending an empty string or null."
                            },
                            "avatar": {
                              "type": "object",
                              "description": "Set avatar.avatarId to attach an avatar; the server looks it up in your avatar catalog and derives avatarUrl, provider, and any provider-specific ids (e.g. Tavus faceId/palId) from that catalog row. Any of those fields sent in the request body are ignored \u2014 they cannot be set directly. An avatarId with no matching catalog row is rejected with 400, not saved.",
                              "properties": {
                                "avatarId": {
                                  "type": "string",
                                  "description": "Required to set an avatar. Must match a row in your company's avatar catalog (your own uploads or the shared system catalog)."
                                },
                                "avatarUrl": {
                                  "type": "string",
                                  "description": "Read-only in practice: always overwritten from the matched catalog row."
                                },
                                "provider": {
                                  "type": "string",
                                  "description": "Read-only in practice: always overwritten from the matched catalog row."
                                },
                                "tavusFaceId": {
                                  "type": "string",
                                  "description": "Read-only: derived server-side from the catalog row's tavus.faceId. Cannot be set by the client."
                                },
                                "tavusPalId": {
                                  "type": "string",
                                  "description": "Read-only: derived server-side from the catalog row's tavus.palId. Cannot be set by the client."
                                }
                              }
                            },
                            "conversationMode": {
                              "type": "string",
                              "enum": [
                                "voice",
                                "avatar"
                              ]
                            },
                            "status": {
                              "type": "string",
                              "description": "One of the agent status values."
                            },
                            "chatSettings": {
                              "type": "object",
                              "properties": {
                                "welcomeMessage": {
                                  "type": "string"
                                },
                                "conversationStarters": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "maxResponseLength": {
                                  "type": "integer"
                                },
                                "topicsToAvoid": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "maxSessionLength": {
                                  "type": "integer"
                                },
                                "language": {
                                  "type": "string"
                                },
                                "responsePace": {
                                  "type": "string",
                                  "description": "One of the response-pace presets, if set."
                                }
                              }
                            },
                            "websiteUrl": {
                              "type": "string"
                            },
                            "enableWebSearch": {
                              "type": "boolean"
                            },
                            "creativityLevel": {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 1
                            },
                            "folderId": {
                              "type": "string"
                            },
                            "telephony": {
                              "type": "object",
                              "properties": {
                                "enabled": {
                                  "type": "boolean"
                                },
                                "phoneNumberId": {
                                  "type": "string"
                                },
                                "handoff": {
                                  "type": "object",
                                  "properties": {
                                    "enabled": {
                                      "type": "boolean"
                                    },
                                    "targetNumber": {
                                      "type": "string"
                                    },
                                    "summaryPrompt": {
                                      "type": "string"
                                    }
                                  }
                                },
                                "settings": {
                                  "type": "object",
                                  "properties": {
                                    "recordCalls": {
                                      "type": "boolean"
                                    }
                                  }
                                }
                              }
                            },
                            "isDeleted": {
                              "type": "boolean",
                              "description": "DELETE soft-deletes: this flips to true and the agent stops appearing in list/get, but the document is not removed."
                            },
                            "deletedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "agent": {
                    "value": {
                      "status": "success",
                      "data": {
                        "agent": {
                          "agentId": "6a1b2c3d4e5f60718293a4b5",
                          "companyId": "6650a1b2c3d4e5f60000000a",
                          "userId": "6650a1b2c3d4e5f60000001a",
                          "name": "Support Agent",
                          "personality": "Friendly and concise",
                          "instructions": "Help callers troubleshoot billing questions.",
                          "voice": {
                            "provider": "elevenlabs",
                            "voiceId": "21m00Tcm4TlvDq8ikWAM"
                          },
                          "llm": {
                            "provider": "openai",
                            "model": "gpt-5.4"
                          },
                          "conversationMode": "voice",
                          "status": "active",
                          "chatSettings": {
                            "language": "en",
                            "maxResponseLength": 500,
                            "maxSessionLength": 1800,
                            "conversationStarters": [],
                            "topicsToAvoid": []
                          },
                          "creativityLevel": 0.7,
                          "isDeleted": false,
                          "createdAt": "2026-09-01T12:00:00.000Z",
                          "updatedAt": "2026-09-23T19:33:24.232Z"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Agents"
      },
      "put": {
        "tags": [
          "Voice Agents"
        ],
        "summary": "Update Voice Agent",
        "operationId": "voice-agents-update",
        "description": "### Update Agent\n\nRequires the OWNER or ADMIN role. Partial update \u2014 send only the fields you want to change; fields left out of the body are left untouched, including `avatar`. `companyId`, `agentId`, and other immutable fields are silently dropped if sent.\n\nIf the body sets `avatar.avatarId`, the server re-resolves `avatarUrl`/`provider`/Tavus ids from the catalog row and overwrites the agent's whole avatar sub-object with that resolved value; an unresolvable `avatarId` is rejected with 400 rather than saved.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "_id": {
                    "type": "string",
                    "description": "MongoDB document id, included because every document has one; use agentId to identify it."
                  },
                  "agentId": {
                    "type": "string",
                    "description": "Server-generated UUID. Immutable \u2014 sent in the body on create or update is silently dropped."
                  },
                  "companyId": {
                    "type": "string",
                    "description": "Stamped from the caller's authenticated company. Sending your own value on create or update is silently dropped; you cannot re-parent an agent."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Id of the user who created the agent."
                  },
                  "name": {
                    "type": "string",
                    "description": "Required on create. Trimmed, non-empty."
                  },
                  "personality": {
                    "type": "string",
                    "description": "Required on create. Free text describing the agent's tone. Can be cleared to an empty string on update."
                  },
                  "instructions": {
                    "type": "string",
                    "description": "Required on create. The agent's system instructions. Can be cleared to an empty string on update."
                  },
                  "voice": {
                    "type": "object",
                    "description": "Required on create.",
                    "properties": {
                      "provider": {
                        "type": "string",
                        "description": "TTS provider, e.g. elevenlabs or openai."
                      },
                      "voiceId": {
                        "type": "string"
                      },
                      "model": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "provider",
                      "voiceId"
                    ]
                  },
                  "stt": {
                    "type": "object",
                    "description": "Speech-to-text provider config. Shape is not validated beyond being an object."
                  },
                  "llm": {
                    "type": "object",
                    "properties": {
                      "provider": {
                        "type": "string",
                        "description": "Must be one of the voice-agent LLM providers if sent."
                      },
                      "model": {
                        "type": "string",
                        "description": "Must be one of the voice-agent model ids if sent."
                      }
                    }
                  },
                  "liveVoice": {
                    "type": "string",
                    "nullable": true,
                    "description": "The voice id used when llm.model is a Live (speech-to-speech) model. Rejected with a 400 listing the valid ids if it is not one of the voices the resolved Live model offers. Cleared by sending an empty string or null."
                  },
                  "avatar": {
                    "type": "object",
                    "description": "Set avatar.avatarId to attach an avatar; the server looks it up in your avatar catalog and derives avatarUrl, provider, and any provider-specific ids (e.g. Tavus faceId/palId) from that catalog row. Any of those fields sent in the request body are ignored \u2014 they cannot be set directly. An avatarId with no matching catalog row is rejected with 400, not saved.",
                    "properties": {
                      "avatarId": {
                        "type": "string",
                        "description": "Required to set an avatar. Must match a row in your company's avatar catalog (your own uploads or the shared system catalog)."
                      },
                      "avatarUrl": {
                        "type": "string",
                        "description": "Read-only in practice: always overwritten from the matched catalog row."
                      },
                      "provider": {
                        "type": "string",
                        "description": "Read-only in practice: always overwritten from the matched catalog row."
                      },
                      "tavusFaceId": {
                        "type": "string",
                        "description": "Read-only: derived server-side from the catalog row's tavus.faceId. Cannot be set by the client."
                      },
                      "tavusPalId": {
                        "type": "string",
                        "description": "Read-only: derived server-side from the catalog row's tavus.palId. Cannot be set by the client."
                      }
                    }
                  },
                  "conversationMode": {
                    "type": "string",
                    "enum": [
                      "voice",
                      "avatar"
                    ]
                  },
                  "status": {
                    "type": "string",
                    "description": "One of the agent status values."
                  },
                  "chatSettings": {
                    "type": "object",
                    "properties": {
                      "welcomeMessage": {
                        "type": "string"
                      },
                      "conversationStarters": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "maxResponseLength": {
                        "type": "integer"
                      },
                      "topicsToAvoid": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "maxSessionLength": {
                        "type": "integer"
                      },
                      "language": {
                        "type": "string"
                      },
                      "responsePace": {
                        "type": "string",
                        "description": "One of the response-pace presets, if set."
                      }
                    }
                  },
                  "websiteUrl": {
                    "type": "string"
                  },
                  "enableWebSearch": {
                    "type": "boolean"
                  },
                  "creativityLevel": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                  },
                  "folderId": {
                    "type": "string"
                  },
                  "telephony": {
                    "type": "object",
                    "properties": {
                      "enabled": {
                        "type": "boolean"
                      },
                      "phoneNumberId": {
                        "type": "string"
                      },
                      "handoff": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean"
                          },
                          "targetNumber": {
                            "type": "string",
                            "description": "The number the call is transferred to when the agent hands off to a person. Must be in E.164 format: a plus sign, then 2 to 15 digits, the first of which cannot be zero (for example +15551234567). Conditionally required: required when `handoff.enabled` is true, otherwise optional and an empty string is accepted. A malformed number returns 400 even when `handoff.enabled` is false."
                          },
                          "summaryPrompt": {
                            "type": "string"
                          }
                        }
                      },
                      "settings": {
                        "type": "object",
                        "properties": {
                          "recordCalls": {
                            "type": "boolean"
                          }
                        }
                      }
                    },
                    "description": "Telephony settings for the agent: whether phone calls are enabled, which of your phone numbers the agent uses, call recording, and handoff to a person. Accepted on create and, unlike most other server-managed fields, NOT stripped on update. The keys listed here are validated, so a malformed value returns 400: `enabled` and `settings.recordCalls` must be booleans, `phoneNumberId` must be a string, and `handoff.targetNumber` must be an E.164 number, required whenever `handoff.enabled` is true. Unknown keys inside the object are still accepted and stored as sent. Setting `phoneNumberId` is not the same as assigning that number to the agent: the assignment lives on the phone number's own `agentId` field and is written by the phone number endpoints, which this reference does not yet cover."
                  },
                  "isDeleted": {
                    "type": "boolean",
                    "description": "DELETE soft-deletes: this flips to true and the agent stops appearing in list/get, but the document is not removed."
                  },
                  "deletedAt": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "updatedAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              },
              "examples": {
                "update-name": {
                  "value": {
                    "name": "Renamed Support Agent"
                  }
                },
                "attach-avatar": {
                  "value": {
                    "avatar": {
                      "avatarId": "r55e6793f10f"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "agent": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use agentId to identify it."
                            },
                            "agentId": {
                              "type": "string",
                              "description": "Server-generated UUID. Immutable \u2014 sent in the body on create or update is silently dropped."
                            },
                            "companyId": {
                              "type": "string",
                              "description": "Stamped from the caller's authenticated company. Sending your own value on create or update is silently dropped; you cannot re-parent an agent."
                            },
                            "userId": {
                              "type": "string",
                              "description": "Id of the user who created the agent."
                            },
                            "name": {
                              "type": "string",
                              "description": "Required on create. Trimmed, non-empty."
                            },
                            "personality": {
                              "type": "string",
                              "description": "Required on create. Free text describing the agent's tone. Can be cleared to an empty string on update."
                            },
                            "instructions": {
                              "type": "string",
                              "description": "Required on create. The agent's system instructions. Can be cleared to an empty string on update."
                            },
                            "voice": {
                              "type": "object",
                              "description": "Required on create.",
                              "properties": {
                                "provider": {
                                  "type": "string",
                                  "description": "TTS provider, e.g. elevenlabs or openai."
                                },
                                "voiceId": {
                                  "type": "string"
                                },
                                "model": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "provider",
                                "voiceId"
                              ]
                            },
                            "stt": {
                              "type": "object",
                              "description": "Speech-to-text provider config. Shape is not validated beyond being an object."
                            },
                            "llm": {
                              "type": "object",
                              "properties": {
                                "provider": {
                                  "type": "string",
                                  "description": "Must be one of the voice-agent LLM providers if sent."
                                },
                                "model": {
                                  "type": "string",
                                  "description": "Must be one of the voice-agent model ids if sent."
                                }
                              }
                            },
                            "liveVoice": {
                              "type": "string",
                              "nullable": true,
                              "description": "The voice id used when llm.model is a Live (speech-to-speech) model. Rejected with a 400 listing the valid ids if it is not one of the voices the resolved Live model offers. Cleared by sending an empty string or null."
                            },
                            "avatar": {
                              "type": "object",
                              "description": "Set avatar.avatarId to attach an avatar; the server looks it up in your avatar catalog and derives avatarUrl, provider, and any provider-specific ids (e.g. Tavus faceId/palId) from that catalog row. Any of those fields sent in the request body are ignored \u2014 they cannot be set directly. An avatarId with no matching catalog row is rejected with 400, not saved.",
                              "properties": {
                                "avatarId": {
                                  "type": "string",
                                  "description": "Required to set an avatar. Must match a row in your company's avatar catalog (your own uploads or the shared system catalog)."
                                },
                                "avatarUrl": {
                                  "type": "string",
                                  "description": "Read-only in practice: always overwritten from the matched catalog row."
                                },
                                "provider": {
                                  "type": "string",
                                  "description": "Read-only in practice: always overwritten from the matched catalog row."
                                },
                                "tavusFaceId": {
                                  "type": "string",
                                  "description": "Read-only: derived server-side from the catalog row's tavus.faceId. Cannot be set by the client."
                                },
                                "tavusPalId": {
                                  "type": "string",
                                  "description": "Read-only: derived server-side from the catalog row's tavus.palId. Cannot be set by the client."
                                }
                              }
                            },
                            "conversationMode": {
                              "type": "string",
                              "enum": [
                                "voice",
                                "avatar"
                              ]
                            },
                            "status": {
                              "type": "string",
                              "description": "One of the agent status values."
                            },
                            "chatSettings": {
                              "type": "object",
                              "properties": {
                                "welcomeMessage": {
                                  "type": "string"
                                },
                                "conversationStarters": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "maxResponseLength": {
                                  "type": "integer"
                                },
                                "topicsToAvoid": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "maxSessionLength": {
                                  "type": "integer"
                                },
                                "language": {
                                  "type": "string"
                                },
                                "responsePace": {
                                  "type": "string",
                                  "description": "One of the response-pace presets, if set."
                                }
                              }
                            },
                            "websiteUrl": {
                              "type": "string"
                            },
                            "enableWebSearch": {
                              "type": "boolean"
                            },
                            "creativityLevel": {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 1
                            },
                            "folderId": {
                              "type": "string"
                            },
                            "telephony": {
                              "type": "object",
                              "properties": {
                                "enabled": {
                                  "type": "boolean"
                                },
                                "phoneNumberId": {
                                  "type": "string"
                                },
                                "handoff": {
                                  "type": "object",
                                  "properties": {
                                    "enabled": {
                                      "type": "boolean"
                                    },
                                    "targetNumber": {
                                      "type": "string"
                                    },
                                    "summaryPrompt": {
                                      "type": "string"
                                    }
                                  }
                                },
                                "settings": {
                                  "type": "object",
                                  "properties": {
                                    "recordCalls": {
                                      "type": "boolean"
                                    }
                                  }
                                }
                              }
                            },
                            "isDeleted": {
                              "type": "boolean",
                              "description": "DELETE soft-deletes: this flips to true and the agent stops appearing in list/get, but the document is not removed."
                            },
                            "deletedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "agent": {
                    "value": {
                      "status": "success",
                      "data": {
                        "agent": {
                          "agentId": "6a1b2c3d4e5f60718293a4b5",
                          "companyId": "6650a1b2c3d4e5f60000000a",
                          "userId": "6650a1b2c3d4e5f60000001a",
                          "name": "Support Agent",
                          "personality": "Friendly and concise",
                          "instructions": "Help callers troubleshoot billing questions.",
                          "voice": {
                            "provider": "elevenlabs",
                            "voiceId": "21m00Tcm4TlvDq8ikWAM"
                          },
                          "llm": {
                            "provider": "openai",
                            "model": "gpt-5.4"
                          },
                          "conversationMode": "voice",
                          "status": "active",
                          "chatSettings": {
                            "language": "en",
                            "maxResponseLength": 500,
                            "maxSessionLength": 1800,
                            "conversationStarters": [],
                            "topicsToAvoid": []
                          },
                          "creativityLevel": 0.7,
                          "isDeleted": false,
                          "createdAt": "2026-09-01T12:00:00.000Z",
                          "updatedAt": "2026-09-23T19:33:24.232Z"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed, or avatar.avatarId does not match a catalog row visible to your company",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Agents"
      },
      "delete": {
        "tags": [
          "Voice Agents"
        ],
        "summary": "Delete Voice Agent",
        "operationId": "voice-agents-delete",
        "description": "### Delete Agent\n\nRequires the OWNER or ADMIN role. Soft-deletes: the agent is flagged `isDeleted` and stops appearing in list/get, but the record and its conversation history are retained.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "deleted": {
                    "value": {
                      "status": "success",
                      "message": "Agent deleted successfully"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Agents"
      }
    },
    "/voice/avatars": {
      "get": {
        "tags": [
          "Voice Agents"
        ],
        "summary": "List Voice Avatars",
        "operationId": "voice-avatars-list",
        "description": "### List Avatars\n\nReturns the shared system avatar catalog plus any avatars your company has uploaded, newest first. Another company's private uploads are never included.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "avatars": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "avatarId": {
                                "type": "string",
                                "description": "Server-generated UUID on create. Immutable."
                              },
                              "companyId": {
                                "type": "string",
                                "nullable": true,
                                "description": "Absent on a shared system-catalog avatar, which every company can read but only Speak can write. Present on a company's own uploaded avatar."
                              },
                              "name": {
                                "type": "string",
                                "description": "Required on create."
                              },
                              "provider": {
                                "type": "string",
                                "enum": [
                                  "bey",
                                  "tavus",
                                  "heygen",
                                  "synthesia",
                                  "d-id"
                                ],
                                "description": "Required on create."
                              },
                              "imageUrl": {
                                "type": "string"
                              },
                              "videoUrl": {
                                "type": "string"
                              },
                              "localImagePath": {
                                "type": "string",
                                "description": "Local file path used by internal upload flows."
                              },
                              "localVideoPath": {
                                "type": "string",
                                "description": "Local file path used by internal upload flows."
                              },
                              "tavus": {
                                "type": "object",
                                "description": "Set when provider is tavus.",
                                "properties": {
                                  "faceId": {
                                    "type": "string",
                                    "description": "Required within this object if tavus is sent at all."
                                  },
                                  "palId": {
                                    "type": "string"
                                  },
                                  "status": {
                                    "type": "string",
                                    "enum": [
                                      "started",
                                      "completed",
                                      "error"
                                    ]
                                  },
                                  "isRecommended": {
                                    "type": "boolean"
                                  },
                                  "trainingProgress": {
                                    "type": "string"
                                  },
                                  "faceType": {
                                    "type": "string",
                                    "enum": [
                                      "user",
                                      "system"
                                    ]
                                  },
                                  "modelType": {
                                    "type": "string"
                                  }
                                }
                              },
                              "bey": {
                                "type": "object",
                                "description": "Set when provider is bey.",
                                "properties": {
                                  "avatarId": {
                                    "type": "string",
                                    "description": "Required within this object if bey is sent at all."
                                  },
                                  "gender": {
                                    "type": "string"
                                  },
                                  "ethnicity": {
                                    "type": "string"
                                  },
                                  "voiceId": {
                                    "type": "string"
                                  },
                                  "ageRange": {
                                    "type": "string"
                                  },
                                  "style": {
                                    "type": "string"
                                  },
                                  "isDefault": {
                                    "type": "boolean"
                                  },
                                  "languageCode": {
                                    "type": "string"
                                  }
                                }
                              },
                              "custom": {
                                "type": "object",
                                "description": "Set when provider is a custom/self-hosted avatar.",
                                "properties": {
                                  "uploadedBy": {
                                    "type": "string"
                                  },
                                  "originalFileName": {
                                    "type": "string"
                                  },
                                  "fileSize": {
                                    "type": "number"
                                  },
                                  "mimeType": {
                                    "type": "string"
                                  }
                                }
                              },
                              "category": {
                                "type": "string",
                                "enum": [
                                  "professional",
                                  "casual",
                                  "stock",
                                  "custom",
                                  "premium"
                                ],
                                "description": "Defaults to professional if not sent."
                              },
                              "tags": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "isPremium": {
                                "type": "boolean",
                                "description": "Defaults to false."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "active",
                                  "inactive",
                                  "processing",
                                  "error"
                                ],
                                "description": "Defaults to active."
                              },
                              "isPublic": {
                                "type": "boolean",
                                "description": "Defaults to true."
                              },
                              "description": {
                                "type": "string"
                              },
                              "metadata": {
                                "type": "object",
                                "description": "Arbitrary metadata object. Shape is not validated."
                              },
                              "createdBy": {
                                "type": "string",
                                "description": "Id of the user who created this avatar."
                              },
                              "lastSyncedAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "Set by the system-catalog sync job for shared avatars."
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "avatars": {
                    "value": {
                      "status": "success",
                      "data": {
                        "avatars": [
                          {
                            "avatarId": "r55e6793f10f",
                            "name": "Rae",
                            "provider": "tavus",
                            "imageUrl": "https://cdn.replica.tavus.io/still.png",
                            "tavus": {
                              "faceId": "r55e6793f10f",
                              "palId": "p135a0c8e542"
                            },
                            "category": "professional",
                            "isPremium": false,
                            "status": "active",
                            "isPublic": true,
                            "createdAt": "2026-08-01T12:00:00.000Z",
                            "updatedAt": "2026-08-01T12:00:00.000Z"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Avatars"
      }
    },
    "/voice/testing/{agentId}/suite": {
      "get": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "Get Test Suite",
        "operationId": "voice-testing-get-suite",
        "description": "### Get Test Suite\n\nReturns the agent's test suite, or `null` in `data.suite` if none has been created yet \u2014 this is not a 404.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "suite": {
                          "type": "object",
                          "nullable": true,
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use suiteId to identify it."
                            },
                            "suiteId": {
                              "type": "string"
                            },
                            "agentId": {
                              "type": "string"
                            },
                            "companyId": {
                              "type": "string"
                            },
                            "scenarios": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "scenarioId": {
                                    "type": "string"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  },
                                  "userMessages": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    },
                                    "minItems": 1,
                                    "description": "Required, at least one message. The scripted turns sent to the agent."
                                  },
                                  "criteria": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "criterionId": {
                                          "type": "string"
                                        },
                                        "name": {
                                          "type": "string"
                                        },
                                        "evaluationPrompt": {
                                          "type": "string",
                                          "description": "What the LLM judge is asked to evaluate."
                                        },
                                        "weight": {
                                          "type": "number",
                                          "minimum": 1,
                                          "maximum": 10
                                        },
                                        "isCritical": {
                                          "type": "boolean"
                                        },
                                        "type": {
                                          "type": "string",
                                          "enum": [
                                            "llm_judged",
                                            "response_length",
                                            "regex_match",
                                            "tool_called"
                                          ],
                                          "description": "Defaults to llm_judged when omitted. The other three route through a deterministic code check before the LLM judge runs."
                                        },
                                        "maxWords": {
                                          "type": "integer",
                                          "description": "For type=response_length: fails if any agent response exceeds this word count."
                                        },
                                        "regexPattern": {
                                          "type": "string",
                                          "description": "For type=regex_match: JS regex source, no slashes."
                                        },
                                        "mustMatch": {
                                          "type": "boolean",
                                          "description": "For type=regex_match: when true (default), at least one response must match; when false, none may."
                                        },
                                        "expectedToolName": {
                                          "type": "string",
                                          "description": "For type=tool_called: the tool name to look for in the transcript's tool calls."
                                        }
                                      }
                                    },
                                    "description": "Defaults to an empty array."
                                  },
                                  "category": {
                                    "type": "string",
                                    "enum": [
                                      "greeting",
                                      "kb_retrieval",
                                      "off_topic",
                                      "edge_case",
                                      "custom"
                                    ]
                                  },
                                  "isEnabled": {
                                    "type": "boolean"
                                  }
                                }
                              }
                            },
                            "maxCostPerRun": {
                              "type": "number",
                              "minimum": 0
                            },
                            "autoRunOnKbUpdate": {
                              "type": "boolean"
                            },
                            "autoRunOnInstructionSave": {
                              "type": "boolean"
                            },
                            "scheduledCron": {
                              "type": "string",
                              "nullable": true
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Suite"
      },
      "put": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "Create Or Update Test Suite",
        "operationId": "voice-testing-update-suite",
        "description": "### Update Test Suite\n\nRequires the OWNER or ADMIN role. Upserts \u2014 creates the suite on first call, updates it on later calls. Send the full `scenarios` array you want to keep; it replaces the stored array rather than merging.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "scenarios": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "scenarioId": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        },
                        "userMessages": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "minItems": 1,
                          "description": "Required, at least one message. The scripted turns sent to the agent."
                        },
                        "criteria": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "criterionId": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "evaluationPrompt": {
                                "type": "string",
                                "description": "What the LLM judge is asked to evaluate."
                              },
                              "weight": {
                                "type": "number",
                                "minimum": 1,
                                "maximum": 10
                              },
                              "isCritical": {
                                "type": "boolean"
                              },
                              "type": {
                                "type": "string",
                                "enum": [
                                  "llm_judged",
                                  "response_length",
                                  "regex_match",
                                  "tool_called"
                                ],
                                "description": "Defaults to llm_judged when omitted. The other three route through a deterministic code check before the LLM judge runs."
                              },
                              "maxWords": {
                                "type": "integer",
                                "description": "For type=response_length: fails if any agent response exceeds this word count."
                              },
                              "regexPattern": {
                                "type": "string",
                                "description": "For type=regex_match: JS regex source, no slashes."
                              },
                              "mustMatch": {
                                "type": "boolean",
                                "description": "For type=regex_match: when true (default), at least one response must match; when false, none may."
                              },
                              "expectedToolName": {
                                "type": "string",
                                "description": "For type=tool_called: the tool name to look for in the transcript's tool calls."
                              }
                            }
                          },
                          "description": "Defaults to an empty array."
                        },
                        "category": {
                          "type": "string",
                          "enum": [
                            "greeting",
                            "kb_retrieval",
                            "off_topic",
                            "edge_case",
                            "custom"
                          ]
                        },
                        "isEnabled": {
                          "type": "boolean"
                        }
                      }
                    }
                  },
                  "maxCostPerRun": {
                    "type": "number",
                    "minimum": 0
                  },
                  "autoRunOnKbUpdate": {
                    "type": "boolean"
                  },
                  "autoRunOnInstructionSave": {
                    "type": "boolean"
                  },
                  "scheduledCron": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "examples": {
                "one-scenario": {
                  "value": {
                    "scenarios": [
                      {
                        "name": "Greeting",
                        "userMessages": [
                          "Hi there"
                        ],
                        "category": "greeting",
                        "criteria": [],
                        "isEnabled": true
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "suite": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use suiteId to identify it."
                            },
                            "suiteId": {
                              "type": "string"
                            },
                            "agentId": {
                              "type": "string"
                            },
                            "companyId": {
                              "type": "string"
                            },
                            "scenarios": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "scenarioId": {
                                    "type": "string"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  },
                                  "userMessages": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    },
                                    "minItems": 1,
                                    "description": "Required, at least one message. The scripted turns sent to the agent."
                                  },
                                  "criteria": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "criterionId": {
                                          "type": "string"
                                        },
                                        "name": {
                                          "type": "string"
                                        },
                                        "evaluationPrompt": {
                                          "type": "string",
                                          "description": "What the LLM judge is asked to evaluate."
                                        },
                                        "weight": {
                                          "type": "number",
                                          "minimum": 1,
                                          "maximum": 10
                                        },
                                        "isCritical": {
                                          "type": "boolean"
                                        },
                                        "type": {
                                          "type": "string",
                                          "enum": [
                                            "llm_judged",
                                            "response_length",
                                            "regex_match",
                                            "tool_called"
                                          ],
                                          "description": "Defaults to llm_judged when omitted. The other three route through a deterministic code check before the LLM judge runs."
                                        },
                                        "maxWords": {
                                          "type": "integer",
                                          "description": "For type=response_length: fails if any agent response exceeds this word count."
                                        },
                                        "regexPattern": {
                                          "type": "string",
                                          "description": "For type=regex_match: JS regex source, no slashes."
                                        },
                                        "mustMatch": {
                                          "type": "boolean",
                                          "description": "For type=regex_match: when true (default), at least one response must match; when false, none may."
                                        },
                                        "expectedToolName": {
                                          "type": "string",
                                          "description": "For type=tool_called: the tool name to look for in the transcript's tool calls."
                                        }
                                      }
                                    },
                                    "description": "Defaults to an empty array."
                                  },
                                  "category": {
                                    "type": "string",
                                    "enum": [
                                      "greeting",
                                      "kb_retrieval",
                                      "off_topic",
                                      "edge_case",
                                      "custom"
                                    ]
                                  },
                                  "isEnabled": {
                                    "type": "boolean"
                                  }
                                }
                              }
                            },
                            "maxCostPerRun": {
                              "type": "number",
                              "minimum": 0
                            },
                            "autoRunOnKbUpdate": {
                              "type": "boolean"
                            },
                            "autoRunOnInstructionSave": {
                              "type": "boolean"
                            },
                            "scheduledCron": {
                              "type": "string",
                              "nullable": true
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Suite"
      }
    },
    "/voice/testing/{agentId}/suite/generate": {
      "post": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "Generate Default Test Suite",
        "operationId": "voice-testing-generate-suite",
        "description": "### Auto-Generate Test Suite\n\nRequires the OWNER or ADMIN role. Uses the agent's own instructions and knowledge base to generate a default set of scenarios via an LLM call, then overwrites the suite's `scenarios` array with the result (upserting the suite if none exists). `maxCostPerRun` and the auto-run flags are left untouched.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "suite": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use suiteId to identify it."
                            },
                            "suiteId": {
                              "type": "string"
                            },
                            "agentId": {
                              "type": "string"
                            },
                            "companyId": {
                              "type": "string"
                            },
                            "scenarios": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "scenarioId": {
                                    "type": "string"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  },
                                  "userMessages": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    },
                                    "minItems": 1,
                                    "description": "Required, at least one message. The scripted turns sent to the agent."
                                  },
                                  "criteria": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "criterionId": {
                                          "type": "string"
                                        },
                                        "name": {
                                          "type": "string"
                                        },
                                        "evaluationPrompt": {
                                          "type": "string",
                                          "description": "What the LLM judge is asked to evaluate."
                                        },
                                        "weight": {
                                          "type": "number",
                                          "minimum": 1,
                                          "maximum": 10
                                        },
                                        "isCritical": {
                                          "type": "boolean"
                                        },
                                        "type": {
                                          "type": "string",
                                          "enum": [
                                            "llm_judged",
                                            "response_length",
                                            "regex_match",
                                            "tool_called"
                                          ],
                                          "description": "Defaults to llm_judged when omitted. The other three route through a deterministic code check before the LLM judge runs."
                                        },
                                        "maxWords": {
                                          "type": "integer",
                                          "description": "For type=response_length: fails if any agent response exceeds this word count."
                                        },
                                        "regexPattern": {
                                          "type": "string",
                                          "description": "For type=regex_match: JS regex source, no slashes."
                                        },
                                        "mustMatch": {
                                          "type": "boolean",
                                          "description": "For type=regex_match: when true (default), at least one response must match; when false, none may."
                                        },
                                        "expectedToolName": {
                                          "type": "string",
                                          "description": "For type=tool_called: the tool name to look for in the transcript's tool calls."
                                        }
                                      }
                                    },
                                    "description": "Defaults to an empty array."
                                  },
                                  "category": {
                                    "type": "string",
                                    "enum": [
                                      "greeting",
                                      "kb_retrieval",
                                      "off_topic",
                                      "edge_case",
                                      "custom"
                                    ]
                                  },
                                  "isEnabled": {
                                    "type": "boolean"
                                  }
                                }
                              }
                            },
                            "maxCostPerRun": {
                              "type": "number",
                              "minimum": 0
                            },
                            "autoRunOnKbUpdate": {
                              "type": "boolean"
                            },
                            "autoRunOnInstructionSave": {
                              "type": "boolean"
                            },
                            "scheduledCron": {
                              "type": "string",
                              "nullable": true
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Suite generation is unavailable \u2014 the underlying LLM provider is not configured",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Suite"
      }
    },
    "/voice/testing/{agentId}/run": {
      "post": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "Start Test Run",
        "operationId": "voice-testing-start-run",
        "description": "### Start Test Run\n\nRequires the OWNER or ADMIN role. **The live execution engine is not wired up yet.** These endpoints create and transition the run record \u2014 `queued`, `running`, `paused`, `completed`, `cancelled`, `budget_exceeded` \u2014 but nothing here drives a simulated conversation against the agent. A run created with `POST /run` stays `queued` until something else (not yet built) advances it; `scenarioResults` stays empty and `overallScore` stays 0.\n\nRejects with 409 if the agent has no test suite, the suite has no enabled scenarios, or an active run (`queued`/`running`/`paused`) already exists for this agent \u2014 only one run can be active per agent at a time.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "run": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use runId to identify it."
                            },
                            "runId": {
                              "type": "string"
                            },
                            "suiteId": {
                              "type": "string"
                            },
                            "agentId": {
                              "type": "string"
                            },
                            "companyId": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "queued",
                                "running",
                                "paused",
                                "completed",
                                "failed",
                                "cancelled",
                                "budget_exceeded"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "kb_update",
                                "instruction_save",
                                "scheduled"
                              ]
                            },
                            "currentScenarioIndex": {
                              "type": "integer"
                            },
                            "totalScenarios": {
                              "type": "integer"
                            },
                            "scenarioResults": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              },
                              "description": "Populated as the execution engine appends results. Empty on a run that never left queued."
                            },
                            "overallScore": {
                              "type": "number"
                            },
                            "passedCount": {
                              "type": "integer"
                            },
                            "failedCount": {
                              "type": "integer"
                            },
                            "totalCount": {
                              "type": "integer"
                            },
                            "totalCost": {
                              "type": "number"
                            },
                            "isRegression": {
                              "type": "boolean"
                            },
                            "baselineScore": {
                              "type": "number",
                              "nullable": true
                            },
                            "scoreDelta": {
                              "type": "number",
                              "nullable": true
                            },
                            "recommendations": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "completedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "failureReason": {
                              "type": "string",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent, run, or recommendation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent, run, or recommendation not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflict \u2014 no test suite configured, no enabled scenarios, an active run already exists, or the transition is not valid from the run's current status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Runs"
      }
    },
    "/voice/testing/{agentId}/run/active": {
      "get": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "Get Active Test Run",
        "operationId": "voice-testing-get-active-run",
        "description": "### Get Active Run\n\nReturns the agent's currently active run (`queued`, `running`, or `paused`), or `null` in `data.run` if none is active. Not a 404 when there is no active run.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "run": {
                          "type": "object",
                          "nullable": true,
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use runId to identify it."
                            },
                            "runId": {
                              "type": "string"
                            },
                            "suiteId": {
                              "type": "string"
                            },
                            "agentId": {
                              "type": "string"
                            },
                            "companyId": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "queued",
                                "running",
                                "paused",
                                "completed",
                                "failed",
                                "cancelled",
                                "budget_exceeded"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "kb_update",
                                "instruction_save",
                                "scheduled"
                              ]
                            },
                            "currentScenarioIndex": {
                              "type": "integer"
                            },
                            "totalScenarios": {
                              "type": "integer"
                            },
                            "scenarioResults": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              },
                              "description": "Populated as the execution engine appends results. Empty on a run that never left queued."
                            },
                            "overallScore": {
                              "type": "number"
                            },
                            "passedCount": {
                              "type": "integer"
                            },
                            "failedCount": {
                              "type": "integer"
                            },
                            "totalCount": {
                              "type": "integer"
                            },
                            "totalCost": {
                              "type": "number"
                            },
                            "isRegression": {
                              "type": "boolean"
                            },
                            "baselineScore": {
                              "type": "number",
                              "nullable": true
                            },
                            "scoreDelta": {
                              "type": "number",
                              "nullable": true
                            },
                            "recommendations": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "completedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "failureReason": {
                              "type": "string",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Runs"
      }
    },
    "/voice/testing/{agentId}/run/{runId}/pause": {
      "post": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "Pause Test Run",
        "operationId": "voice-testing-pause-run",
        "description": "### Pause Run\n\nRequires the OWNER or ADMIN role. Valid only from `queued` or `running`. **The live execution engine is not wired up yet.** These endpoints create and transition the run record \u2014 `queued`, `running`, `paused`, `completed`, `cancelled`, `budget_exceeded` \u2014 but nothing here drives a simulated conversation against the agent. A run created with `POST /run` stays `queued` until something else (not yet built) advances it; `scenarioResults` stays empty and `overallScore` stays 0.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "run": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use runId to identify it."
                            },
                            "runId": {
                              "type": "string"
                            },
                            "suiteId": {
                              "type": "string"
                            },
                            "agentId": {
                              "type": "string"
                            },
                            "companyId": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "queued",
                                "running",
                                "paused",
                                "completed",
                                "failed",
                                "cancelled",
                                "budget_exceeded"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "kb_update",
                                "instruction_save",
                                "scheduled"
                              ]
                            },
                            "currentScenarioIndex": {
                              "type": "integer"
                            },
                            "totalScenarios": {
                              "type": "integer"
                            },
                            "scenarioResults": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              },
                              "description": "Populated as the execution engine appends results. Empty on a run that never left queued."
                            },
                            "overallScore": {
                              "type": "number"
                            },
                            "passedCount": {
                              "type": "integer"
                            },
                            "failedCount": {
                              "type": "integer"
                            },
                            "totalCount": {
                              "type": "integer"
                            },
                            "totalCost": {
                              "type": "number"
                            },
                            "isRegression": {
                              "type": "boolean"
                            },
                            "baselineScore": {
                              "type": "number",
                              "nullable": true
                            },
                            "scoreDelta": {
                              "type": "number",
                              "nullable": true
                            },
                            "recommendations": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "completedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "failureReason": {
                              "type": "string",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent, run, or recommendation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent, run, or recommendation not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflict \u2014 no test suite configured, no enabled scenarios, an active run already exists, or the transition is not valid from the run's current status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Runs"
      }
    },
    "/voice/testing/{agentId}/run/{runId}/resume": {
      "post": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "Resume Test Run",
        "operationId": "voice-testing-resume-run",
        "description": "### Resume Run\n\nRequires the OWNER or ADMIN role. Valid only from `paused`, transitioning back to `running`.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "run": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use runId to identify it."
                            },
                            "runId": {
                              "type": "string"
                            },
                            "suiteId": {
                              "type": "string"
                            },
                            "agentId": {
                              "type": "string"
                            },
                            "companyId": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "queued",
                                "running",
                                "paused",
                                "completed",
                                "failed",
                                "cancelled",
                                "budget_exceeded"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "kb_update",
                                "instruction_save",
                                "scheduled"
                              ]
                            },
                            "currentScenarioIndex": {
                              "type": "integer"
                            },
                            "totalScenarios": {
                              "type": "integer"
                            },
                            "scenarioResults": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              },
                              "description": "Populated as the execution engine appends results. Empty on a run that never left queued."
                            },
                            "overallScore": {
                              "type": "number"
                            },
                            "passedCount": {
                              "type": "integer"
                            },
                            "failedCount": {
                              "type": "integer"
                            },
                            "totalCount": {
                              "type": "integer"
                            },
                            "totalCost": {
                              "type": "number"
                            },
                            "isRegression": {
                              "type": "boolean"
                            },
                            "baselineScore": {
                              "type": "number",
                              "nullable": true
                            },
                            "scoreDelta": {
                              "type": "number",
                              "nullable": true
                            },
                            "recommendations": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "completedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "failureReason": {
                              "type": "string",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent, run, or recommendation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent, run, or recommendation not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflict \u2014 no test suite configured, no enabled scenarios, an active run already exists, or the transition is not valid from the run's current status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Runs"
      }
    },
    "/voice/testing/{agentId}/run/{runId}/cancel": {
      "post": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "Cancel Test Run",
        "operationId": "voice-testing-cancel-run",
        "description": "### Cancel Run\n\nRequires the OWNER or ADMIN role. Valid from `queued`, `running`, or `paused`. Terminal \u2014 a cancelled run can never be resumed.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "run": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use runId to identify it."
                            },
                            "runId": {
                              "type": "string"
                            },
                            "suiteId": {
                              "type": "string"
                            },
                            "agentId": {
                              "type": "string"
                            },
                            "companyId": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "queued",
                                "running",
                                "paused",
                                "completed",
                                "failed",
                                "cancelled",
                                "budget_exceeded"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "kb_update",
                                "instruction_save",
                                "scheduled"
                              ]
                            },
                            "currentScenarioIndex": {
                              "type": "integer"
                            },
                            "totalScenarios": {
                              "type": "integer"
                            },
                            "scenarioResults": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              },
                              "description": "Populated as the execution engine appends results. Empty on a run that never left queued."
                            },
                            "overallScore": {
                              "type": "number"
                            },
                            "passedCount": {
                              "type": "integer"
                            },
                            "failedCount": {
                              "type": "integer"
                            },
                            "totalCount": {
                              "type": "integer"
                            },
                            "totalCost": {
                              "type": "number"
                            },
                            "isRegression": {
                              "type": "boolean"
                            },
                            "baselineScore": {
                              "type": "number",
                              "nullable": true
                            },
                            "scoreDelta": {
                              "type": "number",
                              "nullable": true
                            },
                            "recommendations": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "completedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "failureReason": {
                              "type": "string",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent, run, or recommendation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent, run, or recommendation not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflict \u2014 no test suite configured, no enabled scenarios, an active run already exists, or the transition is not valid from the run's current status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Runs"
      }
    },
    "/voice/testing/{agentId}/runs": {
      "get": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "List Test Runs",
        "operationId": "voice-testing-list-runs",
        "description": "### List Runs\n\nMost recent first, capped at 100 regardless of the `limit` query parameter.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            },
            "description": "Defaults to 20. Values above 100 are capped at 100; non-numeric values fall back to the default."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "runs": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "MongoDB document id, included because every document has one; use runId to identify it."
                              },
                              "runId": {
                                "type": "string"
                              },
                              "suiteId": {
                                "type": "string"
                              },
                              "agentId": {
                                "type": "string"
                              },
                              "companyId": {
                                "type": "string"
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "queued",
                                  "running",
                                  "paused",
                                  "completed",
                                  "failed",
                                  "cancelled",
                                  "budget_exceeded"
                                ]
                              },
                              "trigger": {
                                "type": "string",
                                "enum": [
                                  "manual",
                                  "kb_update",
                                  "instruction_save",
                                  "scheduled"
                                ]
                              },
                              "currentScenarioIndex": {
                                "type": "integer"
                              },
                              "totalScenarios": {
                                "type": "integer"
                              },
                              "scenarioResults": {
                                "type": "array",
                                "items": {
                                  "type": "object"
                                },
                                "description": "Populated as the execution engine appends results. Empty on a run that never left queued."
                              },
                              "overallScore": {
                                "type": "number"
                              },
                              "passedCount": {
                                "type": "integer"
                              },
                              "failedCount": {
                                "type": "integer"
                              },
                              "totalCount": {
                                "type": "integer"
                              },
                              "totalCost": {
                                "type": "number"
                              },
                              "isRegression": {
                                "type": "boolean"
                              },
                              "baselineScore": {
                                "type": "number",
                                "nullable": true
                              },
                              "scoreDelta": {
                                "type": "number",
                                "nullable": true
                              },
                              "recommendations": {
                                "type": "array",
                                "items": {
                                  "type": "object"
                                }
                              },
                              "startedAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "completedAt": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "failureReason": {
                                "type": "string",
                                "nullable": true
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Runs"
      }
    },
    "/voice/testing/{agentId}/runs/{runId}": {
      "get": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "Get Test Run Detail",
        "operationId": "voice-testing-get-run",
        "description": "### Get Run Detail\n\nFull run record including `scenarioResults` and `recommendations`, scoped to your company. The `agentId` path segment is not used to filter this lookup \u2014 only `runId` and your company.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "run": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use runId to identify it."
                            },
                            "runId": {
                              "type": "string"
                            },
                            "suiteId": {
                              "type": "string"
                            },
                            "agentId": {
                              "type": "string"
                            },
                            "companyId": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "queued",
                                "running",
                                "paused",
                                "completed",
                                "failed",
                                "cancelled",
                                "budget_exceeded"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "kb_update",
                                "instruction_save",
                                "scheduled"
                              ]
                            },
                            "currentScenarioIndex": {
                              "type": "integer"
                            },
                            "totalScenarios": {
                              "type": "integer"
                            },
                            "scenarioResults": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              },
                              "description": "Populated as the execution engine appends results. Empty on a run that never left queued."
                            },
                            "overallScore": {
                              "type": "number"
                            },
                            "passedCount": {
                              "type": "integer"
                            },
                            "failedCount": {
                              "type": "integer"
                            },
                            "totalCount": {
                              "type": "integer"
                            },
                            "totalCost": {
                              "type": "number"
                            },
                            "isRegression": {
                              "type": "boolean"
                            },
                            "baselineScore": {
                              "type": "number",
                              "nullable": true
                            },
                            "scoreDelta": {
                              "type": "number",
                              "nullable": true
                            },
                            "recommendations": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "completedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "failureReason": {
                              "type": "string",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Run not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Run not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Runs"
      }
    },
    "/voice/testing/{agentId}/runs/{runId}/recommendations/{recId}/apply": {
      "post": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "Apply Test Run Recommendation",
        "operationId": "voice-testing-apply-recommendation",
        "description": "### Apply Recommendation\n\nRequires the OWNER or ADMIN role. Applies a recommendation's quick action to the agent:\n\n- `patch_instructions` / `instructions` \u2014 appends the recommendation's suggested fix to the agent's instructions.\n- `update_personality` / `personality` \u2014 appends it to the agent's personality.\n- `add_topic_to_avoid` / `topics_to_avoid` \u2014 adds it to `chatSettings.topicsToAvoid`.\n- `add_lexicon_term` / `lexicon` / `add_to_kb` / `kb` \u2014 **marked applied but makes no change to the agent.** These two categories are not wired up yet; the run record reflects the acknowledgement, the agent config does not.\n\nAny other action type returns 400. A recommendation with no `suggestedFix` also returns 400.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "recId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "applied": {
                          "type": "boolean"
                        },
                        "recommendation": {
                          "type": "object",
                          "description": "The recommendation as stored on the run, now with applied: true and appliedAt set."
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid transition, or recommendation has no suggested fix",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent, run, or recommendation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent, run, or recommendation not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Runs"
      }
    },
    "/voice/testing/{agentId}/baseline": {
      "get": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "Get Test Baseline",
        "operationId": "voice-testing-get-baseline",
        "description": "### Get Baseline\n\nThe agent's best-scoring completed run, used to detect regressions on later runs. `null` in `data.baseline` if no run has completed yet.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "baseline": {
                          "type": "object",
                          "nullable": true,
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use suiteId to identify it."
                            },
                            "agentId": {
                              "type": "string"
                            },
                            "suiteId": {
                              "type": "string"
                            },
                            "bestScore": {
                              "type": "number"
                            },
                            "bestRunId": {
                              "type": "string"
                            },
                            "scenarioBaselines": {
                              "type": "object",
                              "description": "Map of scenarioId to that scenario's best score."
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Results"
      }
    },
    "/voice/testing/{agentId}/score-history": {
      "get": {
        "tags": [
          "Voice Agent Testing"
        ],
        "summary": "Get Test Score History",
        "operationId": "voice-testing-get-score-history",
        "description": "### Get Score History\n\nCompleted-run score points for charting, most recent first, capped at 100 regardless of `limit`. Only `status: completed` runs are included \u2014 a queued, running, paused, failed, or cancelled run never appears here.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "history": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "runId": {
                                "type": "string"
                              },
                              "score": {
                                "type": "number"
                              },
                              "timestamp": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "trigger": {
                                "type": "string",
                                "enum": [
                                  "manual",
                                  "kb_update",
                                  "instruction_save",
                                  "scheduled"
                                ]
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Results"
      }
    },
    "/voice/questions": {
      "get": {
        "tags": [
          "Voice Agent Questions"
        ],
        "summary": "List Questions",
        "operationId": "voice-questions-list",
        "description": "### List Questions\n\nLists the questions configured on one agent, in the order the agent asks them. Requires agentId -- returns 404 if that agent does not exist or does not belong to your company.\n\nThese are agent-level instances of a template (see Question Templates below); each carries its own required/attempts/no-response settings and, optionally, a mappedFieldId that writes the caller's answer onto a company Field after the call ends.",
        "parameters": [
          {
            "name": "agentId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Required. The agent whose questions to list."
          },
          {
            "name": "enabledOnly",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "When true, only returns questions with enabled=true."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "fields": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "MongoDB document id, included because every document has one; use fieldId to identify it."
                              },
                              "fieldId": {
                                "type": "string",
                                "description": "Server-generated UUID. Immutable -- sent in the body on create or update is silently dropped."
                              },
                              "companyId": {
                                "type": "string",
                                "description": "Stamped from the caller's authenticated company. Sent in the body is silently dropped."
                              },
                              "userId": {
                                "type": "string",
                                "description": "Id of the user who created this question. Sent in the body is silently dropped."
                              },
                              "agentId": {
                                "type": "string",
                                "description": "Required on create. Immutable after create -- sent on update is silently dropped."
                              },
                              "templateId": {
                                "type": "string",
                                "description": "Required on create. The question template this question is based on. Immutable after create -- sent on update is silently dropped."
                              },
                              "customConfig": {
                                "type": "object",
                                "description": "Agent-level override of the template's defaultConfig. Only the keys you send are overridden; the rest fall back to the template.",
                                "properties": {
                                  "displayLabel": {
                                    "type": "string"
                                  },
                                  "question": {
                                    "type": "string",
                                    "description": "The prompt text the agent speaks to ask this question. Renamed from promptText."
                                  },
                                  "confirmationText": {
                                    "type": "string"
                                  },
                                  "validationPrompt": {
                                    "type": "string"
                                  },
                                  "validation": {
                                    "type": "object",
                                    "properties": {
                                      "pattern": {
                                        "type": "string"
                                      },
                                      "minLength": {
                                        "type": "number"
                                      },
                                      "maxLength": {
                                        "type": "number"
                                      },
                                      "min": {
                                        "type": "number"
                                      },
                                      "max": {
                                        "type": "number"
                                      },
                                      "allowedValues": {
                                        "type": "array",
                                        "items": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  }
                                }
                              },
                              "required": {
                                "type": "boolean",
                                "description": "Defaults to false. Agent must collect this before ending the conversation."
                              },
                              "maxPromptAttempts": {
                                "type": "number",
                                "minimum": 1,
                                "maximum": 3,
                                "description": "Defaults to 2. Hard maximum of 3. Joi validates this as Joi.number().integer(), which this spec generator reports as \"number\"."
                              },
                              "noResponseBehavior": {
                                "type": "string",
                                "enum": [
                                  "move_to_next_question",
                                  "end_conversation"
                                ],
                                "description": "Defaults to move_to_next_question."
                              },
                              "triggerCondition": {
                                "type": "string"
                              },
                              "order": {
                                "type": "number",
                                "description": "Defaults to 0. Use PUT /voice/questions/reorder to reorder in bulk."
                              },
                              "enabled": {
                                "type": "boolean",
                                "description": "Defaults to true."
                              },
                              "mappedFieldId": {
                                "type": "string",
                                "nullable": true,
                                "description": "Id of a general company Field (see the Fields API) this question's collected answer is written onto after each call ends. Send null or an empty string to clear the mapping."
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "fields": {
                    "value": {
                      "status": "success",
                      "data": {
                        "fields": [
                          {
                            "fieldId": "q-8f2a1c4e",
                            "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                            "templateId": "tpl-email",
                            "required": true,
                            "maxPromptAttempts": 2,
                            "noResponseBehavior": "move_to_next_question",
                            "order": 0,
                            "enabled": true,
                            "mappedFieldId": "6650a1b2c3d4e5f678901234",
                            "createdAt": "2026-08-01T12:00:00.000Z",
                            "updatedAt": "2026-08-01T12:00:00.000Z"
                          }
                        ],
                        "total": 1
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Questions"
      },
      "post": {
        "tags": [
          "Voice Agent Questions"
        ],
        "summary": "Create Question",
        "operationId": "voice-questions-create",
        "description": "### Create Question\n\nRequires the OWNER or ADMIN role. Attaches a question template to an agent. agentId and templateId are both required; both must belong to your company (or, for templateId, be a public system template). Returns 404 if either is not found.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agentId": {
                    "type": "string",
                    "description": "Required."
                  },
                  "templateId": {
                    "type": "string",
                    "description": "Required. Must reference a template your company can see (its own, or a system template)."
                  },
                  "customConfig": {
                    "type": "object",
                    "description": "Agent-level override of the template's defaultConfig. Only the keys you send are overridden; the rest fall back to the template.",
                    "properties": {
                      "displayLabel": {
                        "type": "string"
                      },
                      "question": {
                        "type": "string",
                        "description": "The prompt text the agent speaks to ask this question. Renamed from promptText."
                      },
                      "confirmationText": {
                        "type": "string"
                      },
                      "validationPrompt": {
                        "type": "string"
                      },
                      "validation": {
                        "type": "object",
                        "properties": {
                          "pattern": {
                            "type": "string"
                          },
                          "minLength": {
                            "type": "number"
                          },
                          "maxLength": {
                            "type": "number"
                          },
                          "min": {
                            "type": "number"
                          },
                          "max": {
                            "type": "number"
                          },
                          "allowedValues": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": {
                    "type": "boolean"
                  },
                  "maxPromptAttempts": {
                    "type": "number",
                    "minimum": 1,
                    "maximum": 3
                  },
                  "noResponseBehavior": {
                    "type": "string",
                    "enum": [
                      "move_to_next_question",
                      "end_conversation"
                    ]
                  },
                  "triggerCondition": {
                    "type": "string"
                  },
                  "order": {
                    "type": "number"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "mappedFieldId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Id of an existing company Field to write this question's collected answer onto after each call."
                  }
                },
                "required": [
                  "agentId",
                  "templateId"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "field": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use fieldId to identify it."
                            },
                            "fieldId": {
                              "type": "string",
                              "description": "Server-generated UUID. Immutable -- sent in the body on create or update is silently dropped."
                            },
                            "companyId": {
                              "type": "string",
                              "description": "Stamped from the caller's authenticated company. Sent in the body is silently dropped."
                            },
                            "userId": {
                              "type": "string",
                              "description": "Id of the user who created this question. Sent in the body is silently dropped."
                            },
                            "agentId": {
                              "type": "string",
                              "description": "Required on create. Immutable after create -- sent on update is silently dropped."
                            },
                            "templateId": {
                              "type": "string",
                              "description": "Required on create. The question template this question is based on. Immutable after create -- sent on update is silently dropped."
                            },
                            "customConfig": {
                              "type": "object",
                              "description": "Agent-level override of the template's defaultConfig. Only the keys you send are overridden; the rest fall back to the template.",
                              "properties": {
                                "displayLabel": {
                                  "type": "string"
                                },
                                "question": {
                                  "type": "string",
                                  "description": "The prompt text the agent speaks to ask this question. Renamed from promptText."
                                },
                                "confirmationText": {
                                  "type": "string"
                                },
                                "validationPrompt": {
                                  "type": "string"
                                },
                                "validation": {
                                  "type": "object",
                                  "properties": {
                                    "pattern": {
                                      "type": "string"
                                    },
                                    "minLength": {
                                      "type": "number"
                                    },
                                    "maxLength": {
                                      "type": "number"
                                    },
                                    "min": {
                                      "type": "number"
                                    },
                                    "max": {
                                      "type": "number"
                                    },
                                    "allowedValues": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "required": {
                              "type": "boolean",
                              "description": "Defaults to false. Agent must collect this before ending the conversation."
                            },
                            "maxPromptAttempts": {
                              "type": "number",
                              "minimum": 1,
                              "maximum": 3,
                              "description": "Defaults to 2. Hard maximum of 3. Joi validates this as Joi.number().integer(), which this spec generator reports as \"number\"."
                            },
                            "noResponseBehavior": {
                              "type": "string",
                              "enum": [
                                "move_to_next_question",
                                "end_conversation"
                              ],
                              "description": "Defaults to move_to_next_question."
                            },
                            "triggerCondition": {
                              "type": "string"
                            },
                            "order": {
                              "type": "number",
                              "description": "Defaults to 0. Use PUT /voice/questions/reorder to reorder in bulk."
                            },
                            "enabled": {
                              "type": "boolean",
                              "description": "Defaults to true."
                            },
                            "mappedFieldId": {
                              "type": "string",
                              "nullable": true,
                              "description": "Id of a general company Field (see the Fields API) this question's collected answer is written onto after each call ends. Send null or an empty string to clear the mapping."
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "field": {
                    "value": {
                      "status": "success",
                      "data": {
                        "field": {
                          "fieldId": "q-8f2a1c4e",
                          "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                          "templateId": "tpl-email",
                          "required": true,
                          "maxPromptAttempts": 2,
                          "noResponseBehavior": "move_to_next_question",
                          "order": 0,
                          "enabled": true,
                          "mappedFieldId": "6650a1b2c3d4e5f678901234",
                          "createdAt": "2026-08-01T12:00:00.000Z",
                          "updatedAt": "2026-08-01T12:00:00.000Z"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage questions"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent or template not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Questions"
      }
    },
    "/voice/questions/{fieldId}": {
      "get": {
        "tags": [
          "Voice Agent Questions"
        ],
        "summary": "Get Question",
        "operationId": "voice-questions-get",
        "description": "### Get Question\n\nFetches a single question by id, scoped to your company.",
        "parameters": [
          {
            "name": "fieldId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "field": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use fieldId to identify it."
                            },
                            "fieldId": {
                              "type": "string",
                              "description": "Server-generated UUID. Immutable -- sent in the body on create or update is silently dropped."
                            },
                            "companyId": {
                              "type": "string",
                              "description": "Stamped from the caller's authenticated company. Sent in the body is silently dropped."
                            },
                            "userId": {
                              "type": "string",
                              "description": "Id of the user who created this question. Sent in the body is silently dropped."
                            },
                            "agentId": {
                              "type": "string",
                              "description": "Required on create. Immutable after create -- sent on update is silently dropped."
                            },
                            "templateId": {
                              "type": "string",
                              "description": "Required on create. The question template this question is based on. Immutable after create -- sent on update is silently dropped."
                            },
                            "customConfig": {
                              "type": "object",
                              "description": "Agent-level override of the template's defaultConfig. Only the keys you send are overridden; the rest fall back to the template.",
                              "properties": {
                                "displayLabel": {
                                  "type": "string"
                                },
                                "question": {
                                  "type": "string",
                                  "description": "The prompt text the agent speaks to ask this question. Renamed from promptText."
                                },
                                "confirmationText": {
                                  "type": "string"
                                },
                                "validationPrompt": {
                                  "type": "string"
                                },
                                "validation": {
                                  "type": "object",
                                  "properties": {
                                    "pattern": {
                                      "type": "string"
                                    },
                                    "minLength": {
                                      "type": "number"
                                    },
                                    "maxLength": {
                                      "type": "number"
                                    },
                                    "min": {
                                      "type": "number"
                                    },
                                    "max": {
                                      "type": "number"
                                    },
                                    "allowedValues": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "required": {
                              "type": "boolean",
                              "description": "Defaults to false. Agent must collect this before ending the conversation."
                            },
                            "maxPromptAttempts": {
                              "type": "number",
                              "minimum": 1,
                              "maximum": 3,
                              "description": "Defaults to 2. Hard maximum of 3. Joi validates this as Joi.number().integer(), which this spec generator reports as \"number\"."
                            },
                            "noResponseBehavior": {
                              "type": "string",
                              "enum": [
                                "move_to_next_question",
                                "end_conversation"
                              ],
                              "description": "Defaults to move_to_next_question."
                            },
                            "triggerCondition": {
                              "type": "string"
                            },
                            "order": {
                              "type": "number",
                              "description": "Defaults to 0. Use PUT /voice/questions/reorder to reorder in bulk."
                            },
                            "enabled": {
                              "type": "boolean",
                              "description": "Defaults to true."
                            },
                            "mappedFieldId": {
                              "type": "string",
                              "nullable": true,
                              "description": "Id of a general company Field (see the Fields API) this question's collected answer is written onto after each call ends. Send null or an empty string to clear the mapping."
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "field": {
                    "value": {
                      "status": "success",
                      "data": {
                        "field": {
                          "fieldId": "q-8f2a1c4e",
                          "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                          "templateId": "tpl-email",
                          "required": true,
                          "maxPromptAttempts": 2,
                          "noResponseBehavior": "move_to_next_question",
                          "order": 0,
                          "enabled": true,
                          "mappedFieldId": "6650a1b2c3d4e5f678901234",
                          "createdAt": "2026-08-01T12:00:00.000Z",
                          "updatedAt": "2026-08-01T12:00:00.000Z"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Field not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Field not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Questions"
      },
      "put": {
        "tags": [
          "Voice Agent Questions"
        ],
        "summary": "Update Question",
        "operationId": "voice-questions-update",
        "description": "### Update Question\n\nRequires the OWNER or ADMIN role. Partial update -- only the keys you send are changed. agentId and templateId cannot be changed after create; sending them is silently dropped.",
        "parameters": [
          {
            "name": "fieldId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "customConfig": {
                    "type": "object",
                    "description": "Agent-level override of the template's defaultConfig. Only the keys you send are overridden; the rest fall back to the template.",
                    "properties": {
                      "displayLabel": {
                        "type": "string"
                      },
                      "question": {
                        "type": "string",
                        "description": "The prompt text the agent speaks to ask this question. Renamed from promptText."
                      },
                      "confirmationText": {
                        "type": "string"
                      },
                      "validationPrompt": {
                        "type": "string"
                      },
                      "validation": {
                        "type": "object",
                        "properties": {
                          "pattern": {
                            "type": "string"
                          },
                          "minLength": {
                            "type": "number"
                          },
                          "maxLength": {
                            "type": "number"
                          },
                          "min": {
                            "type": "number"
                          },
                          "max": {
                            "type": "number"
                          },
                          "allowedValues": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  },
                  "required": {
                    "type": "boolean"
                  },
                  "maxPromptAttempts": {
                    "type": "number",
                    "minimum": 1,
                    "maximum": 3
                  },
                  "noResponseBehavior": {
                    "type": "string",
                    "enum": [
                      "move_to_next_question",
                      "end_conversation"
                    ]
                  },
                  "triggerCondition": {
                    "type": "string"
                  },
                  "order": {
                    "type": "number"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "mappedFieldId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Id of an existing company Field to write this question's collected answer onto after each call."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "field": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use fieldId to identify it."
                            },
                            "fieldId": {
                              "type": "string",
                              "description": "Server-generated UUID. Immutable -- sent in the body on create or update is silently dropped."
                            },
                            "companyId": {
                              "type": "string",
                              "description": "Stamped from the caller's authenticated company. Sent in the body is silently dropped."
                            },
                            "userId": {
                              "type": "string",
                              "description": "Id of the user who created this question. Sent in the body is silently dropped."
                            },
                            "agentId": {
                              "type": "string",
                              "description": "Required on create. Immutable after create -- sent on update is silently dropped."
                            },
                            "templateId": {
                              "type": "string",
                              "description": "Required on create. The question template this question is based on. Immutable after create -- sent on update is silently dropped."
                            },
                            "customConfig": {
                              "type": "object",
                              "description": "Agent-level override of the template's defaultConfig. Only the keys you send are overridden; the rest fall back to the template.",
                              "properties": {
                                "displayLabel": {
                                  "type": "string"
                                },
                                "question": {
                                  "type": "string",
                                  "description": "The prompt text the agent speaks to ask this question. Renamed from promptText."
                                },
                                "confirmationText": {
                                  "type": "string"
                                },
                                "validationPrompt": {
                                  "type": "string"
                                },
                                "validation": {
                                  "type": "object",
                                  "properties": {
                                    "pattern": {
                                      "type": "string"
                                    },
                                    "minLength": {
                                      "type": "number"
                                    },
                                    "maxLength": {
                                      "type": "number"
                                    },
                                    "min": {
                                      "type": "number"
                                    },
                                    "max": {
                                      "type": "number"
                                    },
                                    "allowedValues": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "required": {
                              "type": "boolean",
                              "description": "Defaults to false. Agent must collect this before ending the conversation."
                            },
                            "maxPromptAttempts": {
                              "type": "number",
                              "minimum": 1,
                              "maximum": 3,
                              "description": "Defaults to 2. Hard maximum of 3. Joi validates this as Joi.number().integer(), which this spec generator reports as \"number\"."
                            },
                            "noResponseBehavior": {
                              "type": "string",
                              "enum": [
                                "move_to_next_question",
                                "end_conversation"
                              ],
                              "description": "Defaults to move_to_next_question."
                            },
                            "triggerCondition": {
                              "type": "string"
                            },
                            "order": {
                              "type": "number",
                              "description": "Defaults to 0. Use PUT /voice/questions/reorder to reorder in bulk."
                            },
                            "enabled": {
                              "type": "boolean",
                              "description": "Defaults to true."
                            },
                            "mappedFieldId": {
                              "type": "string",
                              "nullable": true,
                              "description": "Id of a general company Field (see the Fields API) this question's collected answer is written onto after each call ends. Send null or an empty string to clear the mapping."
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "field": {
                    "value": {
                      "status": "success",
                      "data": {
                        "field": {
                          "fieldId": "q-8f2a1c4e",
                          "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                          "templateId": "tpl-email",
                          "required": true,
                          "maxPromptAttempts": 2,
                          "noResponseBehavior": "move_to_next_question",
                          "order": 0,
                          "enabled": true,
                          "mappedFieldId": "6650a1b2c3d4e5f678901234",
                          "createdAt": "2026-08-01T12:00:00.000Z",
                          "updatedAt": "2026-08-01T12:00:00.000Z"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage questions"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Field not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Field not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Questions"
      },
      "delete": {
        "tags": [
          "Voice Agent Questions"
        ],
        "summary": "Delete Question",
        "operationId": "voice-questions-delete",
        "description": "### Delete Question\n\nRequires the OWNER or ADMIN role. Permanently removes the question from the agent and decrements the template's usageCount.",
        "parameters": [
          {
            "name": "fieldId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "message": {
                    "value": {
                      "status": "success",
                      "message": "Field deleted successfully"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage questions"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Field not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Field not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Questions"
      }
    },
    "/voice/questions/reorder": {
      "put": {
        "tags": [
          "Voice Agent Questions"
        ],
        "summary": "Reorder Questions",
        "operationId": "voice-questions-reorder",
        "description": "### Reorder Questions\n\nRequires the OWNER or ADMIN role. Bulk-writes the order field on each listed question, then returns the agent's full question list in its new order. Entries for a fieldId that does not belong to the given agentId are silently skipped (no error).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agentId": {
                    "type": "string",
                    "description": "Required."
                  },
                  "fieldOrders": {
                    "type": "array",
                    "description": "Required. The new order for some or all of the agent's questions; each entry's order value is written directly (not resequenced).",
                    "items": {
                      "type": "object",
                      "properties": {
                        "fieldId": {
                          "type": "string"
                        },
                        "order": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "fieldId",
                        "order"
                      ]
                    }
                  }
                },
                "required": [
                  "agentId",
                  "fieldOrders"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "fields": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "MongoDB document id, included because every document has one; use fieldId to identify it."
                              },
                              "fieldId": {
                                "type": "string",
                                "description": "Server-generated UUID. Immutable -- sent in the body on create or update is silently dropped."
                              },
                              "companyId": {
                                "type": "string",
                                "description": "Stamped from the caller's authenticated company. Sent in the body is silently dropped."
                              },
                              "userId": {
                                "type": "string",
                                "description": "Id of the user who created this question. Sent in the body is silently dropped."
                              },
                              "agentId": {
                                "type": "string",
                                "description": "Required on create. Immutable after create -- sent on update is silently dropped."
                              },
                              "templateId": {
                                "type": "string",
                                "description": "Required on create. The question template this question is based on. Immutable after create -- sent on update is silently dropped."
                              },
                              "customConfig": {
                                "type": "object",
                                "description": "Agent-level override of the template's defaultConfig. Only the keys you send are overridden; the rest fall back to the template.",
                                "properties": {
                                  "displayLabel": {
                                    "type": "string"
                                  },
                                  "question": {
                                    "type": "string",
                                    "description": "The prompt text the agent speaks to ask this question. Renamed from promptText."
                                  },
                                  "confirmationText": {
                                    "type": "string"
                                  },
                                  "validationPrompt": {
                                    "type": "string"
                                  },
                                  "validation": {
                                    "type": "object",
                                    "properties": {
                                      "pattern": {
                                        "type": "string"
                                      },
                                      "minLength": {
                                        "type": "number"
                                      },
                                      "maxLength": {
                                        "type": "number"
                                      },
                                      "min": {
                                        "type": "number"
                                      },
                                      "max": {
                                        "type": "number"
                                      },
                                      "allowedValues": {
                                        "type": "array",
                                        "items": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  }
                                }
                              },
                              "required": {
                                "type": "boolean",
                                "description": "Defaults to false. Agent must collect this before ending the conversation."
                              },
                              "maxPromptAttempts": {
                                "type": "number",
                                "minimum": 1,
                                "maximum": 3,
                                "description": "Defaults to 2. Hard maximum of 3. Joi validates this as Joi.number().integer(), which this spec generator reports as \"number\"."
                              },
                              "noResponseBehavior": {
                                "type": "string",
                                "enum": [
                                  "move_to_next_question",
                                  "end_conversation"
                                ],
                                "description": "Defaults to move_to_next_question."
                              },
                              "triggerCondition": {
                                "type": "string"
                              },
                              "order": {
                                "type": "number",
                                "description": "Defaults to 0. Use PUT /voice/questions/reorder to reorder in bulk."
                              },
                              "enabled": {
                                "type": "boolean",
                                "description": "Defaults to true."
                              },
                              "mappedFieldId": {
                                "type": "string",
                                "nullable": true,
                                "description": "Id of a general company Field (see the Fields API) this question's collected answer is written onto after each call ends. Send null or an empty string to clear the mapping."
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "fields": {
                    "value": {
                      "status": "success",
                      "data": {
                        "fields": [
                          {
                            "fieldId": "q-8f2a1c4e",
                            "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                            "templateId": "tpl-email",
                            "required": true,
                            "maxPromptAttempts": 2,
                            "noResponseBehavior": "move_to_next_question",
                            "order": 0,
                            "enabled": true,
                            "mappedFieldId": "6650a1b2c3d4e5f678901234",
                            "createdAt": "2026-08-01T12:00:00.000Z",
                            "updatedAt": "2026-08-01T12:00:00.000Z"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage questions"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Questions"
      }
    },
    "/voice/question-templates": {
      "get": {
        "tags": [
          "Voice Agent Questions"
        ],
        "summary": "List Question Templates",
        "operationId": "voice-question-templates-list",
        "description": "### List Question Templates\n\nLists the question templates visible to your company: Speak's shared system templates, plus your own company's templates.",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "contact",
                "booking",
                "qualification",
                "payment",
                "custom"
              ]
            },
            "description": "Filter to one category."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "templates": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "MongoDB document id, included because every document has one; use templateId to identify it."
                              },
                              "templateId": {
                                "type": "string",
                                "description": "Server-generated UUID. Immutable."
                              },
                              "userId": {
                                "type": "string",
                                "nullable": true,
                                "description": "Id of the user who created this template. Absent on a system template."
                              },
                              "name": {
                                "type": "string",
                                "description": "Required on create."
                              },
                              "description": {
                                "type": "string",
                                "description": "Required on create."
                              },
                              "category": {
                                "type": "string",
                                "enum": [
                                  "contact",
                                  "booking",
                                  "qualification",
                                  "payment",
                                  "custom"
                                ],
                                "description": "Required on create."
                              },
                              "fieldType": {
                                "type": "string",
                                "enum": [
                                  "email",
                                  "phone",
                                  "date",
                                  "time",
                                  "datetime",
                                  "text",
                                  "number",
                                  "boolean",
                                  "choice",
                                  "url"
                                ],
                                "description": "Required on create."
                              },
                              "defaultConfig": {
                                "type": "object",
                                "properties": {
                                  "displayLabel": {
                                    "type": "string"
                                  },
                                  "question": {
                                    "type": "string",
                                    "description": "The prompt text the agent speaks to ask this. Renamed from promptText."
                                  },
                                  "confirmationText": {
                                    "type": "string"
                                  },
                                  "validationPrompt": {
                                    "type": "string"
                                  },
                                  "validation": {
                                    "type": "object",
                                    "properties": {
                                      "pattern": {
                                        "type": "string"
                                      },
                                      "minLength": {
                                        "type": "number"
                                      },
                                      "maxLength": {
                                        "type": "number"
                                      },
                                      "min": {
                                        "type": "number"
                                      },
                                      "max": {
                                        "type": "number"
                                      },
                                      "allowedValues": {
                                        "type": "array",
                                        "items": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  }
                                },
                                "description": "Required on create. displayLabel and question are both required within this object."
                              },
                              "isSystemTemplate": {
                                "type": "boolean",
                                "description": "Always false for a template your company creates. Not settable directly."
                              },
                              "isPublic": {
                                "type": "boolean",
                                "description": "Defaults to false."
                              },
                              "tags": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "usageCount": {
                                "type": "integer",
                                "description": "Incremented when a question is created from this template, decremented when that question is deleted. Not settable directly."
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "templates": {
                    "value": {
                      "status": "success",
                      "data": {
                        "templates": [
                          {
                            "templateId": "tpl-email",
                            "name": "Email",
                            "description": "The caller's email address",
                            "category": "contact",
                            "fieldType": "email",
                            "defaultConfig": {
                              "displayLabel": "Email",
                              "question": "What is your email address?"
                            },
                            "isSystemTemplate": true,
                            "isPublic": true,
                            "tags": [],
                            "usageCount": 12,
                            "createdAt": "2026-01-01T00:00:00.000Z",
                            "updatedAt": "2026-01-01T00:00:00.000Z"
                          }
                        ],
                        "total": 1
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Question Templates"
      },
      "post": {
        "tags": [
          "Voice Agent Questions"
        ],
        "summary": "Create Question Template",
        "operationId": "voice-question-templates-create",
        "description": "### Create Question Template\n\nRequires the OWNER or ADMIN role. Creates a company-scoped template -- the \"custom question\" a user names themselves rather than picking from Speak's shared library. The server stamps companyId and forces isSystemTemplate to false, so this template is only ever visible to your company.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Required."
                  },
                  "description": {
                    "type": "string",
                    "description": "Required."
                  },
                  "category": {
                    "type": "string",
                    "enum": [
                      "contact",
                      "booking",
                      "qualification",
                      "payment",
                      "custom"
                    ],
                    "description": "Required."
                  },
                  "fieldType": {
                    "type": "string",
                    "enum": [
                      "email",
                      "phone",
                      "date",
                      "time",
                      "datetime",
                      "text",
                      "number",
                      "boolean",
                      "choice",
                      "url"
                    ],
                    "description": "Required."
                  },
                  "defaultConfig": {
                    "type": "object",
                    "properties": {
                      "displayLabel": {
                        "type": "string"
                      },
                      "question": {
                        "type": "string",
                        "description": "The prompt text the agent speaks to ask this. Renamed from promptText."
                      },
                      "confirmationText": {
                        "type": "string"
                      },
                      "validationPrompt": {
                        "type": "string"
                      },
                      "validation": {
                        "type": "object",
                        "properties": {
                          "pattern": {
                            "type": "string"
                          },
                          "minLength": {
                            "type": "number"
                          },
                          "maxLength": {
                            "type": "number"
                          },
                          "min": {
                            "type": "number"
                          },
                          "max": {
                            "type": "number"
                          },
                          "allowedValues": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    },
                    "description": "Required on create. displayLabel and question are both required within this object."
                  },
                  "isPublic": {
                    "type": "boolean"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "required": [
                  "name",
                  "description",
                  "category",
                  "fieldType",
                  "defaultConfig"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "template": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use templateId to identify it."
                            },
                            "templateId": {
                              "type": "string",
                              "description": "Server-generated UUID. Immutable."
                            },
                            "userId": {
                              "type": "string",
                              "nullable": true,
                              "description": "Id of the user who created this template. Absent on a system template."
                            },
                            "name": {
                              "type": "string",
                              "description": "Required on create."
                            },
                            "description": {
                              "type": "string",
                              "description": "Required on create."
                            },
                            "category": {
                              "type": "string",
                              "enum": [
                                "contact",
                                "booking",
                                "qualification",
                                "payment",
                                "custom"
                              ],
                              "description": "Required on create."
                            },
                            "fieldType": {
                              "type": "string",
                              "enum": [
                                "email",
                                "phone",
                                "date",
                                "time",
                                "datetime",
                                "text",
                                "number",
                                "boolean",
                                "choice",
                                "url"
                              ],
                              "description": "Required on create."
                            },
                            "defaultConfig": {
                              "type": "object",
                              "properties": {
                                "displayLabel": {
                                  "type": "string"
                                },
                                "question": {
                                  "type": "string",
                                  "description": "The prompt text the agent speaks to ask this. Renamed from promptText."
                                },
                                "confirmationText": {
                                  "type": "string"
                                },
                                "validationPrompt": {
                                  "type": "string"
                                },
                                "validation": {
                                  "type": "object",
                                  "properties": {
                                    "pattern": {
                                      "type": "string"
                                    },
                                    "minLength": {
                                      "type": "number"
                                    },
                                    "maxLength": {
                                      "type": "number"
                                    },
                                    "min": {
                                      "type": "number"
                                    },
                                    "max": {
                                      "type": "number"
                                    },
                                    "allowedValues": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              },
                              "description": "Required on create. displayLabel and question are both required within this object."
                            },
                            "isSystemTemplate": {
                              "type": "boolean",
                              "description": "Always false for a template your company creates. Not settable directly."
                            },
                            "isPublic": {
                              "type": "boolean",
                              "description": "Defaults to false."
                            },
                            "tags": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "usageCount": {
                              "type": "integer",
                              "description": "Incremented when a question is created from this template, decremented when that question is deleted. Not settable directly."
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "template": {
                    "value": {
                      "status": "success",
                      "data": {
                        "template": {
                          "templateId": "tpl-email",
                          "name": "Email",
                          "description": "The caller's email address",
                          "category": "contact",
                          "fieldType": "email",
                          "defaultConfig": {
                            "displayLabel": "Email",
                            "question": "What is your email address?"
                          },
                          "isSystemTemplate": true,
                          "isPublic": true,
                          "tags": [],
                          "usageCount": 12,
                          "createdAt": "2026-01-01T00:00:00.000Z",
                          "updatedAt": "2026-01-01T00:00:00.000Z"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage questions"
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Question Templates"
      }
    },
    "/voice/voices": {
      "get": {
        "tags": [
          "Voice Agents"
        ],
        "summary": "List Voices",
        "operationId": "voice-voices-list",
        "description": "### List Voices\n\nLists the voices visible to your company: Speak's shared system catalog, plus your own company's uploaded voices, whether public or not.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "voices": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "MongoDB document id, included because every document has one. Not used to identify a voice anywhere in this API -- use voiceId for that."
                              },
                              "voiceId": {
                                "type": "string",
                                "description": "Client-supplied on create if you send one, otherwise server-generated. The identifier for this voice everywhere in this API (unlike most resources, this catalog has no separate server-generated UUID)."
                              },
                              "companyId": {
                                "type": "string",
                                "nullable": true,
                                "description": "Absent on a shared system-catalog voice, which every company can read but only Speak can write. Present on a company's own uploaded voice. Not settable directly."
                              },
                              "createdBy": {
                                "type": "string",
                                "description": "Id of the user who created this voice. Not settable directly."
                              },
                              "name": {
                                "type": "string",
                                "description": "Required on create."
                              },
                              "provider": {
                                "type": "string",
                                "enum": [
                                  "elevenlabs",
                                  "openai",
                                  "deepgram",
                                  "cartesia",
                                  "google",
                                  "azure"
                                ],
                                "description": "Required on create."
                              },
                              "language": {
                                "type": "string",
                                "description": "Defaults to English."
                              },
                              "languageCode": {
                                "type": "string",
                                "description": "Defaults to en."
                              },
                              "gender": {
                                "type": "string",
                                "enum": [
                                  "male",
                                  "female",
                                  "neutral"
                                ]
                              },
                              "age": {
                                "type": "string",
                                "enum": [
                                  "young",
                                  "middle-aged",
                                  "old"
                                ]
                              },
                              "accent": {
                                "type": "string"
                              },
                              "description": {
                                "type": "string"
                              },
                              "previewUrl": {
                                "type": "string"
                              },
                              "category": {
                                "type": "string",
                                "enum": [
                                  "premade",
                                  "cloned",
                                  "custom",
                                  "professional",
                                  "conversational"
                                ],
                                "description": "Defaults to premade."
                              },
                              "tags": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "isPremium": {
                                "type": "boolean",
                                "description": "Defaults to false."
                              },
                              "isMultilingual": {
                                "type": "boolean",
                                "description": "Defaults to false."
                              },
                              "isPublic": {
                                "type": "boolean",
                                "description": "Defaults to true."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "active",
                                  "inactive",
                                  "processing",
                                  "error"
                                ],
                                "description": "Defaults to active."
                              },
                              "providerData": {
                                "type": "object",
                                "description": "Arbitrary provider-specific data. Shape is not validated."
                              },
                              "metadata": {
                                "type": "object",
                                "description": "Arbitrary metadata object. Shape is not validated."
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "voices": {
                    "value": {
                      "status": "success",
                      "data": {
                        "voices": [
                          {
                            "_id": "6650a1b2c3d4e5f678901234",
                            "voiceId": "b2c3d4e5-f678-9012-abcd-ef1234567890",
                            "createdBy": "user-1",
                            "name": "Rachel",
                            "provider": "elevenlabs",
                            "language": "English",
                            "languageCode": "en",
                            "gender": "female",
                            "category": "premade",
                            "tags": [],
                            "isPremium": false,
                            "isMultilingual": true,
                            "isPublic": true,
                            "status": "active",
                            "createdAt": "2026-01-01T00:00:00.000Z",
                            "updatedAt": "2026-01-01T00:00:00.000Z"
                          }
                        ],
                        "total": 1
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Voices"
      }
    },
    "/voice/knowledge-base/{agentId}/gaps": {
      "get": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "List KB Gaps",
        "operationId": "voice-kb-gaps-list",
        "description": "### List Knowledge Base Gaps\n\nLists this agent's pending KB gaps -- questions callers asked that the agent answered with low confidence or an explicit \"I don't know,\" surfaced automatically after calls. Up to the 50 most recent pending gaps, newest first.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "gaps": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "MongoDB document id, included because every document has one; use gapId to identify it."
                              },
                              "gapId": {
                                "type": "string",
                                "description": "Server-generated. Immutable."
                              },
                              "agentId": {
                                "type": "string"
                              },
                              "query": {
                                "type": "string",
                                "description": "The caller question that triggered a low-confidence or hedging KB answer."
                              },
                              "context": {
                                "type": "string"
                              },
                              "avgRetrievalScore": {
                                "type": "number"
                              },
                              "conversationId": {
                                "type": "string",
                                "description": "The call this gap surfaced from. See Conversations."
                              },
                              "suggestedTitle": {
                                "type": "string"
                              },
                              "suggestedAnswer": {
                                "type": "string",
                                "description": "AI-drafted answer. Override with title/answer in the request body when adding to the KB."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "pending",
                                  "added",
                                  "dismissed"
                                ]
                              },
                              "severity": {
                                "type": "string",
                                "enum": [
                                  "low",
                                  "medium",
                                  "high"
                                ]
                              },
                              "resolvedAt": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "gaps": {
                    "value": {
                      "status": "success",
                      "data": {
                        "gaps": [
                          {
                            "gapId": "gap-4f1a",
                            "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                            "query": "Do you offer a student discount?",
                            "avgRetrievalScore": 0.31,
                            "conversationId": "c9d8e7f6-a5b4-3210-9876-543210fedcba",
                            "suggestedTitle": "Student discount policy",
                            "suggestedAnswer": "We don't currently offer a student discount.",
                            "status": "pending",
                            "severity": "medium",
                            "resolvedAt": null,
                            "createdAt": "2026-08-01T12:00:00.000Z",
                            "updatedAt": "2026-08-01T12:00:00.000Z"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Knowledge Base Gaps"
      }
    },
    "/voice/knowledge-base/{agentId}/gaps/analyze": {
      "post": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Analyze KB Gaps",
        "operationId": "voice-kb-gaps-analyze",
        "description": "### Analyze KB Gaps\n\nRequires the OWNER or ADMIN role. Triggers gap analysis over this agent's recent calls in the background and returns immediately -- new gaps appear in the list once analysis finishes, which is not synchronous with this response.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "message": {
                    "value": {
                      "status": "success",
                      "message": "Analysis started"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Knowledge Base Gaps"
      }
    },
    "/voice/knowledge-base/{agentId}/gaps/{gapId}/add": {
      "post": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Add Gap To KB",
        "operationId": "voice-kb-gaps-add",
        "description": "### Add Gap To Knowledge Base\n\nRequires the OWNER or ADMIN role. Writes the gap's answer (or your override) into the agent's knowledge base as a new document, and marks the gap added. Fails with 409 if the gap was already added or dismissed, or if the agent has no knowledge base collection to write into.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "gapId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "answer": {
                    "type": "string",
                    "description": "Overrides suggestedAnswer. Optional."
                  },
                  "title": {
                    "type": "string",
                    "description": "Overrides suggestedTitle. Optional."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "message": {
                    "value": {
                      "status": "success",
                      "message": "Added to knowledge base"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Gap not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Gap not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "conflict": {
                    "value": {
                      "status": "failed",
                      "message": "Gap already resolved"
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Knowledge Base Gaps"
      }
    },
    "/voice/knowledge-base/{agentId}/gaps/{gapId}": {
      "delete": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Dismiss Gap",
        "operationId": "voice-kb-gaps-dismiss",
        "description": "### Dismiss Gap\n\nRequires the OWNER or ADMIN role. Marks the gap dismissed without writing anything to the knowledge base.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "gapId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "message": {
                    "value": {
                      "status": "success",
                      "message": "Gap dismissed"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Gap not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Gap not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Knowledge Base Gaps"
      }
    },
    "/voice/knowledge-base/{agentId}/faqs": {
      "get": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "List FAQ Suggestions",
        "operationId": "voice-kb-faqs-list",
        "description": "### List FAQ Suggestions\n\nLists this agent's pending FAQ suggestions -- questions multiple callers asked in similar form, clustered and drafted into a reusable question/answer pair. Up to the 20 largest clusters, largest first.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "faqs": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "MongoDB document id, included because every document has one; use suggestionId to identify it."
                              },
                              "suggestionId": {
                                "type": "string",
                                "description": "Server-generated. Immutable. Used as the suggestionId path parameter on every FAQ endpoint."
                              },
                              "agentId": {
                                "type": "string"
                              },
                              "question": {
                                "type": "string"
                              },
                              "answer": {
                                "type": "string"
                              },
                              "sourceConversationIds": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "The calls this FAQ was clustered from. See Conversations."
                              },
                              "clusterSize": {
                                "type": "integer",
                                "description": "How many similar caller questions were grouped into this one suggestion."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "pending",
                                  "added",
                                  "dismissed"
                                ]
                              },
                              "resolvedAt": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "faqs": {
                    "value": {
                      "status": "success",
                      "data": {
                        "faqs": [
                          {
                            "suggestionId": "sugg-7c2e",
                            "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                            "question": "What are your business hours?",
                            "answer": "We're open Monday to Friday, 9am to 5pm.",
                            "sourceConversationIds": [
                              "c9d8e7f6-a5b4-3210-9876-543210fedcba"
                            ],
                            "clusterSize": 4,
                            "status": "pending",
                            "resolvedAt": null,
                            "createdAt": "2026-08-01T12:00:00.000Z",
                            "updatedAt": "2026-08-01T12:00:00.000Z"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "FAQs"
      }
    },
    "/voice/knowledge-base/{agentId}/faqs/generate": {
      "post": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Generate FAQ Suggestions",
        "operationId": "voice-kb-faqs-generate",
        "description": "### Generate FAQ Suggestions\n\nRequires the OWNER or ADMIN role. Triggers FAQ clustering over this agent's recent calls in the background and returns immediately -- new suggestions appear in the list once generation finishes, which is not synchronous with this response.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "message": {
                    "value": {
                      "status": "success",
                      "message": "FAQ generation started"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "FAQs"
      }
    },
    "/voice/agent-resources": {
      "get": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "List Agent Resources",
        "operationId": "voice-agent-resources-list",
        "description": "### List Agent Resources\n\nLists the knowledge documents/links an agent searches during calls -- separate from the KB Gaps and FAQ Suggestions above, which are the self-improvement layer that surfaces what an agent is missing, not the content itself. Paginated; optionally scoped to one agentId, and searchable by title/description.",
        "parameters": [
          {
            "name": "agentId",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Scope to one agent's resources. Omit to list across all your agents."
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Defaults to 1."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Defaults to 10, max 100."
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive match against title or description."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "resources": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "MongoDB document id, included because every document has one; use resourceId to identify it."
                              },
                              "resourceId": {
                                "type": "string",
                                "description": "Server-generated UUID. Immutable -- sent in the body on create or update is silently dropped."
                              },
                              "agentId": {
                                "type": "string",
                                "description": "Required on create. Immutable after create -- sent on update is silently dropped."
                              },
                              "companyId": {
                                "type": "string",
                                "description": "Stamped from the caller's authenticated company. Sent in the body is silently dropped."
                              },
                              "userId": {
                                "type": "string",
                                "description": "Id of the user who created this resource. Sent in the body is silently dropped."
                              },
                              "url": {
                                "type": "string",
                                "format": "uri",
                                "description": "Required on create."
                              },
                              "title": {
                                "type": "string",
                                "description": "Required on create. Max 200 characters."
                              },
                              "description": {
                                "type": "string",
                                "description": "Required on create. Max 1000 characters."
                              },
                              "action": {
                                "type": "string",
                                "enum": [
                                  "link",
                                  "presentation"
                                ],
                                "description": "Required on create."
                              },
                              "contentType": {
                                "type": "string",
                                "enum": [
                                  "video",
                                  "pdf",
                                  "image"
                                ]
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "pending",
                                  "uploading",
                                  "processing",
                                  "completed",
                                  "failed"
                                ],
                                "description": "Defaults to pending. Advances as the resource's content is fetched and embedded for the agent to search during calls. Not settable directly."
                              },
                              "isDeleted": {
                                "type": "boolean",
                                "description": "Delete is a soft delete. Not settable directly."
                              },
                              "deletedAt": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        },
                        "total": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "limit": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "resources": {
                    "value": {
                      "status": "success",
                      "data": {
                        "resources": [
                          {
                            "resourceId": "res-2a9f",
                            "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                            "url": "https://docs.example.com/pricing",
                            "title": "Pricing page",
                            "description": "Current plan pricing and feature comparison",
                            "action": "link",
                            "status": "completed",
                            "isDeleted": false,
                            "createdAt": "2026-08-01T12:00:00.000Z",
                            "updatedAt": "2026-08-01T12:00:00.000Z"
                          }
                        ],
                        "total": 1,
                        "page": 1,
                        "limit": 10
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Agent Resources"
      },
      "post": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Create Agent Resource",
        "operationId": "voice-agent-resources-create",
        "description": "### Create Agent Resource\n\nRequires the OWNER or ADMIN role. Adds one document/link to an agent's knowledge base; the server fetches and embeds the content in the background (status moves from pending to completed).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agentId": {
                    "type": "string",
                    "description": "Required."
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Required."
                  },
                  "title": {
                    "type": "string",
                    "description": "Required. Max 200 characters."
                  },
                  "description": {
                    "type": "string",
                    "description": "Required. Max 1000 characters."
                  },
                  "action": {
                    "type": "string",
                    "enum": [
                      "link",
                      "presentation"
                    ],
                    "description": "Required."
                  },
                  "contentType": {
                    "type": "string",
                    "enum": [
                      "video",
                      "pdf",
                      "image"
                    ]
                  }
                },
                "required": [
                  "agentId",
                  "url",
                  "title",
                  "description",
                  "action"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "resource": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use resourceId to identify it."
                            },
                            "resourceId": {
                              "type": "string",
                              "description": "Server-generated UUID. Immutable -- sent in the body on create or update is silently dropped."
                            },
                            "agentId": {
                              "type": "string",
                              "description": "Required on create. Immutable after create -- sent on update is silently dropped."
                            },
                            "companyId": {
                              "type": "string",
                              "description": "Stamped from the caller's authenticated company. Sent in the body is silently dropped."
                            },
                            "userId": {
                              "type": "string",
                              "description": "Id of the user who created this resource. Sent in the body is silently dropped."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri",
                              "description": "Required on create."
                            },
                            "title": {
                              "type": "string",
                              "description": "Required on create. Max 200 characters."
                            },
                            "description": {
                              "type": "string",
                              "description": "Required on create. Max 1000 characters."
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "link",
                                "presentation"
                              ],
                              "description": "Required on create."
                            },
                            "contentType": {
                              "type": "string",
                              "enum": [
                                "video",
                                "pdf",
                                "image"
                              ]
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "pending",
                                "uploading",
                                "processing",
                                "completed",
                                "failed"
                              ],
                              "description": "Defaults to pending. Advances as the resource's content is fetched and embedded for the agent to search during calls. Not settable directly."
                            },
                            "isDeleted": {
                              "type": "boolean",
                              "description": "Delete is a soft delete. Not settable directly."
                            },
                            "deletedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "resource": {
                    "value": {
                      "status": "success",
                      "data": {
                        "resource": {
                          "resourceId": "res-2a9f",
                          "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                          "url": "https://docs.example.com/pricing",
                          "title": "Pricing page",
                          "description": "Current plan pricing and feature comparison",
                          "action": "link",
                          "status": "completed",
                          "isDeleted": false,
                          "createdAt": "2026-08-01T12:00:00.000Z",
                          "updatedAt": "2026-08-01T12:00:00.000Z"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agent resources"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Agent Resources"
      }
    },
    "/voice/agent-resources/bulk": {
      "post": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Bulk Create Agent Resources",
        "operationId": "voice-agent-resources-bulk-create",
        "description": "### Bulk Create Agent Resources\n\nRequires the OWNER or ADMIN role. Adds up to 100 documents/links in one call; each is fetched and embedded independently in the background.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agentId": {
                    "type": "string",
                    "description": "Required."
                  },
                  "resources": {
                    "type": "array",
                    "description": "Required. 1 to 100 entries, each shaped like the Create Agent Resource request body minus agentId.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "agentId": {
                          "type": "string",
                          "description": "Required."
                        },
                        "url": {
                          "type": "string",
                          "format": "uri",
                          "description": "Required."
                        },
                        "title": {
                          "type": "string",
                          "description": "Required. Max 200 characters."
                        },
                        "description": {
                          "type": "string",
                          "description": "Required. Max 1000 characters."
                        },
                        "action": {
                          "type": "string",
                          "enum": [
                            "link",
                            "presentation"
                          ],
                          "description": "Required."
                        },
                        "contentType": {
                          "type": "string",
                          "enum": [
                            "video",
                            "pdf",
                            "image"
                          ]
                        }
                      }
                    }
                  }
                },
                "required": [
                  "agentId",
                  "resources"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "resources": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "MongoDB document id, included because every document has one; use resourceId to identify it."
                              },
                              "resourceId": {
                                "type": "string",
                                "description": "Server-generated UUID. Immutable -- sent in the body on create or update is silently dropped."
                              },
                              "agentId": {
                                "type": "string",
                                "description": "Required on create. Immutable after create -- sent on update is silently dropped."
                              },
                              "companyId": {
                                "type": "string",
                                "description": "Stamped from the caller's authenticated company. Sent in the body is silently dropped."
                              },
                              "userId": {
                                "type": "string",
                                "description": "Id of the user who created this resource. Sent in the body is silently dropped."
                              },
                              "url": {
                                "type": "string",
                                "format": "uri",
                                "description": "Required on create."
                              },
                              "title": {
                                "type": "string",
                                "description": "Required on create. Max 200 characters."
                              },
                              "description": {
                                "type": "string",
                                "description": "Required on create. Max 1000 characters."
                              },
                              "action": {
                                "type": "string",
                                "enum": [
                                  "link",
                                  "presentation"
                                ],
                                "description": "Required on create."
                              },
                              "contentType": {
                                "type": "string",
                                "enum": [
                                  "video",
                                  "pdf",
                                  "image"
                                ]
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "pending",
                                  "uploading",
                                  "processing",
                                  "completed",
                                  "failed"
                                ],
                                "description": "Defaults to pending. Advances as the resource's content is fetched and embedded for the agent to search during calls. Not settable directly."
                              },
                              "isDeleted": {
                                "type": "boolean",
                                "description": "Delete is a soft delete. Not settable directly."
                              },
                              "deletedAt": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "resources": {
                    "value": {
                      "status": "success",
                      "data": {
                        "resources": [
                          {
                            "resourceId": "res-2a9f",
                            "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                            "url": "https://docs.example.com/pricing",
                            "title": "Pricing page",
                            "description": "Current plan pricing and feature comparison",
                            "action": "link",
                            "status": "completed",
                            "isDeleted": false,
                            "createdAt": "2026-08-01T12:00:00.000Z",
                            "updatedAt": "2026-08-01T12:00:00.000Z"
                          }
                        ],
                        "total": 1
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agent resources"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Agent Resources"
      }
    },
    "/voice/agent-resources/{resourceId}": {
      "put": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Update Agent Resource",
        "operationId": "voice-agent-resources-update",
        "description": "### Update Agent Resource\n\nRequires the OWNER or ADMIN role. Partial update -- send at least one field. agentId cannot be changed. Changing url, title, or description re-triggers embedding.",
        "parameters": [
          {
            "name": "resourceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Required."
                  },
                  "title": {
                    "type": "string",
                    "description": "Required. Max 200 characters."
                  },
                  "description": {
                    "type": "string",
                    "description": "Required. Max 1000 characters."
                  },
                  "action": {
                    "type": "string",
                    "enum": [
                      "link",
                      "presentation"
                    ],
                    "description": "Required."
                  },
                  "contentType": {
                    "type": "string",
                    "enum": [
                      "video",
                      "pdf",
                      "image"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "resource": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use resourceId to identify it."
                            },
                            "resourceId": {
                              "type": "string",
                              "description": "Server-generated UUID. Immutable -- sent in the body on create or update is silently dropped."
                            },
                            "agentId": {
                              "type": "string",
                              "description": "Required on create. Immutable after create -- sent on update is silently dropped."
                            },
                            "companyId": {
                              "type": "string",
                              "description": "Stamped from the caller's authenticated company. Sent in the body is silently dropped."
                            },
                            "userId": {
                              "type": "string",
                              "description": "Id of the user who created this resource. Sent in the body is silently dropped."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri",
                              "description": "Required on create."
                            },
                            "title": {
                              "type": "string",
                              "description": "Required on create. Max 200 characters."
                            },
                            "description": {
                              "type": "string",
                              "description": "Required on create. Max 1000 characters."
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "link",
                                "presentation"
                              ],
                              "description": "Required on create."
                            },
                            "contentType": {
                              "type": "string",
                              "enum": [
                                "video",
                                "pdf",
                                "image"
                              ]
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "pending",
                                "uploading",
                                "processing",
                                "completed",
                                "failed"
                              ],
                              "description": "Defaults to pending. Advances as the resource's content is fetched and embedded for the agent to search during calls. Not settable directly."
                            },
                            "isDeleted": {
                              "type": "boolean",
                              "description": "Delete is a soft delete. Not settable directly."
                            },
                            "deletedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "resource": {
                    "value": {
                      "status": "success",
                      "data": {
                        "resource": {
                          "resourceId": "res-2a9f",
                          "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                          "url": "https://docs.example.com/pricing",
                          "title": "Pricing page",
                          "description": "Current plan pricing and feature comparison",
                          "action": "link",
                          "status": "completed",
                          "isDeleted": false,
                          "createdAt": "2026-08-01T12:00:00.000Z",
                          "updatedAt": "2026-08-01T12:00:00.000Z"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agent resources"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Resource not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Agent Resources"
      },
      "delete": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Delete Agent Resource",
        "operationId": "voice-agent-resources-delete",
        "description": "### Delete Agent Resource\n\nRequires the OWNER or ADMIN role. Soft-deletes the resource (isDeleted set true) -- it stops appearing in lists and the agent stops searching it, but the document is not physically removed.",
        "parameters": [
          {
            "name": "resourceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "message": {
                    "value": {
                      "status": "success",
                      "message": "Resource deleted successfully"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agent resources"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Resource not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Agent Resources"
      }
    },
    "/voice/conversations": {
      "get": {
        "tags": [
          "Voice Agent Conversations"
        ],
        "summary": "List Conversations",
        "operationId": "voice-conversations-list",
        "description": "### List Conversations\n\nLists calls handled by your voice agents, newest first. Once a call finishes processing, mediaId links it to a regular Speak media record -- pull the recording, transcript, and insights through the Media API using that id.",
        "parameters": [
          {
            "name": "agentId",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "One agent id, or repeat the param for several (?agentId=a&agentId=b)."
          },
          {
            "name": "callType",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "web",
                "phone"
              ]
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Matches against the agent's name. Max 200 characters."
          },
          {
            "name": "startDate",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO 8601 date."
          },
          {
            "name": "endDate",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO 8601 date."
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Defaults to 1."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Defaults to 50, max 200."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "conversations": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "MongoDB document id, included because every document has one; use conversationId to identify it."
                              },
                              "conversationId": {
                                "type": "string",
                                "description": "Server-generated UUID. Immutable."
                              },
                              "agentId": {
                                "type": "string"
                              },
                              "agentName": {
                                "type": "string",
                                "description": "Only present on the single-conversation Get response, resolved server-side for display."
                              },
                              "companyId": {
                                "type": "string"
                              },
                              "userId": {
                                "type": "string",
                                "nullable": true
                              },
                              "widgetSessionId": {
                                "type": "string",
                                "nullable": true
                              },
                              "participants": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "sessionId": {
                                "type": "string"
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "active",
                                  "completed",
                                  "ended",
                                  "transferred"
                                ]
                              },
                              "duration": {
                                "type": "number",
                                "description": "Call length in seconds."
                              },
                              "costs": {
                                "type": "object",
                                "description": "Vendor cost breakdown (LLM, TTS, STT, telephony). Reporting only, not the customer charge."
                              },
                              "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "endedAt": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              },
                              "endedReason": {
                                "type": "string",
                                "nullable": true
                              },
                              "recordingUrls": {
                                "type": "object",
                                "properties": {
                                  "mixed": {
                                    "type": "string"
                                  },
                                  "user": {
                                    "type": "string"
                                  },
                                  "agent": {
                                    "type": "string"
                                  }
                                }
                              },
                              "recordingStatus": {
                                "type": "string",
                                "enum": [
                                  "pending",
                                  "recording",
                                  "processing",
                                  "completed",
                                  "failed"
                                ]
                              },
                              "callType": {
                                "type": "string",
                                "enum": [
                                  "web",
                                  "phone"
                                ]
                              },
                              "sourceLanguage": {
                                "type": "string",
                                "nullable": true
                              },
                              "phone": {
                                "type": "object",
                                "properties": {
                                  "callSid": {
                                    "type": "string"
                                  },
                                  "from": {
                                    "type": "string"
                                  },
                                  "to": {
                                    "type": "string"
                                  }
                                }
                              },
                              "handoff": {
                                "type": "object",
                                "properties": {
                                  "occurred": {
                                    "type": "boolean"
                                  },
                                  "targetNumber": {
                                    "type": "string"
                                  },
                                  "transferredAt": {
                                    "type": "string",
                                    "format": "date-time"
                                  },
                                  "summary": {
                                    "type": "string"
                                  }
                                }
                              },
                              "callerId": {
                                "type": "string",
                                "nullable": true
                              },
                              "mediaId": {
                                "type": "string",
                                "nullable": true,
                                "description": "Set once the call's post-call pipeline finishes. This is a regular Speak media record -- use it with the Media API (GET /media/{mediaId}, insights, transcript, export) to pull the recording, transcript, summary, and any Fields this call's Questions wrote onto it."
                              },
                              "folderId": {
                                "type": "string",
                                "nullable": true,
                                "description": "The folder the call's media was filed into. See the Folders API."
                              },
                              "pipelineState": {
                                "type": "string",
                                "enum": [
                                  "pending",
                                  "running",
                                  "completed"
                                ],
                                "description": "Internal post-call processing state. pending/running calls may not have mediaId set yet."
                              },
                              "feedback": {
                                "type": "object",
                                "properties": {
                                  "rating": {
                                    "type": "integer"
                                  },
                                  "comment": {
                                    "type": "string"
                                  },
                                  "submittedAt": {
                                    "type": "string",
                                    "format": "date-time"
                                  }
                                }
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        },
                        "total": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "limit": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "conversations": {
                    "value": {
                      "status": "success",
                      "data": {
                        "conversations": [
                          {
                            "conversationId": "c9d8e7f6-a5b4-3210-9876-543210fedcba",
                            "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                            "companyId": "6650a1b2c3d4e5f60000000a",
                            "participants": [
                              "caller"
                            ],
                            "sessionId": "sess-88a1",
                            "status": "completed",
                            "duration": 142.5,
                            "startedAt": "2026-08-01T12:00:00.000Z",
                            "endedAt": "2026-08-01T12:02:22.500Z",
                            "endedReason": "user_hangup",
                            "recordingStatus": "completed",
                            "callType": "web",
                            "mediaId": "6650a1b2c3d4e5f678909999",
                            "folderId": "6650a1b2c3d4e5f678908888",
                            "pipelineState": "completed",
                            "createdAt": "2026-08-01T12:00:00.000Z",
                            "updatedAt": "2026-08-01T12:02:25.000Z"
                          }
                        ],
                        "total": 1,
                        "page": 1,
                        "limit": 50
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/voice/conversations/{conversationId}": {
      "get": {
        "tags": [
          "Voice Agent Conversations"
        ],
        "summary": "Get Conversation",
        "operationId": "voice-conversations-get",
        "description": "### Get Conversation\n\nFetches a single call by id, scoped to your company. Use mediaId from the response with the Media API to retrieve the recording, transcript, and analysis for this call.",
        "parameters": [
          {
            "name": "conversationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "conversation": {
                          "type": "object",
                          "properties": {
                            "_id": {
                              "type": "string",
                              "description": "MongoDB document id, included because every document has one; use conversationId to identify it."
                            },
                            "conversationId": {
                              "type": "string",
                              "description": "Server-generated UUID. Immutable."
                            },
                            "agentId": {
                              "type": "string"
                            },
                            "agentName": {
                              "type": "string",
                              "description": "Only present on the single-conversation Get response, resolved server-side for display."
                            },
                            "companyId": {
                              "type": "string"
                            },
                            "userId": {
                              "type": "string",
                              "nullable": true
                            },
                            "widgetSessionId": {
                              "type": "string",
                              "nullable": true
                            },
                            "participants": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "sessionId": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "active",
                                "completed",
                                "ended",
                                "transferred"
                              ]
                            },
                            "duration": {
                              "type": "number",
                              "description": "Call length in seconds."
                            },
                            "costs": {
                              "type": "object",
                              "description": "Vendor cost breakdown (LLM, TTS, STT, telephony). Reporting only, not the customer charge."
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "endedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "endedReason": {
                              "type": "string",
                              "nullable": true
                            },
                            "recordingUrls": {
                              "type": "object",
                              "properties": {
                                "mixed": {
                                  "type": "string"
                                },
                                "user": {
                                  "type": "string"
                                },
                                "agent": {
                                  "type": "string"
                                }
                              }
                            },
                            "recordingStatus": {
                              "type": "string",
                              "enum": [
                                "pending",
                                "recording",
                                "processing",
                                "completed",
                                "failed"
                              ]
                            },
                            "callType": {
                              "type": "string",
                              "enum": [
                                "web",
                                "phone"
                              ]
                            },
                            "sourceLanguage": {
                              "type": "string",
                              "nullable": true
                            },
                            "phone": {
                              "type": "object",
                              "properties": {
                                "callSid": {
                                  "type": "string"
                                },
                                "from": {
                                  "type": "string"
                                },
                                "to": {
                                  "type": "string"
                                }
                              }
                            },
                            "handoff": {
                              "type": "object",
                              "properties": {
                                "occurred": {
                                  "type": "boolean"
                                },
                                "targetNumber": {
                                  "type": "string"
                                },
                                "transferredAt": {
                                  "type": "string",
                                  "format": "date-time"
                                },
                                "summary": {
                                  "type": "string"
                                }
                              }
                            },
                            "callerId": {
                              "type": "string",
                              "nullable": true
                            },
                            "mediaId": {
                              "type": "string",
                              "nullable": true,
                              "description": "Set once the call's post-call pipeline finishes. This is a regular Speak media record -- use it with the Media API (GET /media/{mediaId}, insights, transcript, export) to pull the recording, transcript, summary, and any Fields this call's Questions wrote onto it."
                            },
                            "folderId": {
                              "type": "string",
                              "nullable": true,
                              "description": "The folder the call's media was filed into. See the Folders API."
                            },
                            "pipelineState": {
                              "type": "string",
                              "enum": [
                                "pending",
                                "running",
                                "completed"
                              ],
                              "description": "Internal post-call processing state. pending/running calls may not have mediaId set yet."
                            },
                            "feedback": {
                              "type": "object",
                              "properties": {
                                "rating": {
                                  "type": "integer"
                                },
                                "comment": {
                                  "type": "string"
                                },
                                "submittedAt": {
                                  "type": "string",
                                  "format": "date-time"
                                }
                              }
                            },
                            "createdAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "updatedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "conversation": {
                    "value": {
                      "status": "success",
                      "data": {
                        "conversation": {
                          "conversationId": "c9d8e7f6-a5b4-3210-9876-543210fedcba",
                          "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                          "companyId": "6650a1b2c3d4e5f60000000a",
                          "participants": [
                            "caller"
                          ],
                          "sessionId": "sess-88a1",
                          "status": "completed",
                          "duration": 142.5,
                          "startedAt": "2026-08-01T12:00:00.000Z",
                          "endedAt": "2026-08-01T12:02:22.500Z",
                          "endedReason": "user_hangup",
                          "recordingStatus": "completed",
                          "callType": "web",
                          "mediaId": "6650a1b2c3d4e5f678909999",
                          "folderId": "6650a1b2c3d4e5f678908888",
                          "pipelineState": "completed",
                          "createdAt": "2026-08-01T12:00:00.000Z",
                          "updatedAt": "2026-08-01T12:02:25.000Z"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Conversation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Conversation not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/voice/conversations/{conversationId}/events": {
      "get": {
        "tags": [
          "Voice Agent Conversations"
        ],
        "summary": "Get Conversation Events",
        "operationId": "voice-conversations-events",
        "description": "### Get Conversation Events\n\nLists the raw turn-by-turn event log for one call (in chronological order): each transcript turn, tool call, and lifecycle transition the worker recorded during the call.",
        "parameters": [
          {
            "name": "conversationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "events": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "MongoDB document id, included because every document has one; use eventId to identify it."
                              },
                              "eventId": {
                                "type": "string"
                              },
                              "conversationId": {
                                "type": "string"
                              },
                              "eventType": {
                                "type": "string",
                                "description": "One of the voice call lifecycle event types (turn taken, tool called, handoff, etc)."
                              },
                              "timestamp": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "cost": {
                                "type": "number",
                                "nullable": true
                              },
                              "platformCost": {
                                "type": "number",
                                "nullable": true
                              },
                              "data": {
                                "type": "object",
                                "description": "Event-type-specific payload. Shape varies by eventType."
                              },
                              "metadata": {
                                "type": "object",
                                "properties": {
                                  "requestId": {
                                    "type": "string"
                                  },
                                  "turnNumber": {
                                    "type": "integer"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "events": {
                    "value": {
                      "status": "success",
                      "data": {
                        "events": [
                          {
                            "eventId": "evt-1",
                            "conversationId": "c9d8e7f6-a5b4-3210-9876-543210fedcba",
                            "eventType": "turn_completed",
                            "timestamp": "2026-08-01T12:00:05.000Z"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Conversation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Conversation not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/voice/sharing/{agentId}/share": {
      "post": {
        "tags": [
          "Voice Agent Sharing"
        ],
        "summary": "Enable Share",
        "operationId": "voice-sharing-enable",
        "description": "### Enable Share\n\nRequires the OWNER or ADMIN role. Turns on the agent's public share link and embeddable widget. Safe to call again to change isPublic/allowedDomains/expiresAt -- the existing shareToken and shortCode are kept rather than rotated.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "isPublic": {
                    "type": "boolean",
                    "description": "Defaults to false."
                  },
                  "allowedDomains": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Restrict the embeddable widget to these domains. Defaults to empty (no restriction)."
                  },
                  "expiresAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "agentId": {
                          "type": "string"
                        },
                        "isPublic": {
                          "type": "boolean"
                        },
                        "shareToken": {
                          "type": "string",
                          "description": "Reused across repeated enable calls once generated. Part of the public share link and the widget embed."
                        },
                        "shortCode": {
                          "type": "string",
                          "description": "Short, URL-friendly alias for shareToken."
                        },
                        "allowedDomains": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "expiresAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "share": {
                    "value": {
                      "status": "success",
                      "data": {
                        "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                        "isPublic": true,
                        "shareToken": "9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e",
                        "shortCode": "aB3dE7fG9h",
                        "allowedDomains": [],
                        "expiresAt": null
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage sharing"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Voice Agent Sharing"
        ],
        "summary": "Disable Share",
        "operationId": "voice-sharing-disable",
        "description": "### Disable Share\n\nRequires the OWNER or ADMIN role. Turns off public sharing and clears shareToken/shortCode -- a later Enable Share issues new ones, so any previously distributed share link stops working permanently, not just while disabled.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "message": {
                    "value": {
                      "status": "success",
                      "message": "Share disabled successfully"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage sharing"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/voice/sharing/{agentId}/widget-config": {
      "patch": {
        "tags": [
          "Voice Agent Sharing"
        ],
        "summary": "Update Widget Config",
        "operationId": "voice-sharing-widget-config",
        "description": "### Update Widget Config\n\nRequires the OWNER or ADMIN role. Partial update of the embeddable widget's appearance and copy -- send at least one of the 24 keys listed here. Rejects any key outside this list (`.unknown(false)` in the server's validation) rather than silently ignoring it, unlike most other partial-update endpoints in this API.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "displayMode": {
                    "type": "string",
                    "enum": [
                      "floating",
                      "inline"
                    ]
                  },
                  "position": {
                    "type": "string",
                    "enum": [
                      "bottom-left",
                      "bottom-right"
                    ]
                  },
                  "bubbleIconType": {
                    "type": "string",
                    "enum": [
                      "avatar",
                      "generic"
                    ]
                  },
                  "buttonSize": {
                    "type": "string",
                    "enum": [
                      "small",
                      "medium",
                      "large"
                    ]
                  },
                  "buttonColor": {
                    "type": "string"
                  },
                  "theme": {
                    "type": "string",
                    "enum": [
                      "light",
                      "dark",
                      "auto"
                    ]
                  },
                  "compactMode": {
                    "type": "boolean"
                  },
                  "defaultMode": {
                    "type": "string",
                    "enum": [
                      "voice",
                      "avatar"
                    ]
                  },
                  "showAvatar": {
                    "type": "boolean"
                  },
                  "fontFamily": {
                    "type": "string"
                  },
                  "borderRadius": {
                    "type": "number",
                    "minimum": 0
                  },
                  "backgroundColor": {
                    "type": "string"
                  },
                  "voiceEnabled": {
                    "type": "boolean"
                  },
                  "enableUserCamera": {
                    "type": "boolean"
                  },
                  "chatOpenByDefault": {
                    "type": "boolean"
                  },
                  "launcherTitle": {
                    "type": "string"
                  },
                  "launcherSubtitle": {
                    "type": "string"
                  },
                  "showLauncher": {
                    "type": "boolean"
                  },
                  "beforeCallTitle": {
                    "type": "string"
                  },
                  "beforeCallDescription": {
                    "type": "string"
                  },
                  "startButtonLabel": {
                    "type": "string"
                  },
                  "afterCallTitle": {
                    "type": "string"
                  },
                  "afterCallDescription": {
                    "type": "string"
                  },
                  "feedbackEnabled": {
                    "type": "boolean"
                  },
                  "companyLogoUrl": {
                    "type": "string"
                  }
                },
                "minProperties": 1
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "widgetConfig": {
                          "type": "object",
                          "properties": {
                            "displayMode": {
                              "type": "string",
                              "enum": [
                                "floating",
                                "inline"
                              ]
                            },
                            "position": {
                              "type": "string",
                              "enum": [
                                "bottom-left",
                                "bottom-right"
                              ]
                            },
                            "bubbleIconType": {
                              "type": "string",
                              "enum": [
                                "avatar",
                                "generic"
                              ]
                            },
                            "buttonSize": {
                              "type": "string",
                              "enum": [
                                "small",
                                "medium",
                                "large"
                              ]
                            },
                            "buttonColor": {
                              "type": "string"
                            },
                            "theme": {
                              "type": "string",
                              "enum": [
                                "light",
                                "dark",
                                "auto"
                              ]
                            },
                            "compactMode": {
                              "type": "boolean"
                            },
                            "defaultMode": {
                              "type": "string",
                              "enum": [
                                "voice",
                                "avatar"
                              ]
                            },
                            "showAvatar": {
                              "type": "boolean"
                            },
                            "fontFamily": {
                              "type": "string"
                            },
                            "borderRadius": {
                              "type": "number",
                              "minimum": 0
                            },
                            "backgroundColor": {
                              "type": "string"
                            },
                            "voiceEnabled": {
                              "type": "boolean"
                            },
                            "enableUserCamera": {
                              "type": "boolean"
                            },
                            "chatOpenByDefault": {
                              "type": "boolean"
                            },
                            "launcherTitle": {
                              "type": "string"
                            },
                            "launcherSubtitle": {
                              "type": "string"
                            },
                            "showLauncher": {
                              "type": "boolean"
                            },
                            "beforeCallTitle": {
                              "type": "string"
                            },
                            "beforeCallDescription": {
                              "type": "string"
                            },
                            "startButtonLabel": {
                              "type": "string"
                            },
                            "afterCallTitle": {
                              "type": "string"
                            },
                            "afterCallDescription": {
                              "type": "string"
                            },
                            "feedbackEnabled": {
                              "type": "boolean"
                            },
                            "companyLogoUrl": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "widgetConfig": {
                    "value": {
                      "status": "success",
                      "data": {
                        "widgetConfig": {
                          "displayMode": "floating",
                          "position": "bottom-right",
                          "theme": "auto"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "No widget configuration fields provided",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage sharing"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/voice/sharing/{agentId}/company-logo/sign": {
      "post": {
        "tags": [
          "Voice Agent Sharing"
        ],
        "summary": "Sign Company Logo Upload",
        "operationId": "voice-sharing-logo-sign",
        "description": "### Sign Company Logo Upload\n\nRequires the OWNER or ADMIN role. Issues a presigned S3 URL for uploading a widget company logo -- you upload the file bytes directly to S3 with a PUT request, then persist the returned companyLogoUrl by calling Update Widget Config yourself. This endpoint does not update the agent.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contentType": {
                    "type": "string",
                    "enum": [
                      "image/png",
                      "image/jpeg",
                      "image/webp",
                      "image/svg+xml"
                    ],
                    "description": "Required."
                  }
                },
                "required": [
                  "contentType"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "uploadUrl": {
                          "type": "string",
                          "description": "Presigned S3 PUT URL, valid briefly. PUT the file's bytes here directly with the same contentType."
                        },
                        "companyLogoUrl": {
                          "type": "string",
                          "nullable": true,
                          "description": "The public CDN URL the file will be reachable at once uploaded. Save this via Update Widget Config's companyLogoUrl -- uploading here does not update the agent by itself."
                        },
                        "key": {
                          "type": "string",
                          "description": "The S3 object key the file was signed for."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "upload": {
                    "value": {
                      "status": "success",
                      "data": {
                        "uploadUrl": "https://s3.amazonaws.com/speak-uploads/voice-agents/a1b2c3d4/company-logo/1735689600000.png?X-Amz-Signature=...",
                        "companyLogoUrl": "https://cdn.speakai.co/voice-agents/a1b2c3d4/company-logo/1735689600000.png",
                        "key": "voice-agents/a1b2c3d4/company-logo/1735689600000.png"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage sharing"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/voice/analytics/overview": {
      "get": {
        "tags": [
          "Voice Agent Analytics"
        ],
        "summary": "Analytics Overview",
        "operationId": "voice-analytics-overview",
        "description": "### Analytics Overview\n\nWorkspace-level call metrics: totals, week-over-week counts, completion rate, average duration, a 14-day daily time series, and average post-call feedback rating. Optionally scope to one agentId. Unlike most endpoints in this API, the response payload sits directly on data, not nested under a named key.",
        "parameters": [
          {
            "name": "agentId",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Scope to one agent. Omit for the whole workspace."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "totalConversations": {
                          "type": "integer"
                        },
                        "thisWeekCount": {
                          "type": "integer"
                        },
                        "lastWeekCount": {
                          "type": "integer"
                        },
                        "completionRate": {
                          "type": "number",
                          "description": "0-1. Share of calls that reached status completed."
                        },
                        "avgDurationSeconds": {
                          "type": "number"
                        },
                        "dailyCounts": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": {
                                "type": "string"
                              },
                              "count": {
                                "type": "integer"
                              }
                            }
                          },
                          "description": "Last 14 days, oldest first, zero-filled for days with no calls."
                        },
                        "averageRating": {
                          "type": "number",
                          "description": "Average post-call feedback rating (1-5). 0 if no feedback submitted yet."
                        },
                        "ratingCount": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "overview": {
                    "value": {
                      "status": "success",
                      "data": {
                        "totalConversations": 214,
                        "thisWeekCount": 31,
                        "lastWeekCount": 27,
                        "completionRate": 0.92,
                        "avgDurationSeconds": 138.4,
                        "dailyCounts": [
                          {
                            "date": "2026-07-19",
                            "count": 4
                          },
                          {
                            "date": "2026-07-20",
                            "count": 6
                          }
                        ],
                        "averageRating": 4.3,
                        "ratingCount": 58
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/voice/analytics/funnel/agent": {
      "get": {
        "tags": [
          "Voice Agent Analytics"
        ],
        "summary": "Engagement Funnel For Agent",
        "operationId": "voice-analytics-funnel-agent",
        "description": "### Engagement Funnel For Agent\n\nBuckets one agent's conversations by transcript turn count (bounce/brief/engaged/deep), each with average duration and sentiment split. Defaults to the last 30 days if since is omitted; since older than 365 days is floored to 365 days ago. The response payload sits directly on data, not nested under a named key.",
        "parameters": [
          {
            "name": "agentId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Required."
          },
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO date. Defaults to 30 days ago."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "buckets": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "label": {
                                "type": "string"
                              },
                              "minMessages": {
                                "type": "integer"
                              },
                              "maxMessages": {
                                "type": "integer",
                                "nullable": true
                              },
                              "count": {
                                "type": "integer"
                              },
                              "percentage": {
                                "type": "integer"
                              },
                              "avgDurationSeconds": {
                                "type": "number"
                              },
                              "sentimentBreakdown": {
                                "type": "object",
                                "properties": {
                                  "positive": {
                                    "type": "integer"
                                  },
                                  "neutral": {
                                    "type": "integer"
                                  },
                                  "negative": {
                                    "type": "integer"
                                  },
                                  "unanalyzed": {
                                    "type": "integer"
                                  }
                                }
                              }
                            }
                          },
                          "description": "Always 4 buckets, in order: Bounce (0-1 turns), Brief (2-5), Engaged (6-15), Deep (16+)."
                        },
                        "totalConversations": {
                          "type": "integer"
                        },
                        "since": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "funnel": {
                    "value": {
                      "status": "success",
                      "data": {
                        "buckets": [
                          {
                            "label": "Bounce (0-1)",
                            "minMessages": 0,
                            "maxMessages": 1,
                            "count": 12,
                            "percentage": 15,
                            "avgDurationSeconds": 8.2,
                            "sentimentBreakdown": {
                              "positive": 2,
                              "neutral": 8,
                              "negative": 2,
                              "unanalyzed": 0
                            }
                          }
                        ],
                        "totalConversations": 80,
                        "since": "2026-07-01T00:00:00.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid since date",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/voice/analytics/funnel": {
      "get": {
        "tags": [
          "Voice Agent Analytics"
        ],
        "summary": "Engagement Funnel Summaries",
        "operationId": "voice-analytics-funnel-summary",
        "description": "### Engagement Funnel Summaries\n\nThe same bounce/brief/engaged/deep breakdown as Engagement Funnel For Agent, but as one summary row per agent across your whole workspace, sorted by deepRate descending. The response payload is a bare array directly on data -- not an object, and not nested under a named key.",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO date. Defaults to 30 days ago."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "agentId": {
                            "type": "string"
                          },
                          "agentName": {
                            "type": "string"
                          },
                          "totalConversations": {
                            "type": "integer"
                          },
                          "bounceRate": {
                            "type": "integer"
                          },
                          "briefRate": {
                            "type": "integer"
                          },
                          "engagedRate": {
                            "type": "integer"
                          },
                          "deepRate": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "summaries": {
                    "value": {
                      "status": "success",
                      "data": [
                        {
                          "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                          "agentName": "Support Agent",
                          "totalConversations": 80,
                          "bounceRate": 15,
                          "briefRate": 30,
                          "engagedRate": 40,
                          "deepRate": 15
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid since date",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/voice/analytics/agent": {
      "get": {
        "tags": [
          "Voice Agent Analytics"
        ],
        "summary": "Agent Analytics",
        "operationId": "voice-analytics-agent",
        "description": "### Agent Analytics\n\nEverything the agent analytics view shows for one agent over a date range: headline numbers with an optional comparison to the previous period, a daily series, audience (locations, devices, traffic sources), leads, handoffs, action items, engagement, sentiment, topics, end reasons, satisfaction, call timing, languages and web versus phone. The response payload sits directly on data, not nested under a named key.\n\nLeave out `start` for all time. A `start` more than 5 years before `end` is moved up to 5 years before `end`. A `start` after `end` returns 400. Rates are fractions from 0 to 1.",
        "parameters": [
          {
            "name": "agentId",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The agent to report on. Required. Must be an agent in your workspace, otherwise the request returns 404.",
            "required": true,
            "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
          },
          {
            "name": "start",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Start of the window, as an ISO 8601 date. Optional. Leave it out for all time.",
            "example": "2026-09-01T00:00:00.000Z"
          },
          {
            "name": "end",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "End of the window, as an ISO 8601 date. Optional. Defaults to now.",
            "example": "2026-09-30T23:59:59.999Z"
          },
          {
            "name": "tz",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 100,
              "default": "UTC"
            },
            "description": "IANA time zone used to bucket days, hours and weekdays, such as `America/Toronto`. Optional. Defaults to `UTC`. At most 100 characters. An unknown zone returns 400.",
            "example": "America/Toronto"
          },
          {
            "name": "compare",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Also return the same numbers for the period of equal length just before `start`, in `previousKpis`. Optional. Defaults to `false`. Has no effect without `start`.",
            "example": "true"
          },
          {
            "name": "includeTests",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Count test calls placed from the dashboard. Optional. Defaults to `false`. `testCalls.count` reports them either way.",
            "example": "false"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "range": {
                          "type": "object",
                          "properties": {
                            "start": {
                              "type": "string",
                              "nullable": true,
                              "format": "date-time",
                              "description": "Start of the window. Null when you sent no `start`, which means all time."
                            },
                            "end": {
                              "type": "string",
                              "format": "date-time",
                              "description": "End of the window. Now when you sent no `end`."
                            },
                            "tz": {
                              "type": "string",
                              "description": "The time zone used to bucket days, hours and weekdays."
                            },
                            "previousStart": {
                              "type": "string",
                              "nullable": true,
                              "format": "date-time",
                              "description": "Start of the comparison window. Null unless `compare` is true and `start` was sent."
                            },
                            "previousEnd": {
                              "type": "string",
                              "nullable": true,
                              "format": "date-time",
                              "description": "End of the comparison window, which is the current `start`. Null unless `compare` is true and `start` was sent."
                            }
                          },
                          "description": "The window the numbers cover."
                        },
                        "testCalls": {
                          "type": "object",
                          "properties": {
                            "count": {
                              "type": "integer",
                              "description": "Test calls placed from the dashboard in the window, counted whether or not they are included."
                            },
                            "included": {
                              "type": "boolean",
                              "description": "Whether test calls are counted in the other numbers, matching `includeTests`."
                            }
                          }
                        },
                        "overview": {
                          "type": "object",
                          "properties": {
                            "kpis": {
                              "type": "object",
                              "properties": {
                                "conversations": {
                                  "type": "integer"
                                },
                                "completionRate": {
                                  "type": "number",
                                  "description": "Completed conversations divided by all conversations, from 0 to 1."
                                },
                                "avgDurationSeconds": {
                                  "type": "number"
                                },
                                "returningCallers": {
                                  "type": "integer",
                                  "description": "Callers in the window who called more than once, or who also called before the window."
                                }
                              }
                            },
                            "previousKpis": {
                              "type": "object",
                              "properties": {
                                "conversations": {
                                  "type": "integer"
                                },
                                "completionRate": {
                                  "type": "number"
                                },
                                "avgDurationSeconds": {
                                  "type": "number"
                                },
                                "returningCallers": {
                                  "type": "integer"
                                }
                              },
                              "nullable": true,
                              "description": "The same numbers for the comparison window. Null unless `compare` is true and `start` was sent."
                            },
                            "overTime": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "date": {
                                    "type": "string",
                                    "description": "Day as `YYYY-MM-DD`."
                                  },
                                  "conversations": {
                                    "type": "integer"
                                  },
                                  "web": {
                                    "type": "integer"
                                  },
                                  "phone": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "description": "One entry per day in the window, zero filled, in the requested time zone. Capped at the most recent 3,660 days. Empty when no `start` was sent and there are no conversations."
                            }
                          }
                        },
                        "audience": {
                          "type": "object",
                          "properties": {
                            "locations": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "city": {
                                    "type": "string",
                                    "nullable": true
                                  },
                                  "region": {
                                    "type": "string",
                                    "nullable": true
                                  },
                                  "country": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "Country name."
                                  },
                                  "count": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "description": "Up to 10 locations with the most conversations."
                            },
                            "locationUnknown": {
                              "type": "integer",
                              "description": "Conversations not counted in `locations`."
                            },
                            "devices": {
                              "type": "object",
                              "properties": {
                                "withDeviceData": {
                                  "type": "integer"
                                },
                                "deviceTypes": {
                                  "type": "object",
                                  "properties": {
                                    "desktop": {
                                      "type": "integer"
                                    },
                                    "mobile": {
                                      "type": "integer"
                                    },
                                    "tablet": {
                                      "type": "integer"
                                    }
                                  }
                                },
                                "browsers": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "name": {
                                        "type": "string"
                                      },
                                      "count": {
                                        "type": "integer"
                                      }
                                    }
                                  },
                                  "description": "Up to 5 browsers."
                                },
                                "os": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "name": {
                                        "type": "string"
                                      },
                                      "count": {
                                        "type": "integer"
                                      }
                                    }
                                  },
                                  "description": "Up to 5 operating systems."
                                }
                              },
                              "description": "Web calls only. Phone calls carry no device data."
                            },
                            "sources": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "kind": {
                                    "type": "string",
                                    "enum": [
                                      "page",
                                      "campaign",
                                      "direct"
                                    ],
                                    "description": "`campaign` when the call carried UTM tags, `page` when it came from a referring page, `direct` otherwise."
                                  },
                                  "label": {
                                    "type": "string",
                                    "description": "The UTM source and campaign, or the referring host and path. Empty for `direct`."
                                  },
                                  "count": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "description": "Up to 10 traffic sources for web calls."
                            }
                          }
                        },
                        "attention": {
                          "type": "object",
                          "properties": {
                            "notJoined": {
                              "type": "integer",
                              "description": "Web calls that ended before the caller said anything."
                            },
                            "unanswered": {
                              "type": "integer",
                              "description": "Knowledge gaps for this agent still waiting for an answer. Not limited to the window."
                            }
                          }
                        },
                        "outcomes": {
                          "type": "object",
                          "properties": {
                            "leads": {
                              "type": "object",
                              "properties": {
                                "count": {
                                  "type": "integer"
                                },
                                "rate": {
                                  "type": "number",
                                  "description": "Lead conversations divided by all conversations, from 0 to 1."
                                },
                                "fields": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "field": {
                                        "type": "string"
                                      },
                                      "count": {
                                        "type": "integer"
                                      }
                                    }
                                  },
                                  "description": "Up to 6 collected fields that were filled in most often."
                                },
                                "latest": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "conversationId": {
                                        "type": "string"
                                      },
                                      "createdAt": {
                                        "type": "string"
                                      },
                                      "name": {
                                        "type": "string",
                                        "nullable": true
                                      },
                                      "email": {
                                        "type": "string",
                                        "nullable": true
                                      },
                                      "phone": {
                                        "type": "string",
                                        "nullable": true
                                      },
                                      "summary": {
                                        "type": "string",
                                        "nullable": true
                                      },
                                      "mediaId": {
                                        "type": "string",
                                        "nullable": true
                                      },
                                      "folderId": {
                                        "type": "string",
                                        "nullable": true
                                      }
                                    }
                                  },
                                  "description": "Up to 10 most recent conversations that collected data."
                                }
                              }
                            },
                            "handoffs": {
                              "type": "object",
                              "properties": {
                                "count": {
                                  "type": "integer"
                                },
                                "rate": {
                                  "type": "number",
                                  "description": "Handed off conversations divided by all conversations, from 0 to 1."
                                },
                                "reasons": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "reason": {
                                        "type": "string"
                                      },
                                      "count": {
                                        "type": "integer"
                                      }
                                    }
                                  },
                                  "description": "Up to 5 most common handoff reasons."
                                }
                              }
                            },
                            "actionItems": {
                              "type": "object",
                              "properties": {
                                "conversations": {
                                  "type": "integer"
                                },
                                "rate": {
                                  "type": "number",
                                  "description": "Conversations with action items divided by all conversations, from 0 to 1."
                                },
                                "recent": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "conversationId": {
                                        "type": "string"
                                      },
                                      "createdAt": {
                                        "type": "string"
                                      },
                                      "item": {
                                        "type": "string"
                                      }
                                    }
                                  },
                                  "description": "Up to 5 action items from the most recent conversations."
                                }
                              }
                            }
                          }
                        },
                        "quality": {
                          "type": "object",
                          "properties": {
                            "engagement": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "label": {
                                    "type": "string"
                                  },
                                  "minMessages": {
                                    "type": "integer"
                                  },
                                  "maxMessages": {
                                    "type": "integer",
                                    "nullable": true
                                  },
                                  "count": {
                                    "type": "integer"
                                  },
                                  "percentage": {
                                    "type": "integer"
                                  },
                                  "avgDurationSeconds": {
                                    "type": "number"
                                  },
                                  "sentimentBreakdown": {
                                    "type": "object",
                                    "properties": {
                                      "positive": {
                                        "type": "integer"
                                      },
                                      "neutral": {
                                        "type": "integer"
                                      },
                                      "negative": {
                                        "type": "integer"
                                      },
                                      "unanalyzed": {
                                        "type": "integer"
                                      }
                                    }
                                  }
                                }
                              },
                              "description": "Always 4 buckets, in order: Bounce (0-1 turns), Brief (2-5), Engaged (6-15), Deep (16+)."
                            },
                            "sentiment": {
                              "type": "object",
                              "properties": {
                                "positive": {
                                  "type": "integer"
                                },
                                "neutral": {
                                  "type": "integer"
                                },
                                "negative": {
                                  "type": "integer"
                                },
                                "unanalyzed": {
                                  "type": "integer"
                                }
                              }
                            },
                            "topTopics": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "topic": {
                                    "type": "string"
                                  },
                                  "count": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "description": "Up to 10 key topics, lowercased."
                            },
                            "endReasons": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "reason": {
                                    "type": "string"
                                  },
                                  "count": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "description": "Up to 10 reasons calls ended."
                            },
                            "satisfaction": {
                              "type": "object",
                              "properties": {
                                "average": {
                                  "type": "number"
                                },
                                "count": {
                                  "type": "integer"
                                }
                              },
                              "nullable": true,
                              "description": "Average post-call rating. Null when no call in the window was rated."
                            }
                          }
                        },
                        "whenAndWho": {
                          "type": "object",
                          "properties": {
                            "byHour": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "hour": {
                                    "type": "integer"
                                  },
                                  "count": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "description": "24 entries, hour 0 to 23 in the requested time zone."
                            },
                            "byWeekday": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "weekday": {
                                    "type": "integer"
                                  },
                                  "count": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "description": "7 entries, weekday 0 (Sunday) to 6 (Saturday) in the requested time zone."
                            },
                            "languages": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "language": {
                                    "type": "string"
                                  },
                                  "count": {
                                    "type": "integer"
                                  }
                                }
                              },
                              "description": "Up to 10 caller languages."
                            }
                          }
                        },
                        "channel": {
                          "type": "object",
                          "properties": {
                            "web": {
                              "type": "object",
                              "properties": {
                                "count": {
                                  "type": "integer"
                                },
                                "avgDurationSeconds": {
                                  "type": "number"
                                }
                              }
                            },
                            "phone": {
                              "type": "object",
                              "properties": {
                                "count": {
                                  "type": "integer"
                                },
                                "avgDurationSeconds": {
                                  "type": "number"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "agent-analytics": {
                    "value": {
                      "status": "success",
                      "data": {
                        "range": {
                          "start": "2026-09-01T00:00:00.000Z",
                          "end": "2026-09-30T23:59:59.999Z",
                          "tz": "America/Toronto",
                          "previousStart": "2026-08-03T00:00:00.001Z",
                          "previousEnd": "2026-09-01T00:00:00.000Z"
                        },
                        "testCalls": {
                          "count": 3,
                          "included": false
                        },
                        "overview": {
                          "kpis": {
                            "conversations": 120,
                            "completionRate": 0.85,
                            "avgDurationSeconds": 142.6,
                            "returningCallers": 14
                          },
                          "previousKpis": {
                            "conversations": 96,
                            "completionRate": 0.81,
                            "avgDurationSeconds": 131.2,
                            "returningCallers": 9
                          },
                          "overTime": [
                            {
                              "date": "2026-09-01",
                              "conversations": 5,
                              "web": 4,
                              "phone": 1
                            }
                          ]
                        },
                        "audience": {
                          "locations": [
                            {
                              "city": "Toronto",
                              "region": "Ontario",
                              "country": "Canada",
                              "count": 22
                            }
                          ],
                          "locationUnknown": 31,
                          "devices": {
                            "withDeviceData": 88,
                            "deviceTypes": {
                              "desktop": 52,
                              "mobile": 33,
                              "tablet": 3
                            },
                            "browsers": [
                              {
                                "name": "Chrome",
                                "count": 54
                              }
                            ],
                            "os": [
                              {
                                "name": "Windows",
                                "count": 40
                              }
                            ]
                          },
                          "sources": [
                            {
                              "kind": "page",
                              "label": "example.com/pricing",
                              "count": 27
                            }
                          ]
                        },
                        "attention": {
                          "notJoined": 4,
                          "unanswered": 2
                        },
                        "outcomes": {
                          "leads": {
                            "count": 36,
                            "rate": 0.3,
                            "fields": [
                              {
                                "field": "email",
                                "count": 34
                              }
                            ],
                            "latest": [
                              {
                                "conversationId": "c0ffee00-1234-4abc-9def-0123456789ab",
                                "createdAt": "2026-09-29T15:42:10.000Z",
                                "name": "Jordan Example",
                                "email": "jordan@example.com",
                                "phone": null,
                                "summary": "Asked about annual pricing and booked a demo.",
                                "mediaId": "3afc714552cd",
                                "folderId": null
                              }
                            ]
                          },
                          "handoffs": {
                            "count": 8,
                            "rate": 0.0667,
                            "reasons": [
                              {
                                "reason": "Requested a human agent",
                                "count": 5
                              }
                            ]
                          },
                          "actionItems": {
                            "conversations": 41,
                            "rate": 0.3417,
                            "recent": [
                              {
                                "conversationId": "c0ffee00-1234-4abc-9def-0123456789ab",
                                "createdAt": "2026-09-29T15:42:10.000Z",
                                "item": "Send the annual pricing sheet."
                              }
                            ]
                          }
                        },
                        "quality": {
                          "engagement": [
                            {
                              "label": "Engaged (6-15)",
                              "minMessages": 6,
                              "maxMessages": 15,
                              "count": 48,
                              "percentage": 40,
                              "avgDurationSeconds": 168.3,
                              "sentimentBreakdown": {
                                "positive": 30,
                                "neutral": 14,
                                "negative": 3,
                                "unanalyzed": 1
                              }
                            }
                          ],
                          "sentiment": {
                            "positive": 70,
                            "neutral": 38,
                            "negative": 9,
                            "unanalyzed": 3
                          },
                          "topTopics": [
                            {
                              "topic": "pricing",
                              "count": 25
                            }
                          ],
                          "endReasons": [
                            {
                              "reason": "customer-ended-call",
                              "count": 77
                            }
                          ],
                          "satisfaction": {
                            "average": 4.4,
                            "count": 52
                          }
                        },
                        "whenAndWho": {
                          "byHour": [
                            {
                              "hour": 14,
                              "count": 12
                            }
                          ],
                          "byWeekday": [
                            {
                              "weekday": 2,
                              "count": 25
                            }
                          ],
                          "languages": [
                            {
                              "language": "en",
                              "count": 104
                            }
                          ]
                        },
                        "channel": {
                          "web": {
                            "count": 98,
                            "avgDurationSeconds": 139.1
                          },
                          "phone": {
                            "count": 22,
                            "avgDurationSeconds": 158.2
                          }
                        }
                      }
                    },
                    "x-abridged": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "A query parameter failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/voice/agents/generation": {
      "post": {
        "tags": [
          "Voice Agents"
        ],
        "summary": "Create Agent From Prompt",
        "operationId": "voice-generation-create",
        "description": "### Create Agent From Prompt\n\nRequires the OWNER or ADMIN role. Prompt-first creation: creates a new agent server-side with placeholder config, then runs the same generation flow as Generate Agent Config against it. Response always includes the new agentId, plus either an agent key (generation succeeded) or needsFollowUp: true (prompt needs more detail) -- see Generate Agent Config for both shapes.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "Required. Describe the agent you want in a sentence or two."
                  },
                  "name": {
                    "type": "string"
                  },
                  "manualInstructions": {
                    "type": "string",
                    "description": "Skips the thin-prompt follow-up question and generates immediately, folding this in as additional context."
                  }
                },
                "required": [
                  "prompt"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "allOf": [
                        {
                          "type": "object",
                          "properties": {
                            "agentId": {
                              "type": "string",
                              "description": "The newly created agent's id."
                            }
                          }
                        },
                        {
                          "oneOf": [
                            {
                              "type": "object",
                              "description": "When the prompt still needs more detail after the follow-up.",
                              "properties": {
                                "needsFollowUp": {
                                  "type": "boolean",
                                  "enum": [
                                    true
                                  ]
                                },
                                "followUpQuestion": {
                                  "type": "string"
                                },
                                "extracted": {
                                  "type": "object"
                                }
                              }
                            },
                            {
                              "type": "object",
                              "description": "When generation succeeded and the agent was updated.",
                              "properties": {
                                "agent": {
                                  "type": "object",
                                  "description": "The updated agent. Full shape documented on the Voice Agents page."
                                }
                              }
                            }
                          ]
                        }
                      ]
                    }
                  }
                },
                "examples": {
                  "created": {
                    "value": {
                      "status": "success",
                      "data": {
                        "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                        "agent": {
                          "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                          "name": "Support Agent"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Generation"
      }
    },
    "/voice/agents/{agentId}/generation/generate": {
      "post": {
        "tags": [
          "Voice Agents"
        ],
        "summary": "Generate Agent Config",
        "operationId": "voice-generation-generate",
        "description": "### Generate Agent Config\n\nRequires the OWNER or ADMIN role. Runs the prompt-to-config pipeline against an existing agent: extracts a config from prompt via the LLM, and either persists it onto the agent (response has an agent key), or, when the prompt is too thin to act on and manualInstructions was not sent, returns a follow-up question instead (response has needsFollowUp: true) so you can call this again with more detail.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "Required. Describe the agent you want in a sentence or two."
                  },
                  "name": {
                    "type": "string"
                  },
                  "manualInstructions": {
                    "type": "string",
                    "description": "Skips the thin-prompt follow-up question and generates immediately, folding this in as additional context."
                  }
                },
                "required": [
                  "prompt"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "oneOf": [
                        {
                          "type": "object",
                          "description": "When the prompt still needs more detail after the follow-up.",
                          "properties": {
                            "needsFollowUp": {
                              "type": "boolean",
                              "enum": [
                                true
                              ]
                            },
                            "followUpQuestion": {
                              "type": "string"
                            },
                            "extracted": {
                              "type": "object"
                            }
                          }
                        },
                        {
                          "type": "object",
                          "description": "When generation succeeded and the agent was updated.",
                          "properties": {
                            "agent": {
                              "type": "object",
                              "description": "The updated agent. Full shape documented on the Voice Agents page."
                            }
                          }
                        }
                      ]
                    }
                  }
                },
                "examples": {
                  "generated": {
                    "value": {
                      "status": "success",
                      "data": {
                        "agent": {
                          "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                          "name": "Support Agent"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Generation"
      }
    },
    "/voice/agents/{agentId}/generation/gaps/analyze": {
      "post": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Analyze Instruction Gaps",
        "operationId": "voice-generation-gaps-analyze",
        "description": "### Analyze Instruction Gaps\n\nRequires the OWNER or ADMIN role. Advisory only -- compares the agent's current instructions against anchors/original intent/conversation summaries you supply and suggests up to 3 patches. Nothing is written; pass a suggestion's suggestedPatch to Apply Instruction Gap to actually apply it.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "anchors": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Specific requirements the instructions must cover. Defaults to empty."
                  },
                  "originalPrompt": {
                    "type": "string",
                    "description": "The original generation prompt, for context."
                  },
                  "conversationSummaries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Recent call summaries, to ground suggestions in what actually came up. Defaults to empty."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "gaps": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "description": {
                                "type": "string"
                              },
                              "suggestedPatch": {
                                "type": "string",
                                "description": "Pass this straight into Apply Instruction Gap's suggestedPatch."
                              },
                              "insertAfterSection": {
                                "type": "string",
                                "nullable": true
                              },
                              "severity": {
                                "type": "string",
                                "enum": [
                                  "low",
                                  "medium",
                                  "high"
                                ]
                              }
                            }
                          },
                          "description": "Up to 3 suggestions. Nothing is persisted by this endpoint."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "gaps": {
                    "value": {
                      "status": "success",
                      "data": {
                        "gaps": [
                          {
                            "description": "No guidance for refund requests",
                            "suggestedPatch": "If the caller asks about a refund, explain the 30-day policy and offer to transfer to billing.",
                            "insertAfterSection": null,
                            "severity": "medium"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Instruction Gaps"
      }
    },
    "/voice/agents/{agentId}/generation/gaps/apply": {
      "post": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Apply Instruction Gap",
        "operationId": "voice-generation-gaps-apply",
        "description": "### Apply Instruction Gap\n\nRequires the OWNER or ADMIN role. Inserts suggestedPatch into the agent's instructions (after insertAfterSection if given, otherwise appended) and persists the result.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "suggestedPatch": {
                    "type": "string",
                    "description": "Required. Typically taken directly from Analyze Instruction Gaps."
                  },
                  "insertAfterSection": {
                    "type": "string",
                    "nullable": true,
                    "description": "Insert after this named section heading; omit or null to append at the end."
                  }
                },
                "required": [
                  "suggestedPatch"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "instructions": {
                          "type": "string",
                          "description": "The agent's full instructions after the patch was applied."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "instructions": {
                    "value": {
                      "status": "success",
                      "data": {
                        "instructions": "You are a helpful support agent...\n\nIf the caller asks about a refund, explain the 30-day policy and offer to transfer to billing."
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "suggestedPatch is required",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "Agent not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Instruction Gaps"
      }
    },
    "/voice/knowledge-base/{agentId}/faqs/{suggestionId}/add": {
      "post": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Add FAQ To KB",
        "operationId": "voice-kb-faqs-add",
        "description": "### Add FAQ To Knowledge Base\n\nRequires the OWNER or ADMIN role. Writes the question/answer (or your override) into the agent's knowledge base as a new document, and marks the suggestion added. Fails with 409 if the suggestion was already added or dismissed, or if the agent has no knowledge base collection to write into.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "suggestionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The FAQ suggestion's suggestionId."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "question": {
                    "type": "string",
                    "description": "Overrides the suggested question. Optional."
                  },
                  "answer": {
                    "type": "string",
                    "description": "Overrides the suggested answer. Optional."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "message": {
                    "value": {
                      "status": "success",
                      "message": "Added to knowledge base"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "FAQ not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "FAQ not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "conflict": {
                    "value": {
                      "status": "failed",
                      "message": "FAQ already resolved"
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "FAQs"
      }
    },
    "/voice/knowledge-base/{agentId}/faqs/{suggestionId}": {
      "put": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Update FAQ Suggestion",
        "operationId": "voice-kb-faqs-update",
        "description": "### Update FAQ Suggestion\n\nRequires the OWNER or ADMIN role. Edits a still-pending suggestion's question and/or answer before adding it. Fails with 400 if the suggestion was already added or dismissed.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "suggestionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The FAQ suggestion's suggestionId."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "question": {
                    "type": "string",
                    "description": "Overrides the suggested question. Optional."
                  },
                  "answer": {
                    "type": "string",
                    "description": "Overrides the suggested answer. Optional."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "message": {
                    "value": {
                      "status": "success",
                      "message": "FAQ updated"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Cannot edit a resolved FAQ",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "FAQ not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "FAQ not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "FAQs"
      },
      "delete": {
        "tags": [
          "Voice Agent Intelligence"
        ],
        "summary": "Dismiss FAQ Suggestion",
        "operationId": "voice-kb-faqs-dismiss",
        "description": "### Dismiss FAQ Suggestion\n\nRequires the OWNER or ADMIN role. Marks the suggestion dismissed without writing anything to the knowledge base.",
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "suggestionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The FAQ suggestion's suggestionId."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "message": {
                    "value": {
                      "status": "success",
                      "message": "FAQ dismissed"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller's role is not OWNER or ADMIN",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to manage agents"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "FAQ not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    },
                    "code": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "value": {
                      "status": "failed",
                      "code": 404,
                      "message": "FAQ not found",
                      "hints": []
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "FAQs"
      }
    },
    "/knowledge-bases": {
      "post": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "Create Knowledge Base Collection",
        "operationId": "knowledge-bases-create",
        "description": "### Create Collection\n\nRequires the OWNER or ADMIN role. Creates an empty document collection. Add documents to it with the manual-document endpoint, then attach it to a folder or agent with the map endpoint so something actually uses it.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Up to 200 characters. Required."
                  },
                  "description": {
                    "type": "string",
                    "description": "Up to 1000 characters. Optional."
                  }
                },
                "required": [
                  "name"
                ]
              },
              "examples": {
                "Example": {
                  "value": {
                    "name": "Product documentation",
                    "description": "Public docs and FAQs."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "knowledgeBaseId": {
                          "type": "string",
                          "description": "Server-generated. Immutable. The identifier used everywhere for this collection."
                        },
                        "name": {
                          "type": "string",
                          "description": "Up to 200 characters."
                        },
                        "description": {
                          "type": "string",
                          "nullable": true,
                          "description": "Up to 1000 characters."
                        },
                        "documents": {
                          "type": "object",
                          "properties": {
                            "embeddingStatus": {
                              "type": "string",
                              "enum": [
                                "pending",
                                "processing",
                                "completed",
                                "failed"
                              ]
                            },
                            "lastIndexedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "You do not have permission to manage knowledge bases"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Collections"
      },
      "get": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "List Knowledge Base Collections",
        "operationId": "knowledge-bases-list",
        "description": "### List Collections\n\nLists every collection in your company, newest first. Each item is enriched with documentCount and a rolled-up status the single-collection Get endpoint does not return.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "knowledgeBaseId": {
                            "type": "string",
                            "description": "Server-generated. Immutable. The identifier used everywhere for this collection."
                          },
                          "name": {
                            "type": "string",
                            "description": "Up to 200 characters."
                          },
                          "description": {
                            "type": "string",
                            "nullable": true,
                            "description": "Up to 1000 characters."
                          },
                          "documents": {
                            "type": "object",
                            "properties": {
                              "embeddingStatus": {
                                "type": "string",
                                "enum": [
                                  "pending",
                                  "processing",
                                  "completed",
                                  "failed"
                                ]
                              },
                              "lastIndexedAt": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              }
                            }
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "documentCount": {
                            "type": "number",
                            "description": "Only present in the list response, not on a single collection fetched by id."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "empty",
                              "processing",
                              "ready",
                              "failed"
                            ],
                            "description": "Rolled up from this collection's documents. Only present in the list response. Distinct from documents.embeddingStatus, which is a stored field on the collection itself."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Collections"
      }
    },
    "/knowledge-bases/{kbId}": {
      "get": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "Get Knowledge Base Collection",
        "operationId": "knowledge-bases-get",
        "description": "### Get Collection\n\nFetches one collection by id, company-scoped. Does not include documentCount or status -- those are only on the list response.",
        "parameters": [
          {
            "name": "kbId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The collection's knowledgeBaseId."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "knowledgeBaseId": {
                          "type": "string",
                          "description": "Server-generated. Immutable. The identifier used everywhere for this collection."
                        },
                        "name": {
                          "type": "string",
                          "description": "Up to 200 characters."
                        },
                        "description": {
                          "type": "string",
                          "nullable": true,
                          "description": "Up to 1000 characters."
                        },
                        "documents": {
                          "type": "object",
                          "properties": {
                            "embeddingStatus": {
                              "type": "string",
                              "enum": [
                                "pending",
                                "processing",
                                "completed",
                                "failed"
                              ]
                            },
                            "lastIndexedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "Knowledge base not found"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Collections"
      },
      "patch": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "Update Knowledge Base Collection",
        "operationId": "knowledge-bases-update",
        "description": "### Update Collection\n\nRequires the OWNER or ADMIN role. Partial update: send only the fields to change. At least one of name or description is required.",
        "parameters": [
          {
            "name": "kbId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The collection's knowledgeBaseId."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Up to 200 characters."
                  },
                  "description": {
                    "type": "string",
                    "description": "Up to 1000 characters."
                  }
                }
              },
              "examples": {
                "Example": {
                  "value": {
                    "name": "Product documentation (2026)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "knowledgeBaseId": {
                          "type": "string",
                          "description": "Server-generated. Immutable. The identifier used everywhere for this collection."
                        },
                        "name": {
                          "type": "string",
                          "description": "Up to 200 characters."
                        },
                        "description": {
                          "type": "string",
                          "nullable": true,
                          "description": "Up to 1000 characters."
                        },
                        "documents": {
                          "type": "object",
                          "properties": {
                            "embeddingStatus": {
                              "type": "string",
                              "enum": [
                                "pending",
                                "processing",
                                "completed",
                                "failed"
                              ]
                            },
                            "lastIndexedAt": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "You do not have permission to manage knowledge bases"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "Knowledge base not found"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Collections"
      },
      "delete": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "Delete Knowledge Base Collection",
        "operationId": "knowledge-bases-delete",
        "description": "### Delete Collection\n\nRequires the OWNER or ADMIN role. Deletes the collection, every document in it, their embeddings, and every mapping row pointing at it. An automation step that still names this collection is not touched -- it starts failing to retrieve rather than being silently unlinked.",
        "parameters": [
          {
            "name": "kbId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The collection's knowledgeBaseId."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "knowledgeBaseId": {
                          "type": "string"
                        },
                        "deleted": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "You do not have permission to manage knowledge bases"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "Knowledge base not found"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Collections"
      }
    },
    "/knowledge-bases/{kbId}/documents": {
      "get": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "List Knowledge Base Documents",
        "operationId": "knowledge-bases-documents-list",
        "description": "### List Documents\n\nLists every document in the collection, newest first. Each item's full text is not included -- fetch it separately from Get Document Text.",
        "parameters": [
          {
            "name": "kbId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The collection's knowledgeBaseId."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "documentId": {
                            "type": "string",
                            "description": "Server-generated. Immutable."
                          },
                          "knowledgeBaseId": {
                            "type": "string"
                          },
                          "source": {
                            "type": "string",
                            "enum": [
                              "upload",
                              "website",
                              "manual"
                            ],
                            "description": "This endpoint set only creates manual documents; upload and website documents come from endpoints not covered here."
                          },
                          "title": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string",
                            "nullable": true
                          },
                          "fileName": {
                            "type": "string",
                            "nullable": true,
                            "description": "Set only for an uploaded file."
                          },
                          "mimeType": {
                            "type": "string",
                            "nullable": true
                          },
                          "sizeBytes": {
                            "type": "number"
                          },
                          "sourceUrl": {
                            "type": "string",
                            "nullable": true,
                            "description": "Set only for a website document."
                          },
                          "pageUrl": {
                            "type": "string",
                            "nullable": true,
                            "description": "Set only for a website document."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "uploaded",
                              "parsing",
                              "parsed",
                              "embedding",
                              "ready",
                              "failed"
                            ]
                          },
                          "error": {
                            "type": "string",
                            "nullable": true
                          },
                          "parse": {
                            "type": "object",
                            "nullable": true,
                            "properties": {
                              "engine": {
                                "type": "string"
                              },
                              "pages": {
                                "type": "number"
                              },
                              "costUsd": {
                                "type": "number"
                              },
                              "parsedAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "Knowledge base not found"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Documents"
      }
    },
    "/knowledge-bases/{kbId}/documents/manual": {
      "post": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "Add Knowledge Base Text Document",
        "operationId": "knowledge-bases-documents-create-manual",
        "description": "### Add a Text Document\n\nRequires the OWNER or ADMIN role. Adds a document with text you supply directly -- the only way this endpoint set creates a document (uploading a file or crawling a website use endpoints not covered here). Kicks off embedding immediately; status starts at uploaded and moves toward ready on its own.",
        "parameters": [
          {
            "name": "kbId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The collection's knowledgeBaseId."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "description": "Up to 200 characters. Required."
                  },
                  "text": {
                    "type": "string",
                    "description": "Required, non-empty. Size-capped server-side; an oversized submission is a 400 asking you to split it into smaller entries."
                  }
                },
                "required": [
                  "title",
                  "text"
                ]
              },
              "examples": {
                "Example": {
                  "value": {
                    "title": "Refund policy",
                    "text": "Refunds are issued within 14 days of purchase..."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "documentId": {
                          "type": "string",
                          "description": "Server-generated. Immutable."
                        },
                        "knowledgeBaseId": {
                          "type": "string"
                        },
                        "source": {
                          "type": "string",
                          "enum": [
                            "upload",
                            "website",
                            "manual"
                          ],
                          "description": "This endpoint set only creates manual documents; upload and website documents come from endpoints not covered here."
                        },
                        "title": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "fileName": {
                          "type": "string",
                          "nullable": true,
                          "description": "Set only for an uploaded file."
                        },
                        "mimeType": {
                          "type": "string",
                          "nullable": true
                        },
                        "sizeBytes": {
                          "type": "number"
                        },
                        "sourceUrl": {
                          "type": "string",
                          "nullable": true,
                          "description": "Set only for a website document."
                        },
                        "pageUrl": {
                          "type": "string",
                          "nullable": true,
                          "description": "Set only for a website document."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "uploaded",
                            "parsing",
                            "parsed",
                            "embedding",
                            "ready",
                            "failed"
                          ]
                        },
                        "error": {
                          "type": "string",
                          "nullable": true
                        },
                        "parse": {
                          "type": "object",
                          "nullable": true,
                          "properties": {
                            "engine": {
                              "type": "string"
                            },
                            "pages": {
                              "type": "number"
                            },
                            "costUsd": {
                              "type": "number"
                            },
                            "parsedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "You do not have permission to manage knowledge bases"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "Knowledge base not found"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Documents"
      }
    },
    "/knowledge-bases/{kbId}/documents/{docId}": {
      "patch": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "Update Knowledge Base Document",
        "operationId": "knowledge-bases-documents-update",
        "description": "### Update Document\n\nRequires the OWNER or ADMIN role. Renames the document's title and/or description -- the only fields this endpoint can change, at any status. A title change also propagates to that document's stored chunk metadata so retrieval citations pick it up immediately.",
        "parameters": [
          {
            "name": "kbId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The collection's knowledgeBaseId."
          },
          {
            "name": "docId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The document's documentId."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "description": "Cannot be sent as an empty string."
                  },
                  "description": {
                    "type": "string"
                  }
                }
              },
              "examples": {
                "Example": {
                  "value": {
                    "title": "Refund policy (updated)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "documentId": {
                          "type": "string",
                          "description": "Server-generated. Immutable."
                        },
                        "knowledgeBaseId": {
                          "type": "string"
                        },
                        "source": {
                          "type": "string",
                          "enum": [
                            "upload",
                            "website",
                            "manual"
                          ],
                          "description": "This endpoint set only creates manual documents; upload and website documents come from endpoints not covered here."
                        },
                        "title": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "fileName": {
                          "type": "string",
                          "nullable": true,
                          "description": "Set only for an uploaded file."
                        },
                        "mimeType": {
                          "type": "string",
                          "nullable": true
                        },
                        "sizeBytes": {
                          "type": "number"
                        },
                        "sourceUrl": {
                          "type": "string",
                          "nullable": true,
                          "description": "Set only for a website document."
                        },
                        "pageUrl": {
                          "type": "string",
                          "nullable": true,
                          "description": "Set only for a website document."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "uploaded",
                            "parsing",
                            "parsed",
                            "embedding",
                            "ready",
                            "failed"
                          ]
                        },
                        "error": {
                          "type": "string",
                          "nullable": true
                        },
                        "parse": {
                          "type": "object",
                          "nullable": true,
                          "properties": {
                            "engine": {
                              "type": "string"
                            },
                            "pages": {
                              "type": "number"
                            },
                            "costUsd": {
                              "type": "number"
                            },
                            "parsedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "You do not have permission to manage knowledge bases"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "Document not found"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Documents"
      },
      "delete": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "Delete Knowledge Base Document",
        "operationId": "knowledge-bases-documents-delete",
        "description": "### Delete Document\n\nRequires the OWNER or ADMIN role. Deletes the document and its embeddings. Looked up by documentId and your company alone -- the kbId in the path is not cross-checked against the document's own collection, so this succeeds even if docId actually belongs to a different one of your collections.",
        "parameters": [
          {
            "name": "kbId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The collection's knowledgeBaseId."
          },
          {
            "name": "docId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The document's documentId."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "documentId": {
                          "type": "string"
                        },
                        "deleted": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "You do not have permission to manage knowledge bases"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "Document not found"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Documents"
      }
    },
    "/knowledge-bases/{kbId}/documents/{docId}/text": {
      "get": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "Get Knowledge Base Document Text",
        "operationId": "knowledge-bases-documents-text",
        "description": "### Get Document Text\n\nFetches the extracted text of one document, company-scoped. A document that has not finished parsing yet is not an error: available is false, text is an empty string, and status shows the document's current state.",
        "parameters": [
          {
            "name": "kbId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The collection's knowledgeBaseId."
          },
          {
            "name": "docId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The document's documentId."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "documentId": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "uploaded",
                            "parsing",
                            "parsed",
                            "embedding",
                            "ready",
                            "failed"
                          ]
                        },
                        "available": {
                          "type": "boolean",
                          "description": "True once text.length > 0."
                        },
                        "text": {
                          "type": "string"
                        },
                        "length": {
                          "type": "number",
                          "description": "Character count, not bytes."
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "Document not found"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Documents"
      }
    },
    "/knowledge-bases/{kbId}/map": {
      "post": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "Map Knowledge Base Collection",
        "operationId": "knowledge-bases-map",
        "description": "### Attach a Collection\n\nRequires the OWNER or ADMIN role. Attaches this collection to a folder or agent, so retrieval actually uses it -- a collection with no mapping is created but inert. Idempotent: mapping the same (collection, owner) pair again returns the existing row rather than erroring. ownerType cannot be automation here -- an automation's collection is set on its own AI step, not through this endpoint; see Get Collection Owners for how that link is surfaced instead.",
        "parameters": [
          {
            "name": "kbId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The collection's knowledgeBaseId."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ownerType": {
                    "type": "string",
                    "enum": [
                      "folder",
                      "agent"
                    ]
                  },
                  "ownerId": {
                    "type": "string"
                  }
                },
                "required": [
                  "ownerType",
                  "ownerId"
                ]
              },
              "examples": {
                "Example": {
                  "value": {
                    "ownerType": "folder",
                    "ownerId": "f_8a2c1e"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "knowledgeBaseId": {
                          "type": "string"
                        },
                        "ownerType": {
                          "type": "string",
                          "enum": [
                            "folder",
                            "agent"
                          ],
                          "description": "Never automation here: an automation's collection lives on its own AI step, not a mapping row -- see GET .../owners for how an automation link is surfaced instead."
                        },
                        "ownerId": {
                          "type": "string"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "You do not have permission to manage knowledge bases"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "Knowledge base not found"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Owner mapping"
      },
      "delete": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "Unmap Knowledge Base Collection",
        "operationId": "knowledge-bases-unmap",
        "description": "### Detach a Collection\n\nRequires the OWNER or ADMIN role. Removes one mapping row. ownerType and ownerId are sent as query parameters on this DELETE, not a request body.",
        "parameters": [
          {
            "name": "kbId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The collection's knowledgeBaseId."
          },
          {
            "name": "ownerType",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "folder",
                "agent"
              ]
            }
          },
          {
            "name": "ownerId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "knowledgeBaseId": {
                          "type": "string"
                        },
                        "ownerType": {
                          "type": "string"
                        },
                        "ownerId": {
                          "type": "string"
                        },
                        "unmapped": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "You do not have permission to manage knowledge bases"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "Mapping not found"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Owner mapping"
      }
    },
    "/knowledge-bases/{kbId}/owners": {
      "get": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "List Knowledge Base Collection Owners",
        "operationId": "knowledge-bases-owners-list",
        "description": "### List Collection Owners\n\nEverything this collection is attached to: folder and agent mappings from the map endpoint, plus every automation whose AI step names this collection directly (automations are never in the mapping table -- their link is read live from the automation's own steps, so it can't go stale).",
        "parameters": [
          {
            "name": "kbId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The collection's knowledgeBaseId."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "knowledgeBaseId": {
                            "type": "string"
                          },
                          "ownerType": {
                            "type": "string",
                            "enum": [
                              "folder",
                              "agent",
                              "automation"
                            ]
                          },
                          "ownerId": {
                            "type": "string"
                          },
                          "ownerName": {
                            "type": "string",
                            "description": "Only present when ownerType is automation -- the automation's name, looked up live from its own record, not stored on a mapping row."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "enum": [
                        "Knowledge base not found"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Owner mapping"
      }
    },
    "/knowledge-bases/owners/{ownerType}/{ownerId}/collections": {
      "get": {
        "tags": [
          "Knowledge Base"
        ],
        "summary": "List Collections for an Owner",
        "operationId": "knowledge-bases-owner-collections-list",
        "description": "### List an Owner's Collections\n\nReverse lookup: every collection mapped to a given folder or agent. Only covers real mapping rows, so an automation's collection (which is never mapped, only referenced from its own AI step) will not appear here even though it shows up in that collection's own Get Collection Owners response.",
        "parameters": [
          {
            "name": "ownerType",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "folder",
                "agent"
              ]
            }
          },
          {
            "name": "ownerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The folder or agent id."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "knowledgeBaseId": {
                            "type": "string",
                            "description": "Server-generated. Immutable. The identifier used everywhere for this collection."
                          },
                          "name": {
                            "type": "string",
                            "description": "Up to 200 characters."
                          },
                          "description": {
                            "type": "string",
                            "nullable": true,
                            "description": "Up to 1000 characters."
                          },
                          "documents": {
                            "type": "object",
                            "properties": {
                              "embeddingStatus": {
                                "type": "string",
                                "enum": [
                                  "pending",
                                  "processing",
                                  "completed",
                                  "failed"
                                ]
                              },
                              "lastIndexedAt": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true
                              }
                            }
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-doc-group": "Owner mapping"
      }
    },
    "/labels": {
      "get": {
        "tags": [
          "Labels"
        ],
        "summary": "List labels",
        "operationId": "labels-list",
        "description": "Returns your company's labels as a tree: groups and ungrouped labels at the top level, each group carrying the labels inside it. Items are ordered by `sortOrder`, then by name. Groups go one level deep.\n\nNo labels permission is needed: anyone on the team can read the list.\n\n#### Filtering\n\n- `status` picks active labels (the default), archived ones, or both.\n- `search` matches names, ignoring case. A group is listed when its own name matches or when any of its labels match; it then carries only the matching labels.\n\n#### Usage counts\n\n`usageCount` counts labelled passages only on media you can open, so it never reveals anything about files in folders you cannot access. Owners and members with **Access all** on folders see company-wide counts.",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Which labels to return. Leave it out for `active`. One of: `active`, `archived`, `all`.",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "archived",
                "all"
              ]
            },
            "example": "active"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Text to match against label and group names, ignoring case. Trimmed, up to 80 characters. An empty value returns everything.",
            "schema": {
              "type": "string",
              "maxLength": 80
            },
            "example": "action"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "labels": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "labelId": {
                                "type": "string",
                                "description": "Id of the label or group."
                              },
                              "isGroup": {
                                "type": "boolean",
                                "description": "`true` for a group. A group holds labels and cannot be applied to a transcript."
                              },
                              "name": {
                                "type": "string",
                                "description": "Name."
                              },
                              "description": {
                                "type": "string",
                                "description": "Description. Left out when none was set."
                              },
                              "color": {
                                "type": "string",
                                "description": "`#rrggbb` in lower case. Groups have none."
                              },
                              "parentId": {
                                "type": "string",
                                "description": "`labelId` of the group this label sits in, or `null` at the top level.",
                                "nullable": true
                              },
                              "source": {
                                "type": "string",
                                "description": "`speak` for labels added from a Speak label set, `user` for everything else.",
                                "enum": [
                                  "user",
                                  "speak"
                                ]
                              },
                              "isActive": {
                                "type": "boolean",
                                "description": "`false` once archived."
                              },
                              "mergedInto": {
                                "type": "string",
                                "description": "`labelId` this label was merged into. Present only on merged labels."
                              },
                              "sortOrder": {
                                "type": "integer",
                                "description": "Position among its siblings."
                              },
                              "userId": {
                                "type": "string",
                                "description": "Id of the person who created it."
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "When it was created.",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "description": "When it last changed.",
                                "format": "date-time"
                              },
                              "usageCount": {
                                "type": "integer",
                                "description": "How many labelled passages use it, counted only on media you can open. For a group, the sum over its listed labels."
                              },
                              "labels": {
                                "type": "array",
                                "description": "Groups only: the labels in the group that match the filter, with the same fields.",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "labelId": {
                                      "type": "string",
                                      "description": "Id of the label or group."
                                    },
                                    "isGroup": {
                                      "type": "boolean",
                                      "description": "`true` for a group. A group holds labels and cannot be applied to a transcript."
                                    },
                                    "name": {
                                      "type": "string",
                                      "description": "Name."
                                    },
                                    "description": {
                                      "type": "string",
                                      "description": "Description. Left out when none was set."
                                    },
                                    "color": {
                                      "type": "string",
                                      "description": "`#rrggbb` in lower case. Groups have none."
                                    },
                                    "parentId": {
                                      "type": "string",
                                      "description": "`labelId` of the group this label sits in, or `null` at the top level.",
                                      "nullable": true
                                    },
                                    "source": {
                                      "type": "string",
                                      "description": "`speak` for labels added from a Speak label set, `user` for everything else.",
                                      "enum": [
                                        "user",
                                        "speak"
                                      ]
                                    },
                                    "isActive": {
                                      "type": "boolean",
                                      "description": "`false` once archived."
                                    },
                                    "mergedInto": {
                                      "type": "string",
                                      "description": "`labelId` this label was merged into. Present only on merged labels."
                                    },
                                    "sortOrder": {
                                      "type": "integer",
                                      "description": "Position among its siblings."
                                    },
                                    "userId": {
                                      "type": "string",
                                      "description": "Id of the person who created it."
                                    },
                                    "createdAt": {
                                      "type": "string",
                                      "description": "When it was created.",
                                      "format": "date-time"
                                    },
                                    "updatedAt": {
                                      "type": "string",
                                      "description": "When it last changed.",
                                      "format": "date-time"
                                    },
                                    "usageCount": {
                                      "type": "integer",
                                      "description": "How many labelled passages use it, counted only on media you can open. For a group, the sum over its listed labels."
                                    }
                                  }
                                }
                              }
                            }
                          },
                          "description": "Top-level groups and ungrouped labels."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "labels": [
                          {
                            "labelId": "Gx7QkP2mVt9LwRz",
                            "isGroup": true,
                            "name": "Meetings",
                            "parentId": null,
                            "source": "speak",
                            "isActive": true,
                            "sortOrder": 0,
                            "userId": "65f0c1a2b3c4d5e6f7a8b9c0",
                            "createdAt": "2026-10-06T14:05:12.000Z",
                            "updatedAt": "2026-10-06T14:05:12.000Z",
                            "usageCount": 12,
                            "labels": [
                              {
                                "labelId": "Lb3NcY8sDf4HqPe",
                                "isGroup": false,
                                "name": "Action item",
                                "description": "Something a person agreed to do.",
                                "color": "#6366f1",
                                "parentId": "Gx7QkP2mVt9LwRz",
                                "source": "speak",
                                "isActive": true,
                                "sortOrder": 0,
                                "userId": "65f0c1a2b3c4d5e6f7a8b9c0",
                                "createdAt": "2026-10-06T14:05:12.000Z",
                                "updatedAt": "2026-10-06T14:05:12.000Z",
                                "usageCount": 12
                              }
                            ]
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A query value failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "A query value failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "\"status\" must be one of [active, archived, all]",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Label list"
      },
      "post": {
        "tags": [
          "Labels"
        ],
        "summary": "Create a label or group",
        "operationId": "labels-create",
        "description": "Requires the **Labels: Create** permission (on by default for admins and members).\n\n#### Request rules\n\n- Send `isGroup: true` to create a group. A group cannot have `color` or `parentId`; sending either returns 400.\n- `parentId` must be the `labelId` of an active group in your company. A missing group returns 404 \"Parent group not found.\"; a label that is not a group returns 400 \"A label can only be placed inside a group.\"\n- `color` defaults to `#6366f1` when you leave it out.\n- `sortOrder` defaults to 0.\n\n#### Errors\n\n- `400` when a field fails validation or the parent is not a group.\n- `403` without the permission.\n- `404` when the parent group does not exist.\n- `409` when an active label with the same name already exists under the same parent. Names are compared ignoring case, after trimming and collapsing spaces.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name of the label or group. Trimmed, then 1 to 80 characters. Repeated spaces are collapsed to one before saving. Names are unique among active labels with the same parent, compared without regard to case, so a duplicate returns 409.",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "isGroup": {
                    "type": "boolean",
                    "description": "`true` to create a group instead of a label. Defaults to `false`."
                  },
                  "description": {
                    "type": "string",
                    "description": "What the label means, shown to people choosing it. Up to 500 characters after trimming. An empty string is accepted.",
                    "maxLength": 500
                  },
                  "color": {
                    "type": "string",
                    "description": "Colour as six-digit hex, `#rrggbb` (pattern `^#[0-9a-fA-F]{6}$`). Stored in lower case. Not allowed on a group.",
                    "pattern": "^#[0-9a-fA-F]{6}$",
                    "example": "#22c55e"
                  },
                  "parentId": {
                    "type": "string",
                    "description": "`labelId` of the group to put the label in. `null` or left out for the top level. Not allowed on a group. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
                    "nullable": true,
                    "pattern": "^[A-Za-z0-9_-]{1,64}$"
                  },
                  "sortOrder": {
                    "type": "integer",
                    "description": "Position among its siblings, lowest first. Integer from 0 to 1,000,000. Labels with the same value are ordered by name.",
                    "minimum": 0,
                    "maximum": 1000000
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "Action item",
                "description": "Something a person agreed to do.",
                "color": "#6366f1",
                "parentId": "Gx7QkP2mVt9LwRz"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "labelId": {
                          "type": "string",
                          "description": "Id of the label or group."
                        },
                        "isGroup": {
                          "type": "boolean",
                          "description": "`true` for a group. A group holds labels and cannot be applied to a transcript."
                        },
                        "name": {
                          "type": "string",
                          "description": "Name."
                        },
                        "description": {
                          "type": "string",
                          "description": "Description. Left out when none was set."
                        },
                        "color": {
                          "type": "string",
                          "description": "`#rrggbb` in lower case. Groups have none."
                        },
                        "parentId": {
                          "type": "string",
                          "description": "`labelId` of the group this label sits in, or `null` at the top level.",
                          "nullable": true
                        },
                        "source": {
                          "type": "string",
                          "description": "`speak` for labels added from a Speak label set, `user` for everything else.",
                          "enum": [
                            "user",
                            "speak"
                          ]
                        },
                        "isActive": {
                          "type": "boolean",
                          "description": "`false` once archived."
                        },
                        "mergedInto": {
                          "type": "string",
                          "description": "`labelId` this label was merged into. Present only on merged labels."
                        },
                        "sortOrder": {
                          "type": "integer",
                          "description": "Position among its siblings."
                        },
                        "userId": {
                          "type": "string",
                          "description": "Id of the person who created it."
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "When it was created.",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "When it last changed.",
                          "format": "date-time"
                        }
                      },
                      "description": "A label or group."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "labelId": "Lb3NcY8sDf4HqPe",
                        "isGroup": false,
                        "name": "Action item",
                        "description": "Something a person agreed to do.",
                        "color": "#6366f1",
                        "parentId": "Gx7QkP2mVt9LwRz",
                        "source": "user",
                        "isActive": true,
                        "sortOrder": 0,
                        "userId": "65f0c1a2b3c4d5e6f7a8b9c0",
                        "createdAt": "2026-10-06T14:05:12.000Z",
                        "updatedAt": "2026-10-06T14:05:12.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "The request failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "\"name\" length must be less than or equal to 80 characters long",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "You lack the Labels: Create permission",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "Why the request was refused."
                    }
                  }
                },
                "examples": {
                  "error-403": {
                    "summary": "You lack the Labels: Create permission",
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to perform this action"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The parent group does not exist",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "The parent group does not exist",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Parent group not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "An active label with this name already exists under the same parent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-409": {
                    "summary": "An active label with this name already exists under the same parent",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 409,
                      "message": "A label with this name already exists here.",
                      "hints": [
                        "Please use PUT for update instead of POST",
                        "The requested operation failed because it tried to create a resource that already exists."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Label list"
      }
    },
    "/labels/speak-sets": {
      "post": {
        "tags": [
          "Labels"
        ],
        "summary": "Add Speak label sets",
        "operationId": "labels-add-speak-sets",
        "description": "Adds ready-made sets of labels, each as a group with `source: \"speak\"`. Requires the **Labels: Create** permission.\n\n| Set | Group | Labels |\n| --- | --- | --- |\n| `sales_qa` | Sales QA | Unprofessional, Slang, Objection, Great moment, Compliance risk |\n| `research` | Research | Pain point, Motivation, Quote for report, Surprise, Follow-up |\n| `meetings` | Meetings | Decision, Action item, Risk, Open question |\n| `transcript_feedback` | Transcript feedback | Wrong split, Misheard word, Wrong speaker, Bad translation |\n\nSafe to repeat: an active group or label with the same name is reused rather than duplicated, so `createdCount` counts only what is new. A set whose group name is already used by a plain top-level label is skipped and listed in `skippedSets`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sets": {
                    "type": "array",
                    "minItems": 1,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "enum": [
                        "sales_qa",
                        "research",
                        "meetings",
                        "transcript_feedback"
                      ]
                    },
                    "description": "The sets to add. At least one, no repeats."
                  }
                },
                "required": [
                  "sets"
                ]
              },
              "example": {
                "sets": [
                  "meetings"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "groups": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "labelId": {
                                "type": "string",
                                "description": "Id of the label or group."
                              },
                              "isGroup": {
                                "type": "boolean",
                                "description": "`true` for a group. A group holds labels and cannot be applied to a transcript."
                              },
                              "name": {
                                "type": "string",
                                "description": "Name."
                              },
                              "description": {
                                "type": "string",
                                "description": "Description. Left out when none was set."
                              },
                              "color": {
                                "type": "string",
                                "description": "`#rrggbb` in lower case. Groups have none."
                              },
                              "parentId": {
                                "type": "string",
                                "description": "`labelId` of the group this label sits in, or `null` at the top level.",
                                "nullable": true
                              },
                              "source": {
                                "type": "string",
                                "description": "`speak` for labels added from a Speak label set, `user` for everything else.",
                                "enum": [
                                  "user",
                                  "speak"
                                ]
                              },
                              "isActive": {
                                "type": "boolean",
                                "description": "`false` once archived."
                              },
                              "mergedInto": {
                                "type": "string",
                                "description": "`labelId` this label was merged into. Present only on merged labels."
                              },
                              "sortOrder": {
                                "type": "integer",
                                "description": "Position among its siblings."
                              },
                              "userId": {
                                "type": "string",
                                "description": "Id of the person who created it."
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "When it was created.",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "description": "When it last changed.",
                                "format": "date-time"
                              }
                            },
                            "description": "A label or group."
                          },
                          "description": "The group for each set that was added or already there."
                        },
                        "createdCount": {
                          "type": "integer",
                          "description": "How many groups and labels were created by this request."
                        },
                        "skippedSets": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Sets skipped because a plain label already uses the group name."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "groups": [
                          {
                            "labelId": "Gx7QkP2mVt9LwRz",
                            "isGroup": true,
                            "name": "Meetings",
                            "parentId": null,
                            "source": "speak",
                            "isActive": true,
                            "sortOrder": 0,
                            "userId": "65f0c1a2b3c4d5e6f7a8b9c0",
                            "createdAt": "2026-10-06T14:05:12.000Z",
                            "updatedAt": "2026-10-06T14:05:12.000Z"
                          }
                        ],
                        "createdCount": 5,
                        "skippedSets": []
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "The request failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "\"sets\" must contain at least 1 items",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "You lack the Labels: Create permission",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "Why the request was refused."
                    }
                  }
                },
                "examples": {
                  "error-403": {
                    "summary": "You lack the Labels: Create permission",
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to perform this action"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Label list"
      }
    },
    "/labels/{labelId}": {
      "put": {
        "tags": [
          "Labels"
        ],
        "summary": "Update a label or group",
        "operationId": "labels-update",
        "description": "Requires the **Labels: Update** permission (on by default for admins and members). Send at least one field; an empty body returns 400. Only the fields you send change.\n\n#### Request rules\n\n- An archived label cannot be edited: restore it first (400 \"Restore this label before editing it.\").\n- A group has no colour and cannot be placed inside another group (400).\n- `parentId` moves a label into a group; `null` moves it to the top level. A label cannot be its own group (400).\n\n#### Errors\n\n- `400` for the rules above or a field that fails validation.\n- `403` without the permission.\n- `404` when the label or the new parent group does not exist.\n- `409` when the new name is already used by an active label under the same parent.",
        "parameters": [
          {
            "name": "labelId",
            "in": "path",
            "required": true,
            "description": "Id of the label or group. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "Lb3NcY8sDf4HqPe"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name of the label or group. Trimmed, then 1 to 80 characters. Repeated spaces are collapsed to one before saving. Names are unique among active labels with the same parent, compared without regard to case, so a duplicate returns 409.",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "description": {
                    "type": "string",
                    "description": "What the label means, shown to people choosing it. Up to 500 characters after trimming. An empty string is accepted.",
                    "maxLength": 500
                  },
                  "color": {
                    "type": "string",
                    "description": "Colour as six-digit hex, `#rrggbb` (pattern `^#[0-9a-fA-F]{6}$`). Stored in lower case. Not allowed on a group.",
                    "pattern": "^#[0-9a-fA-F]{6}$",
                    "example": "#22c55e"
                  },
                  "parentId": {
                    "type": "string",
                    "description": "`labelId` of a group to move the label into, or `null` to move it to the top level. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
                    "nullable": true,
                    "pattern": "^[A-Za-z0-9_-]{1,64}$"
                  },
                  "sortOrder": {
                    "type": "integer",
                    "description": "Position among its siblings, lowest first. Integer from 0 to 1,000,000. Labels with the same value are ordered by name.",
                    "minimum": 0,
                    "maximum": 1000000
                  }
                },
                "minProperties": 1
              },
              "example": {
                "name": "Next step"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "labelId": {
                          "type": "string",
                          "description": "Id of the label or group."
                        },
                        "isGroup": {
                          "type": "boolean",
                          "description": "`true` for a group. A group holds labels and cannot be applied to a transcript."
                        },
                        "name": {
                          "type": "string",
                          "description": "Name."
                        },
                        "description": {
                          "type": "string",
                          "description": "Description. Left out when none was set."
                        },
                        "color": {
                          "type": "string",
                          "description": "`#rrggbb` in lower case. Groups have none."
                        },
                        "parentId": {
                          "type": "string",
                          "description": "`labelId` of the group this label sits in, or `null` at the top level.",
                          "nullable": true
                        },
                        "source": {
                          "type": "string",
                          "description": "`speak` for labels added from a Speak label set, `user` for everything else.",
                          "enum": [
                            "user",
                            "speak"
                          ]
                        },
                        "isActive": {
                          "type": "boolean",
                          "description": "`false` once archived."
                        },
                        "mergedInto": {
                          "type": "string",
                          "description": "`labelId` this label was merged into. Present only on merged labels."
                        },
                        "sortOrder": {
                          "type": "integer",
                          "description": "Position among its siblings."
                        },
                        "userId": {
                          "type": "string",
                          "description": "Id of the person who created it."
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "When it was created.",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "When it last changed.",
                          "format": "date-time"
                        }
                      },
                      "description": "A label or group."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "labelId": "Lb3NcY8sDf4HqPe",
                        "isGroup": false,
                        "name": "Next step",
                        "description": "Something a person agreed to do.",
                        "color": "#6366f1",
                        "parentId": "Gx7QkP2mVt9LwRz",
                        "source": "user",
                        "isActive": true,
                        "sortOrder": 0,
                        "userId": "65f0c1a2b3c4d5e6f7a8b9c0",
                        "createdAt": "2026-10-06T14:05:12.000Z",
                        "updatedAt": "2026-10-06T16:00:00.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A rule above was broken or a field failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "A rule above was broken or a field failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "Restore this label before editing it.",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "You lack the Labels: Update permission",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "Why the request was refused."
                    }
                  }
                },
                "examples": {
                  "error-403": {
                    "summary": "You lack the Labels: Update permission",
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to perform this action"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No label with that id in your company",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "No label with that id in your company",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Label not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "An active label with this name already exists under the same parent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-409": {
                    "summary": "An active label with this name already exists under the same parent",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 409,
                      "message": "A label with this name already exists here.",
                      "hints": [
                        "Please use PUT for update instead of POST",
                        "The requested operation failed because it tried to create a resource that already exists."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Label list"
      }
    },
    "/labels/{labelId}/archive": {
      "post": {
        "tags": [
          "Labels"
        ],
        "summary": "Archive a label or group",
        "operationId": "labels-archive",
        "description": "Requires the **Labels: Delete** permission (on by default for admins). Archived labels drop out of the default list and cannot be applied, but passages already labelled keep them. Archiving a group also archives every label in it. Safe to repeat: archiving something already archived returns `archivedCount: 0`. Nothing is deleted; restore it at any time.",
        "parameters": [
          {
            "name": "labelId",
            "in": "path",
            "required": true,
            "description": "Id of the label or group. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "Lb3NcY8sDf4HqPe"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "labelId": {
                          "type": "string",
                          "description": "Id of the label you archived."
                        },
                        "archivedCount": {
                          "type": "integer",
                          "description": "How many labels and groups changed from active to archived."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "labelId": "Gx7QkP2mVt9LwRz",
                        "archivedCount": 5
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "You lack the Labels: Delete permission",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "Why the request was refused."
                    }
                  }
                },
                "examples": {
                  "error-403": {
                    "summary": "You lack the Labels: Delete permission",
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to perform this action"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No label with that id in your company",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "No label with that id in your company",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Label not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Label list"
      }
    },
    "/labels/{labelId}/restore": {
      "post": {
        "tags": [
          "Labels"
        ],
        "summary": "Restore an archived label or group",
        "operationId": "labels-restore",
        "description": "Requires the **Labels: Delete** permission. Restoring a group also restores its archived labels, except ones that were merged. A label in that group whose name is now used by an active label stays archived and is counted in `skippedCount`.\n\n#### Errors\n\n- `400` \"This label was merged into another label and cannot be restored.\"\n- `400` \"Restore its group first.\" when the label sits in a group that is still archived.\n- `403` without the permission.\n- `404` when the label does not exist.\n- `409` when the label's own name is now used by an active label under the same parent. Rename one of them first.",
        "parameters": [
          {
            "name": "labelId",
            "in": "path",
            "required": true,
            "description": "Id of the label or group. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "Lb3NcY8sDf4HqPe"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "labelId": {
                          "type": "string",
                          "description": "Id of the label you restored."
                        },
                        "restoredCount": {
                          "type": "integer",
                          "description": "How many labels and groups changed from archived to active."
                        },
                        "skippedCount": {
                          "type": "integer",
                          "description": "Labels in the group left archived because their name is taken."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "labelId": "Gx7QkP2mVt9LwRz",
                        "restoredCount": 5,
                        "skippedCount": 0
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The label was merged, or its group is archived",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "The label was merged, or its group is archived",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "Restore its group first.",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "You lack the Labels: Delete permission",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "Why the request was refused."
                    }
                  }
                },
                "examples": {
                  "error-403": {
                    "summary": "You lack the Labels: Delete permission",
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to perform this action"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No label with that id in your company",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "No label with that id in your company",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Label not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Its name is used by an active label",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-409": {
                    "summary": "Its name is used by an active label",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 409,
                      "message": "A label with this name already exists here. Rename one of them first.",
                      "hints": [
                        "Please use PUT for update instead of POST",
                        "The requested operation failed because it tried to create a resource that already exists."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Label list"
      }
    },
    "/labels/{labelId}/merge": {
      "post": {
        "tags": [
          "Labels"
        ],
        "summary": "Merge a label into another",
        "operationId": "labels-merge",
        "description": "Requires both **Labels: Update** and **Labels: Delete**. Moves every use of the label in the path onto `targetLabelId`, then archives it with `mergedInto` set. A passage that already had both labels keeps one. A merged label cannot be restored.\n\n`movedCount` is the number of labelled passages changed across the whole company.\n\n#### Errors\n\n- `400` when the two ids are the same, when either is a group, or when either is archived.\n- `403` without both permissions.\n- `404` when either label does not exist.",
        "parameters": [
          {
            "name": "labelId",
            "in": "path",
            "required": true,
            "description": "Id of the label to merge away. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "Lb9TmK2vXa6JrWo"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "targetLabelId": {
                    "type": "string",
                    "description": "Id of the label to keep. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
                    "pattern": "^[A-Za-z0-9_-]{1,64}$"
                  }
                },
                "required": [
                  "targetLabelId"
                ]
              },
              "example": {
                "targetLabelId": "Lb3NcY8sDf4HqPe"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "labelId": {
                          "type": "string",
                          "description": "Id of the label that was merged and archived."
                        },
                        "mergedInto": {
                          "type": "string",
                          "description": "Id of the label that now carries its uses."
                        },
                        "movedCount": {
                          "type": "integer",
                          "description": "Labelled passages changed, company-wide."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "labelId": "Lb9TmK2vXa6JrWo",
                        "mergedInto": "Lb3NcY8sDf4HqPe",
                        "movedCount": 7
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Same label, a group, or an archived label",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "Same label, a group, or an archived label",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "Choose a different label to merge into.",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "You lack Labels: Update or Labels: Delete",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "Why the request was refused."
                    }
                  }
                },
                "examples": {
                  "error-403": {
                    "summary": "You lack Labels: Update or Labels: Delete",
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to perform this action"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Either label does not exist",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "Either label does not exist",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Target label not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Label list"
      }
    },
    "/media/{mediaId}/labels": {
      "get": {
        "tags": [
          "Labels"
        ],
        "summary": "List labels on a transcript",
        "operationId": "media-labels-list",
        "description": "Returns every labelled passage on the media, ordered by position in the transcript, with the media's current `transcriptRevision`. Anyone who can open the file can read its labels; no labels permission is needed. The media must belong to your company and be one you can open. Owners and members with the folder **Access all** permission can open any file; everyone else can open files in folders assigned to them or their groups, and files they own. Any other media returns 404, the same as a media id that does not exist.\n\nWhen a transcript is saved, labels and comments on passages are moved to the new text in the background, after the save has answered. Until that finishes, which is normally a moment, a list can return anchors whose `anchor.transcriptRevision` is lower than the top-level `transcriptRevision`. Fetch the list again shortly after a save.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Return only passages with this status. Leave it out for all of them. One of: `active`, `shifted`, `needs_review`.",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "shifted",
                "needs_review"
              ]
            },
            "example": "needs_review"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "transcriptRevision": {
                          "type": "integer",
                          "description": "The media's current transcript revision. Send it as `expectedTranscriptRevision` when you label or comment."
                        },
                        "mediaLabels": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "mediaLabelId": {
                                "type": "string",
                                "description": "Id of the labelled passage."
                              },
                              "mediaId": {
                                "type": "string",
                                "description": "Id of the media."
                              },
                              "labelIds": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Labels on the passage."
                              },
                              "anchor": {
                                "type": "object",
                                "properties": {
                                  "startWord": {
                                    "type": "integer",
                                    "description": "Position of the first word."
                                  },
                                  "endWord": {
                                    "type": "integer",
                                    "description": "Position of the last word, inclusive."
                                  },
                                  "exact": {
                                    "type": "string",
                                    "description": "The quoted words, joined by single spaces."
                                  },
                                  "prefix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text before the quote."
                                  },
                                  "suffix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text after the quote."
                                  },
                                  "startInSec": {
                                    "type": "number",
                                    "description": "Start time of the first word, in seconds."
                                  },
                                  "endInSec": {
                                    "type": "number",
                                    "description": "End time of the last word, in seconds."
                                  },
                                  "speakerIds": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    },
                                    "description": "Speakers of the quoted words."
                                  },
                                  "transcriptRevision": {
                                    "type": "integer",
                                    "description": "The transcript revision these positions refer to."
                                  }
                                },
                                "description": "Where the passage sits in the transcript. Built by the server from the word range you send."
                              },
                              "status": {
                                "type": "string",
                                "description": "`active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                                "enum": [
                                  "active",
                                  "shifted",
                                  "needs_review"
                                ]
                              },
                              "lastResolved": {
                                "type": "object",
                                "properties": {
                                  "startWord": {
                                    "type": "integer",
                                    "description": "Position of the first word."
                                  },
                                  "endWord": {
                                    "type": "integer",
                                    "description": "Position of the last word, inclusive."
                                  },
                                  "exact": {
                                    "type": "string",
                                    "description": "The quoted words, joined by single spaces."
                                  },
                                  "prefix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text before the quote."
                                  },
                                  "suffix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text after the quote."
                                  },
                                  "startInSec": {
                                    "type": "number",
                                    "description": "Start time of the first word, in seconds."
                                  },
                                  "endInSec": {
                                    "type": "number",
                                    "description": "End time of the last word, in seconds."
                                  },
                                  "speakerIds": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    },
                                    "description": "Speakers of the quoted words."
                                  },
                                  "transcriptRevision": {
                                    "type": "integer",
                                    "description": "The transcript revision these positions refer to."
                                  }
                                },
                                "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                              },
                              "userId": {
                                "type": "string",
                                "description": "Id of the person who first labelled the passage."
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "When it was created.",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "description": "When it last changed.",
                                "format": "date-time"
                              }
                            },
                            "description": "Labels on one passage of a transcript."
                          },
                          "description": "Labelled passages, ordered by `anchor.startWord`."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "transcriptRevision": 3,
                        "mediaLabels": [
                          {
                            "mediaLabelId": "Ml5RtB7nZc2GyQs",
                            "mediaId": "b4994aa1267c",
                            "labelIds": [
                              "Lb3NcY8sDf4HqPe"
                            ],
                            "anchor": {
                              "startWord": 42,
                              "endWord": 49,
                              "exact": "we need the pricing sheet by Friday",
                              "prefix": "Before we close the quarter, ",
                              "suffix": ". Can you send it over?",
                              "startInSec": 61.4,
                              "endInSec": 64.2,
                              "speakerIds": [
                                "1"
                              ],
                              "transcriptRevision": 3
                            },
                            "status": "active",
                            "userId": "65f0c1a2b3c4d5e6f7a8b9c0",
                            "createdAt": "2026-10-06T14:05:12.000Z",
                            "updatedAt": "2026-10-06T14:05:12.000Z"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A path or query value failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "A path or query value failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "\"status\" must be one of [active, shifted, needs_review]",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The media does not exist or you cannot open it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "The media does not exist or you cannot open it",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Media not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Labels on a transcript"
      },
      "post": {
        "tags": [
          "Labels"
        ],
        "summary": "Label a passage",
        "operationId": "media-labels-create",
        "description": "Requires the **Labels: Assign** permission (on by default for admins and members). The media must belong to your company and be one you can open. Owners and members with the folder **Access all** permission can open any file; everyone else can open files in folders assigned to them or their groups, and files they own. Any other media returns 404, the same as a media id that does not exist.\n\n#### How to address words\n\nSend the word range and the revision you read it from. Word positions count every word of the transcript in order, starting at 0. Within each sentence, words come from `entities` in order (an entity that holds several words, such as \"New York\", counts as several), or from the sentence `text` split on whitespace when the sentence has no entities. A token that is only punctuation is not counted. `expectedTranscriptRevision` is the `transcriptRevision` you read the transcript at, from `GET /media/transcript/{mediaId}`, `GET /media/insight/{mediaId}`, or the list endpoints on this page. The server builds the anchor from its own copy of the transcript. If the transcript has been saved since, the request returns 409 \"This transcript changed since you opened it. Reload to keep editing.\" and nothing is written: read the transcript again and recompute the word range.\n\n#### Request rules\n\n- When the same words already carry labels at this revision, the labels you send are added to that passage and the existing passage is returned.\n- A transcript holds at most 5,000 labelled passages; past that the request returns 400.\n\n#### Errors\n\n- `400` when a field fails validation, the range runs past the transcript, a label is archived, a group or not in your company, or the passage limit is reached.\n- `403` without the permission.\n- `404` when the media does not exist or you cannot open it.\n- `409` when `expectedTranscriptRevision` is stale.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "range": {
                    "type": "object",
                    "properties": {
                      "start": {
                        "type": "integer",
                        "description": "Position of the first word. Integer, 0 or more.",
                        "minimum": 0
                      },
                      "end": {
                        "type": "integer",
                        "description": "Position of the last word, inclusive. Integer, at least `start`. A range that runs past the last word returns 400 \"The selected words are outside this transcript.\"",
                        "minimum": 0
                      }
                    },
                    "required": [
                      "start",
                      "end"
                    ],
                    "description": "Inclusive range of word positions. Word positions count every word of the transcript in order, starting at 0. Within each sentence, words come from `entities` in order (an entity that holds several words, such as \"New York\", counts as several), or from the sentence `text` split on whitespace when the sentence has no entities. A token that is only punctuation is not counted."
                  },
                  "labelIds": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 20,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "pattern": "^[A-Za-z0-9_-]{1,64}$"
                    },
                    "description": "Labels to put on the passage. 1 to 20 ids, no repeats. Each must be an active label (not a group) in your company, or the request returns 400 \"Choose active labels from this workspace (groups cannot be applied).\""
                  },
                  "expectedTranscriptRevision": {
                    "type": "integer",
                    "description": "The `transcriptRevision` you read the transcript at. Integer, 0 or more. A stale value returns 409.",
                    "minimum": 0
                  }
                },
                "required": [
                  "range",
                  "labelIds",
                  "expectedTranscriptRevision"
                ]
              },
              "example": {
                "range": {
                  "start": 42,
                  "end": 49
                },
                "labelIds": [
                  "Lb3NcY8sDf4HqPe"
                ],
                "expectedTranscriptRevision": 3
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "mediaLabelId": {
                          "type": "string",
                          "description": "Id of the labelled passage."
                        },
                        "mediaId": {
                          "type": "string",
                          "description": "Id of the media."
                        },
                        "labelIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Labels on the passage."
                        },
                        "anchor": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "Where the passage sits in the transcript. Built by the server from the word range you send."
                        },
                        "status": {
                          "type": "string",
                          "description": "`active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                          "enum": [
                            "active",
                            "shifted",
                            "needs_review"
                          ]
                        },
                        "lastResolved": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                        },
                        "userId": {
                          "type": "string",
                          "description": "Id of the person who first labelled the passage."
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "When it was created.",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "When it last changed.",
                          "format": "date-time"
                        }
                      },
                      "description": "Labels on one passage of a transcript."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "mediaLabelId": "Ml5RtB7nZc2GyQs",
                        "mediaId": "b4994aa1267c",
                        "labelIds": [
                          "Lb3NcY8sDf4HqPe"
                        ],
                        "anchor": {
                          "startWord": 42,
                          "endWord": 49,
                          "exact": "we need the pricing sheet by Friday",
                          "prefix": "Before we close the quarter, ",
                          "suffix": ". Can you send it over?",
                          "startInSec": 61.4,
                          "endInSec": 64.2,
                          "speakerIds": [
                            "1"
                          ],
                          "transcriptRevision": 3
                        },
                        "status": "active",
                        "userId": "65f0c1a2b3c4d5e6f7a8b9c0",
                        "createdAt": "2026-10-06T14:05:12.000Z",
                        "updatedAt": "2026-10-06T14:05:12.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation, range, label or limit problem",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "Validation, range, label or limit problem",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "The selected words are outside this transcript.",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "You lack the Labels: Assign permission",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "Why the request was refused."
                    }
                  }
                },
                "examples": {
                  "error-403": {
                    "summary": "You lack the Labels: Assign permission",
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to perform this action"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The media does not exist or you cannot open it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "The media does not exist or you cannot open it",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Media not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The transcript changed since you read it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-409": {
                    "summary": "The transcript changed since you read it",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 409,
                      "message": "This transcript changed since you opened it. Reload to keep editing.",
                      "hints": [
                        "Please use PUT for update instead of POST",
                        "The requested operation failed because it tried to create a resource that already exists."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Labels on a transcript"
      }
    },
    "/media/{mediaId}/labels/{mediaLabelId}": {
      "patch": {
        "tags": [
          "Labels"
        ],
        "summary": "Change, confirm or move a labelled passage",
        "operationId": "media-labels-update",
        "description": "Requires the **Labels: Assign** permission. Send exactly one of `labelIds` or `action`; both or neither returns 400.\n\n- `labelIds` replaces the passage's labels, with the same rules as when you label a passage.\n- `action: \"keep\"` confirms the passage where it is now: `status` becomes `active` and `lastResolved` is cleared. Use it on a `shifted` passage, or to accept the suggestion on a `needs_review` one. It returns 409 if the passage is still on an older revision, which happens for a moment after a save.\n- `action: \"replace\"` moves the passage to new words. It needs `range` and `expectedTranscriptRevision`, which are not allowed with any other choice. `expectedTranscriptRevision` is the `transcriptRevision` you read the transcript at, from `GET /media/transcript/{mediaId}`, `GET /media/insight/{mediaId}`, or the list endpoints on this page. The server builds the anchor from its own copy of the transcript. If the transcript has been saved since, the request returns 409 \"This transcript changed since you opened it. Reload to keep editing.\" and nothing is written: read the transcript again and recompute the word range.\n\n#### Errors\n\n- `400` when the body breaks the rules above, the range runs past the transcript, or a label cannot be applied.\n- `403` without the permission.\n- `404` when the media or the labelled passage does not exist.\n- `409` when the revision is stale.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "mediaLabelId",
            "in": "path",
            "required": true,
            "description": "Id of the labelled passage, from `mediaLabelId`. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "Ml5RtB7nZc2GyQs"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "labelIds": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 20,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "pattern": "^[A-Za-z0-9_-]{1,64}$"
                    },
                    "description": "Labels to put on the passage. 1 to 20 ids, no repeats. Each must be an active label (not a group) in your company, or the request returns 400 \"Choose active labels from this workspace (groups cannot be applied).\""
                  },
                  "action": {
                    "type": "string",
                    "description": "`keep` to confirm the current position, `replace` to move the passage.",
                    "enum": [
                      "keep",
                      "replace"
                    ]
                  },
                  "range": {
                    "type": "object",
                    "properties": {
                      "start": {
                        "type": "integer",
                        "description": "Position of the first word. Integer, 0 or more.",
                        "minimum": 0
                      },
                      "end": {
                        "type": "integer",
                        "description": "Position of the last word, inclusive. Integer, at least `start`. A range that runs past the last word returns 400 \"The selected words are outside this transcript.\"",
                        "minimum": 0
                      }
                    },
                    "required": [
                      "start",
                      "end"
                    ],
                    "description": "Required with `action: \"replace\"`, not allowed otherwise. Inclusive range of word positions. Word positions count every word of the transcript in order, starting at 0. Within each sentence, words come from `entities` in order (an entity that holds several words, such as \"New York\", counts as several), or from the sentence `text` split on whitespace when the sentence has no entities. A token that is only punctuation is not counted."
                  },
                  "expectedTranscriptRevision": {
                    "type": "integer",
                    "description": "Required with `action: \"replace\"`, not allowed otherwise. The `transcriptRevision` you read the transcript at. Integer, 0 or more. A stale value returns 409.",
                    "minimum": 0
                  }
                }
              },
              "example": {
                "labelIds": [
                  "Lb3NcY8sDf4HqPe",
                  "Lb9TmK2vXa6JrWo"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "mediaLabelId": {
                          "type": "string",
                          "description": "Id of the labelled passage."
                        },
                        "mediaId": {
                          "type": "string",
                          "description": "Id of the media."
                        },
                        "labelIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Labels on the passage."
                        },
                        "anchor": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "Where the passage sits in the transcript. Built by the server from the word range you send."
                        },
                        "status": {
                          "type": "string",
                          "description": "`active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                          "enum": [
                            "active",
                            "shifted",
                            "needs_review"
                          ]
                        },
                        "lastResolved": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                        },
                        "userId": {
                          "type": "string",
                          "description": "Id of the person who first labelled the passage."
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "When it was created.",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "When it last changed.",
                          "format": "date-time"
                        }
                      },
                      "description": "Labels on one passage of a transcript."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "mediaLabelId": "Ml5RtB7nZc2GyQs",
                        "mediaId": "b4994aa1267c",
                        "labelIds": [
                          "Lb3NcY8sDf4HqPe",
                          "Lb9TmK2vXa6JrWo"
                        ],
                        "anchor": {
                          "startWord": 42,
                          "endWord": 49,
                          "exact": "we need the pricing sheet by Friday",
                          "prefix": "Before we close the quarter, ",
                          "suffix": ". Can you send it over?",
                          "startInSec": 61.4,
                          "endInSec": 64.2,
                          "speakerIds": [
                            "1"
                          ],
                          "transcriptRevision": 3
                        },
                        "status": "active",
                        "userId": "65f0c1a2b3c4d5e6f7a8b9c0",
                        "createdAt": "2026-10-06T14:05:12.000Z",
                        "updatedAt": "2026-10-06T14:05:12.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body broke a rule or failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "The body broke a rule or failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "\"value\" must contain at least one of [labelIds, action]",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "You lack the Labels: Assign permission",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "Why the request was refused."
                    }
                  }
                },
                "examples": {
                  "error-403": {
                    "summary": "You lack the Labels: Assign permission",
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to perform this action"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The media or the labelled passage does not exist",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "The media or the labelled passage does not exist",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Label on this transcript not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The transcript changed since you read it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-409": {
                    "summary": "The transcript changed since you read it",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 409,
                      "message": "This transcript changed since you opened it. Reload to keep editing.",
                      "hints": [
                        "Please use PUT for update instead of POST",
                        "The requested operation failed because it tried to create a resource that already exists."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Labels on a transcript"
      },
      "delete": {
        "tags": [
          "Labels"
        ],
        "summary": "Remove a labelled passage",
        "operationId": "media-labels-delete",
        "description": "Requires the **Labels: Assign** permission. Removes the passage and all its labels from the transcript. The labels themselves stay in your list. Comments linked to the passage stay, without the link.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "mediaLabelId",
            "in": "path",
            "required": true,
            "description": "Id of the labelled passage, from `mediaLabelId`. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "Ml5RtB7nZc2GyQs"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "mediaLabelId": {
                          "type": "string",
                          "description": "Id of the passage you removed."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "mediaLabelId": "Ml5RtB7nZc2GyQs"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "You lack the Labels: Assign permission",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "Why the request was refused."
                    }
                  }
                },
                "examples": {
                  "error-403": {
                    "summary": "You lack the Labels: Assign permission",
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to perform this action"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The media or the labelled passage does not exist",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "The media or the labelled passage does not exist",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Label on this transcript not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Labels on a transcript"
      }
    },
    "/media/{mediaId}/comments": {
      "get": {
        "tags": [
          "Comments"
        ],
        "summary": "List comment threads",
        "operationId": "media-comments-list",
        "description": "Returns the media's comment threads, oldest first, with the media's current `transcriptRevision`. Each thread is its first comment with a `replies` array. Anyone who can open the file can read its comments; no comments permission is needed. The media must belong to your company and be one you can open. Owners and members with the folder **Access all** permission can open any file; everyone else can open files in folders assigned to them or their groups, and files they own. Any other media returns 404, the same as a media id that does not exist.\n\nA deleted first comment that still has replies stays in the list with an empty `body` and `isDeleted: true`, so the replies keep their context. Deleted replies are left out.\n\nWhen a transcript is saved, labels and comments on passages are moved to the new text in the background, after the save has answered. Until that finishes, which is normally a moment, a list can return anchors whose `anchor.transcriptRevision` is lower than the top-level `transcriptRevision`. Fetch the list again shortly after a save.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "filter",
            "in": "query",
            "required": false,
            "description": "`all` (the default), `open` or `resolved` threads, or `file` for comments on the whole file only. One of: `all`, `open`, `resolved`, `file`.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "open",
                "resolved",
                "file"
              ]
            },
            "example": "open"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "transcriptRevision": {
                          "type": "integer",
                          "description": "The media's current transcript revision."
                        },
                        "threads": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "commentId": {
                                "type": "string",
                                "description": "Id of the comment."
                              },
                              "mediaId": {
                                "type": "string",
                                "description": "Id of the media."
                              },
                              "anchor": {
                                "type": "object",
                                "properties": {
                                  "startWord": {
                                    "type": "integer",
                                    "description": "Position of the first word."
                                  },
                                  "endWord": {
                                    "type": "integer",
                                    "description": "Position of the last word, inclusive."
                                  },
                                  "exact": {
                                    "type": "string",
                                    "description": "The quoted words, joined by single spaces."
                                  },
                                  "prefix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text before the quote."
                                  },
                                  "suffix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text after the quote."
                                  },
                                  "startInSec": {
                                    "type": "number",
                                    "description": "Start time of the first word, in seconds."
                                  },
                                  "endInSec": {
                                    "type": "number",
                                    "description": "End time of the last word, in seconds."
                                  },
                                  "speakerIds": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    },
                                    "description": "Speakers of the quoted words."
                                  },
                                  "transcriptRevision": {
                                    "type": "integer",
                                    "description": "The transcript revision these positions refer to."
                                  }
                                },
                                "description": "The passage the comment is on, or `null` for a comment on the whole file. Replies carry `null`.",
                                "nullable": true
                              },
                              "parentId": {
                                "type": "string",
                                "description": "`commentId` of the thread's first comment for a reply, `null` for the first comment.",
                                "nullable": true
                              },
                              "body": {
                                "type": "string",
                                "description": "Comment text. Empty on a deleted first comment that still has replies."
                              },
                              "mediaLabelId": {
                                "type": "string",
                                "description": "Labelled passage the comment is linked to. Present only when one was linked."
                              },
                              "status": {
                                "type": "string",
                                "description": "Present only on comments with an anchor. `active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                                "enum": [
                                  "active",
                                  "shifted",
                                  "needs_review"
                                ]
                              },
                              "lastResolved": {
                                "type": "object",
                                "properties": {
                                  "startWord": {
                                    "type": "integer",
                                    "description": "Position of the first word."
                                  },
                                  "endWord": {
                                    "type": "integer",
                                    "description": "Position of the last word, inclusive."
                                  },
                                  "exact": {
                                    "type": "string",
                                    "description": "The quoted words, joined by single spaces."
                                  },
                                  "prefix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text before the quote."
                                  },
                                  "suffix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text after the quote."
                                  },
                                  "startInSec": {
                                    "type": "number",
                                    "description": "Start time of the first word, in seconds."
                                  },
                                  "endInSec": {
                                    "type": "number",
                                    "description": "End time of the last word, in seconds."
                                  },
                                  "speakerIds": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    },
                                    "description": "Speakers of the quoted words."
                                  },
                                  "transcriptRevision": {
                                    "type": "integer",
                                    "description": "The transcript revision these positions refer to."
                                  }
                                },
                                "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                              },
                              "isResolved": {
                                "type": "boolean",
                                "description": "`true` once the thread is resolved. Only set on the first comment of a thread."
                              },
                              "resolvedBy": {
                                "type": "string",
                                "description": "Id of the person who resolved the thread. Present only while it is resolved."
                              },
                              "isDeleted": {
                                "type": "boolean",
                                "description": "`true` on a deleted first comment kept because it has replies."
                              },
                              "userId": {
                                "type": "string",
                                "description": "Id of the author."
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "When it was posted.",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "description": "When it last changed.",
                                "format": "date-time"
                              },
                              "replies": {
                                "type": "array",
                                "description": "Replies, oldest first, with the same fields. Deleted replies are left out.",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "commentId": {
                                      "type": "string",
                                      "description": "Id of the comment."
                                    },
                                    "mediaId": {
                                      "type": "string",
                                      "description": "Id of the media."
                                    },
                                    "anchor": {
                                      "type": "object",
                                      "properties": {
                                        "startWord": {
                                          "type": "integer",
                                          "description": "Position of the first word."
                                        },
                                        "endWord": {
                                          "type": "integer",
                                          "description": "Position of the last word, inclusive."
                                        },
                                        "exact": {
                                          "type": "string",
                                          "description": "The quoted words, joined by single spaces."
                                        },
                                        "prefix": {
                                          "type": "string",
                                          "description": "Up to 32 characters of transcript text before the quote."
                                        },
                                        "suffix": {
                                          "type": "string",
                                          "description": "Up to 32 characters of transcript text after the quote."
                                        },
                                        "startInSec": {
                                          "type": "number",
                                          "description": "Start time of the first word, in seconds."
                                        },
                                        "endInSec": {
                                          "type": "number",
                                          "description": "End time of the last word, in seconds."
                                        },
                                        "speakerIds": {
                                          "type": "array",
                                          "items": {
                                            "type": "string"
                                          },
                                          "description": "Speakers of the quoted words."
                                        },
                                        "transcriptRevision": {
                                          "type": "integer",
                                          "description": "The transcript revision these positions refer to."
                                        }
                                      },
                                      "description": "The passage the comment is on, or `null` for a comment on the whole file. Replies carry `null`.",
                                      "nullable": true
                                    },
                                    "parentId": {
                                      "type": "string",
                                      "description": "`commentId` of the thread's first comment for a reply, `null` for the first comment.",
                                      "nullable": true
                                    },
                                    "body": {
                                      "type": "string",
                                      "description": "Comment text. Empty on a deleted first comment that still has replies."
                                    },
                                    "mediaLabelId": {
                                      "type": "string",
                                      "description": "Labelled passage the comment is linked to. Present only when one was linked."
                                    },
                                    "status": {
                                      "type": "string",
                                      "description": "Present only on comments with an anchor. `active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                                      "enum": [
                                        "active",
                                        "shifted",
                                        "needs_review"
                                      ]
                                    },
                                    "lastResolved": {
                                      "type": "object",
                                      "properties": {
                                        "startWord": {
                                          "type": "integer",
                                          "description": "Position of the first word."
                                        },
                                        "endWord": {
                                          "type": "integer",
                                          "description": "Position of the last word, inclusive."
                                        },
                                        "exact": {
                                          "type": "string",
                                          "description": "The quoted words, joined by single spaces."
                                        },
                                        "prefix": {
                                          "type": "string",
                                          "description": "Up to 32 characters of transcript text before the quote."
                                        },
                                        "suffix": {
                                          "type": "string",
                                          "description": "Up to 32 characters of transcript text after the quote."
                                        },
                                        "startInSec": {
                                          "type": "number",
                                          "description": "Start time of the first word, in seconds."
                                        },
                                        "endInSec": {
                                          "type": "number",
                                          "description": "End time of the last word, in seconds."
                                        },
                                        "speakerIds": {
                                          "type": "array",
                                          "items": {
                                            "type": "string"
                                          },
                                          "description": "Speakers of the quoted words."
                                        },
                                        "transcriptRevision": {
                                          "type": "integer",
                                          "description": "The transcript revision these positions refer to."
                                        }
                                      },
                                      "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                                    },
                                    "isResolved": {
                                      "type": "boolean",
                                      "description": "`true` once the thread is resolved. Only set on the first comment of a thread."
                                    },
                                    "resolvedBy": {
                                      "type": "string",
                                      "description": "Id of the person who resolved the thread. Present only while it is resolved."
                                    },
                                    "isDeleted": {
                                      "type": "boolean",
                                      "description": "`true` on a deleted first comment kept because it has replies."
                                    },
                                    "userId": {
                                      "type": "string",
                                      "description": "Id of the author."
                                    },
                                    "createdAt": {
                                      "type": "string",
                                      "description": "When it was posted.",
                                      "format": "date-time"
                                    },
                                    "updatedAt": {
                                      "type": "string",
                                      "description": "When it last changed.",
                                      "format": "date-time"
                                    }
                                  }
                                }
                              }
                            }
                          },
                          "description": "Threads, oldest first."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "transcriptRevision": 3,
                        "threads": [
                          {
                            "commentId": "Cm8WpE3kLv6NdHa",
                            "mediaId": "b4994aa1267c",
                            "anchor": {
                              "startWord": 42,
                              "endWord": 49,
                              "exact": "we need the pricing sheet by Friday",
                              "prefix": "Before we close the quarter, ",
                              "suffix": ". Can you send it over?",
                              "startInSec": 61.4,
                              "endInSec": 64.2,
                              "speakerIds": [
                                "1"
                              ],
                              "transcriptRevision": 3
                            },
                            "parentId": null,
                            "body": "Can we confirm this date with finance?",
                            "status": "active",
                            "isResolved": false,
                            "isDeleted": false,
                            "userId": "65f0c1a2b3c4d5e6f7a8b9c0",
                            "createdAt": "2026-10-06T14:05:12.000Z",
                            "updatedAt": "2026-10-06T14:05:12.000Z",
                            "replies": [
                              {
                                "commentId": "Cm2YsF9qJt4BxMr",
                                "mediaId": "b4994aa1267c",
                                "anchor": null,
                                "parentId": "Cm8WpE3kLv6NdHa",
                                "body": "Confirmed, Friday works.",
                                "isResolved": false,
                                "isDeleted": false,
                                "userId": "65f0c1a2b3c4d5e6f7a8b9c1",
                                "createdAt": "2026-10-06T15:20:40.000Z",
                                "updatedAt": "2026-10-06T15:20:40.000Z"
                              }
                            ]
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A path or query value failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "A path or query value failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "\"filter\" must be one of [all, open, resolved, file]",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The media does not exist or you cannot open it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "The media does not exist or you cannot open it",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Media not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Comments"
        ],
        "summary": "Post a comment or reply",
        "operationId": "media-comments-create",
        "description": "Requires the **Comments: Create** permission (on by default for admins and members). The media must belong to your company and be one you can open. Owners and members with the folder **Access all** permission can open any file; everyone else can open files in folders assigned to them or their groups, and files they own. Any other media returns 404, the same as a media id that does not exist.\n\n#### Three kinds of comment\n\n- **On a passage**: send `range` and `expectedTranscriptRevision` together. `expectedTranscriptRevision` is the `transcriptRevision` you read the transcript at, from `GET /media/transcript/{mediaId}`, `GET /media/insight/{mediaId}`, or the list endpoints on this page. The server builds the anchor from its own copy of the transcript. If the transcript has been saved since, the request returns 409 \"This transcript changed since you opened it. Reload to keep editing.\" and nothing is written: read the transcript again and recompute the word range.\n- **On the whole file**: leave out both `range` and `expectedTranscriptRevision`.\n- **A reply**: send `parentId`, the `commentId` of a thread's first comment. A reply cannot carry `range` or `mediaLabelId`; it belongs to its thread. Replies go one level deep, so replying to a reply returns 400.\n\nAdd `mediaLabelId` to link a new thread to a labelled passage on the same media.\n\nA reply sends an in-app notification to the person who started the thread, unless they wrote the reply. A transcript holds at most 5,000 comments on passages; whole-file comments and replies are not counted.\n\n#### Errors\n\n- `400` when a field fails validation, the rules above are broken, the range runs past the transcript, or the limit is reached.\n- `403` without the permission.\n- `404` when the media, the parent comment or the labelled passage does not exist.\n- `409` when `expectedTranscriptRevision` is stale.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "body": {
                    "type": "string",
                    "description": "Comment text. Trimmed, then 1 to 5,000 characters.",
                    "minLength": 1,
                    "maxLength": 5000
                  },
                  "range": {
                    "type": "object",
                    "properties": {
                      "start": {
                        "type": "integer",
                        "description": "Position of the first word. Integer, 0 or more.",
                        "minimum": 0
                      },
                      "end": {
                        "type": "integer",
                        "description": "Position of the last word, inclusive. Integer, at least `start`. A range that runs past the last word returns 400 \"The selected words are outside this transcript.\"",
                        "minimum": 0
                      }
                    },
                    "required": [
                      "start",
                      "end"
                    ],
                    "description": "The passage to comment on. Send it with `expectedTranscriptRevision`; leave both out for a whole-file comment. Not allowed on a reply. Inclusive range of word positions. Word positions count every word of the transcript in order, starting at 0. Within each sentence, words come from `entities` in order (an entity that holds several words, such as \"New York\", counts as several), or from the sentence `text` split on whitespace when the sentence has no entities. A token that is only punctuation is not counted."
                  },
                  "expectedTranscriptRevision": {
                    "type": "integer",
                    "description": "Required when you send `range`, not allowed without it. The `transcriptRevision` you read the transcript at. Integer, 0 or more. A stale value returns 409.",
                    "minimum": 0
                  },
                  "parentId": {
                    "type": "string",
                    "description": "`commentId` of the thread's first comment, to post a reply. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
                    "pattern": "^[A-Za-z0-9_-]{1,64}$"
                  },
                  "mediaLabelId": {
                    "type": "string",
                    "description": "A labelled passage on this media to link the thread to. Not allowed on a reply. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
                    "pattern": "^[A-Za-z0-9_-]{1,64}$"
                  }
                },
                "required": [
                  "body"
                ]
              },
              "example": {
                "body": "Can we confirm this date with finance?",
                "range": {
                  "start": 42,
                  "end": 49
                },
                "expectedTranscriptRevision": 3
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "commentId": {
                          "type": "string",
                          "description": "Id of the comment."
                        },
                        "mediaId": {
                          "type": "string",
                          "description": "Id of the media."
                        },
                        "anchor": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "The passage the comment is on, or `null` for a comment on the whole file. Replies carry `null`.",
                          "nullable": true
                        },
                        "parentId": {
                          "type": "string",
                          "description": "`commentId` of the thread's first comment for a reply, `null` for the first comment.",
                          "nullable": true
                        },
                        "body": {
                          "type": "string",
                          "description": "Comment text. Empty on a deleted first comment that still has replies."
                        },
                        "mediaLabelId": {
                          "type": "string",
                          "description": "Labelled passage the comment is linked to. Present only when one was linked."
                        },
                        "status": {
                          "type": "string",
                          "description": "Present only on comments with an anchor. `active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                          "enum": [
                            "active",
                            "shifted",
                            "needs_review"
                          ]
                        },
                        "lastResolved": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                        },
                        "isResolved": {
                          "type": "boolean",
                          "description": "`true` once the thread is resolved. Only set on the first comment of a thread."
                        },
                        "resolvedBy": {
                          "type": "string",
                          "description": "Id of the person who resolved the thread. Present only while it is resolved."
                        },
                        "isDeleted": {
                          "type": "boolean",
                          "description": "`true` on a deleted first comment kept because it has replies."
                        },
                        "userId": {
                          "type": "string",
                          "description": "Id of the author."
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "When it was posted.",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "When it last changed.",
                          "format": "date-time"
                        }
                      },
                      "description": "A comment."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "commentId": "Cm8WpE3kLv6NdHa",
                        "mediaId": "b4994aa1267c",
                        "anchor": {
                          "startWord": 42,
                          "endWord": 49,
                          "exact": "we need the pricing sheet by Friday",
                          "prefix": "Before we close the quarter, ",
                          "suffix": ". Can you send it over?",
                          "startInSec": 61.4,
                          "endInSec": 64.2,
                          "speakerIds": [
                            "1"
                          ],
                          "transcriptRevision": 3
                        },
                        "parentId": null,
                        "body": "Can we confirm this date with finance?",
                        "status": "active",
                        "isResolved": false,
                        "isDeleted": false,
                        "userId": "65f0c1a2b3c4d5e6f7a8b9c0",
                        "createdAt": "2026-10-06T14:05:12.000Z",
                        "updatedAt": "2026-10-06T14:05:12.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation, reply depth, range or limit problem",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "Validation, reply depth, range or limit problem",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "Replies can only be added to the first comment in a thread.",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "You lack the Comments: Create permission",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "Why the request was refused."
                    }
                  }
                },
                "examples": {
                  "error-403": {
                    "summary": "You lack the Comments: Create permission",
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to perform this action"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The media, parent comment or labelled passage does not exist",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "The media, parent comment or labelled passage does not exist",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Comment not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The transcript changed since you read it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-409": {
                    "summary": "The transcript changed since you read it",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 409,
                      "message": "This transcript changed since you opened it. Reload to keep editing.",
                      "hints": [
                        "Please use PUT for update instead of POST",
                        "The requested operation failed because it tried to create a resource that already exists."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/media/{mediaId}/comments/{commentId}": {
      "patch": {
        "tags": [
          "Comments"
        ],
        "summary": "Edit, resolve or reopen a comment",
        "operationId": "media-comments-update",
        "description": "Send exactly one of `body` or `isResolved`; both or neither returns 400.\n\n- `body` edits the text. Only the author can edit a comment; anyone else gets 403 \"You can only edit your own comments.\" No permission is needed to edit your own.\n- `isResolved` resolves (`true`) or reopens (`false`) a thread. It needs the **Comments: Update** permission (on by default for admins and members) and works only on the first comment of a thread; a reply returns 400.\n\n#### Errors\n\n- `400` when the body breaks the rules above or fails validation.\n- `403` when you edit someone else's comment (the error envelope shown), or resolve without the permission (`{\"status\": \"failed\", \"message\": \"You do not have permission to perform this action\"}`).\n- `404` when the media or the comment does not exist, or the comment was deleted.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "commentId",
            "in": "path",
            "required": true,
            "description": "Id of the comment. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "Cm8WpE3kLv6NdHa"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "body": {
                    "type": "string",
                    "description": "New text. Author only. Comment text. Trimmed, then 1 to 5,000 characters.",
                    "minLength": 1,
                    "maxLength": 5000
                  },
                  "isResolved": {
                    "type": "boolean",
                    "description": "`true` to resolve the thread, `false` to reopen it. First comment of a thread only."
                  }
                }
              },
              "example": {
                "isResolved": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "commentId": {
                          "type": "string",
                          "description": "Id of the comment."
                        },
                        "mediaId": {
                          "type": "string",
                          "description": "Id of the media."
                        },
                        "anchor": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "The passage the comment is on, or `null` for a comment on the whole file. Replies carry `null`.",
                          "nullable": true
                        },
                        "parentId": {
                          "type": "string",
                          "description": "`commentId` of the thread's first comment for a reply, `null` for the first comment.",
                          "nullable": true
                        },
                        "body": {
                          "type": "string",
                          "description": "Comment text. Empty on a deleted first comment that still has replies."
                        },
                        "mediaLabelId": {
                          "type": "string",
                          "description": "Labelled passage the comment is linked to. Present only when one was linked."
                        },
                        "status": {
                          "type": "string",
                          "description": "Present only on comments with an anchor. `active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                          "enum": [
                            "active",
                            "shifted",
                            "needs_review"
                          ]
                        },
                        "lastResolved": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                        },
                        "isResolved": {
                          "type": "boolean",
                          "description": "`true` once the thread is resolved. Only set on the first comment of a thread."
                        },
                        "resolvedBy": {
                          "type": "string",
                          "description": "Id of the person who resolved the thread. Present only while it is resolved."
                        },
                        "isDeleted": {
                          "type": "boolean",
                          "description": "`true` on a deleted first comment kept because it has replies."
                        },
                        "userId": {
                          "type": "string",
                          "description": "Id of the author."
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "When it was posted.",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "When it last changed.",
                          "format": "date-time"
                        }
                      },
                      "description": "A comment."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "commentId": "Cm8WpE3kLv6NdHa",
                        "mediaId": "b4994aa1267c",
                        "anchor": {
                          "startWord": 42,
                          "endWord": 49,
                          "exact": "we need the pricing sheet by Friday",
                          "prefix": "Before we close the quarter, ",
                          "suffix": ". Can you send it over?",
                          "startInSec": 61.4,
                          "endInSec": 64.2,
                          "speakerIds": [
                            "1"
                          ],
                          "transcriptRevision": 3
                        },
                        "parentId": null,
                        "body": "Can we confirm this date with finance?",
                        "status": "active",
                        "isResolved": true,
                        "isDeleted": false,
                        "userId": "65f0c1a2b3c4d5e6f7a8b9c0",
                        "createdAt": "2026-10-06T14:05:12.000Z",
                        "updatedAt": "2026-10-06T16:30:00.000Z",
                        "resolvedBy": "65f0c1a2b3c4d5e6f7a8b9c0"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body broke a rule or failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "The body broke a rule or failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "Only the first comment in a thread can be resolved.",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Not your comment, or no Comments: Update permission",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-403": {
                    "summary": "Not your comment, or no Comments: Update permission",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 403,
                      "message": "You can only edit your own comments.",
                      "hints": [
                        "The requested operation is forbidden and cannot be completed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The media or comment does not exist",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "The media or comment does not exist",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Comment not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Comments"
        ],
        "summary": "Delete a comment",
        "operationId": "media-comments-delete",
        "description": "You can always delete your own comments. Deleting someone else's needs the **Comments: Delete** permission (on by default for admins only); without it the request returns 403.\n\nA deleted first comment that has replies stays in the list as an empty placeholder so the replies keep their context.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "commentId",
            "in": "path",
            "required": true,
            "description": "Id of the comment. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "Cm8WpE3kLv6NdHa"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "commentId": {
                          "type": "string",
                          "description": "Id of the comment you deleted."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "commentId": "Cm8WpE3kLv6NdHa"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Someone else's comment, and you lack Comments: Delete",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "Why the request was refused."
                    }
                  }
                },
                "examples": {
                  "error-403": {
                    "summary": "Someone else's comment, and you lack Comments: Delete",
                    "value": {
                      "status": "failed",
                      "message": "You do not have permission to perform this action"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The media or comment does not exist, or it was already deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-404": {
                    "summary": "The media or comment does not exist, or it was already deleted",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 404,
                      "message": "Comment not found.",
                      "hints": [
                        "The requested operation failed because a resource associated with the request could not be found."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ]
      }
    },
    "/dashboards": {
      "post": {
        "tags": [
          "Dashboards"
        ],
        "summary": "Create a dashboard",
        "operationId": "dashboards-create",
        "description": "Create an analytics dashboard. Only `spec` is required. Creating a dashboard does not share it; the share link is made from the app.\n\n#### Viewer settings\n\n`settings` controls what viewers of the dashboard's share link see on each media page. Each section (`fields`, `feedback`, `labels`, `comments`) is saved on its own: the section you send replaces the stored one in full, and a section you leave out keeps its stored value. Read the dashboard first and resend every key of the section you change.\n\nLabels and comments are off until you turn them on. With `labels.mode` set to `apply` or `comments.mode` set to `reply`, a viewer picks one of the dashboard's feedback submitter names (`feedback.submitters`, even while feedback itself is off), or types another name when `feedback.allowOtherSubmitter` is on, and writes under that name. With no names and other names off, nobody can write. The link has no sign-in, so these writes are not authenticated: the link holder chooses the name and Speak AI records the entry under it without checking who sent it, the same as feedback. Only the dashboard's feedback names are accepted, plus any other name when `feedback.allowOtherSubmitter` is on. Speak AI accepts this risk by design and limits it: every entry written through the link is shown as made via the dashboard, a name can change or delete only the entries written under it from that dashboard, a name that is not allowed is refused on every write, and revoking the link stops every write at once. List only the names you are happy for link holders to write as.\n\n#### Errors\n\n- `400` when a field fails validation, the spec is invalid, the payload is too large, or a label group is not an active group of your company (\"Choose active label groups from this workspace.\"). Nothing is saved.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "spec": {
                    "type": "object",
                    "description": "The dashboard itself: `title` (1 to 60 characters), `description` (up to 280), `source` (`{\"type\": \"workspace\"}`, `{\"type\": \"team\"}` or `{\"type\": \"folders\", \"folderIds\": [...]}`), `dateRange` (`{\"preset\": \"last30days\"}`), `sections` and `widgets`. It is checked against the dashboard spec schema, and unknown keys return 400."
                  },
                  "icon": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "Icon identifier. Optional. An empty string is allowed."
                  },
                  "assignTo": {
                    "type": "array",
                    "maxItems": 100,
                    "items": {
                      "type": "string"
                    },
                    "description": "User ids, or group ids written as `<groupId> (G)`, that can view the dashboard. Optional."
                  },
                  "filters": {
                    "type": "object",
                    "description": "Saved filters for the dashboard. Optional. Up to 100 keys; `filterList` holds up to 20 filters."
                  },
                  "settings": {
                    "type": "object",
                    "description": "What viewers of the dashboard's share link see on each media page. Optional. Every section is saved on its own: a section you send replaces that whole section, and a section you leave out keeps its stored value. Unknown keys return 400.",
                    "properties": {
                      "fields": {
                        "type": "object",
                        "description": "Which custom fields the media page shows, and how its Fields tab groups them.",
                        "properties": {
                          "includeIds": {
                            "type": "array",
                            "uniqueItems": true,
                            "items": {
                              "type": "string"
                            },
                            "description": "Field ids shown, in this order, private fields included. Empty shows the company's public fields. Required in the section. Ids that are not fields of your company are dropped and listed in `droppedFieldIds`."
                          },
                          "orderIds": {
                            "type": "array",
                            "uniqueItems": true,
                            "items": {
                              "type": "string"
                            },
                            "description": "Used only when `includeIds` is empty: these fields show first, in this order. Optional."
                          },
                          "groups": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "key": {
                                  "type": "string",
                                  "description": "Stable key of the group, unique in the list."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Name shown on the pill."
                                },
                                "fieldIds": {
                                  "type": "array",
                                  "uniqueItems": true,
                                  "items": {
                                    "type": "string"
                                  },
                                  "minItems": 1,
                                  "description": "Field ids in the group, in order. At least one."
                                }
                              },
                              "required": [
                                "key",
                                "label",
                                "fieldIds"
                              ]
                            },
                            "description": "Pills on the Fields tab. Unique by `key`. Required in the section; send an empty array for none."
                          }
                        },
                        "required": [
                          "includeIds",
                          "groups"
                        ]
                      },
                      "feedback": {
                        "type": "object",
                        "description": "The Feedback button on the media page.",
                        "properties": {
                          "isEnabled": {
                            "type": "boolean",
                            "description": "Show the Feedback button."
                          },
                          "fieldIds": {
                            "type": "array",
                            "uniqueItems": true,
                            "items": {
                              "type": "string"
                            },
                            "description": "Fields a reviewer scores. Empty means every field the page shows."
                          },
                          "submitters": {
                            "type": "array",
                            "uniqueItems": true,
                            "items": {
                              "type": "string",
                              "minLength": 1
                            },
                            "description": "Names a reviewer picks from. Empty lets them type their own."
                          },
                          "removeReasons": {
                            "type": "array",
                            "uniqueItems": true,
                            "items": {
                              "type": "string",
                              "minLength": 1
                            },
                            "description": "Reasons for removing a call from scoring. Empty hides that option."
                          },
                          "reviewScope": {
                            "type": "string",
                            "enum": [
                              "dashboard",
                              "company"
                            ],
                            "description": "`dashboard` (the default) or `company`. Optional."
                          },
                          "allowOtherSubmitter": {
                            "type": "boolean",
                            "description": "Lets a reviewer type a name that is not in `submitters`. Optional."
                          },
                          "groups": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "key": {
                                  "type": "string",
                                  "description": "Stable key of the group, unique in the list."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Name shown on the pill."
                                },
                                "fieldIds": {
                                  "type": "array",
                                  "uniqueItems": true,
                                  "items": {
                                    "type": "string"
                                  },
                                  "minItems": 1,
                                  "description": "Field ids in the group, in order. At least one."
                                }
                              },
                              "required": [
                                "key",
                                "label",
                                "fieldIds"
                              ]
                            },
                            "description": "Pills in the Feedback dialog. Optional."
                          },
                          "fieldRules": {
                            "type": "object",
                            "description": "Per field id: an optional row `label` and the allowed `min` and `max` score. Optional.",
                            "additionalProperties": {
                              "type": "object",
                              "properties": {
                                "label": {
                                  "type": "string"
                                },
                                "min": {
                                  "type": "number"
                                },
                                "max": {
                                  "type": "number"
                                }
                              }
                            }
                          },
                          "sheetWebhookUrl": {
                            "type": "string",
                            "description": "Google Apps Script web app URL that receives one row per submission. Never shown to viewers. Optional."
                          }
                        },
                        "required": [
                          "isEnabled",
                          "fieldIds",
                          "submitters",
                          "removeReasons"
                        ]
                      },
                      "labels": {
                        "type": "object",
                        "description": "Labels on the shared media pages. Off unless you turn it on.",
                        "properties": {
                          "isEnabled": {
                            "type": "boolean",
                            "description": "Show labels on media pages opened from the share link."
                          },
                          "mode": {
                            "type": "string",
                            "enum": [
                              "view",
                              "apply"
                            ],
                            "description": "`view` shows labels read-only. `apply` also lets a viewer add and remove labels under one of the reviewer names."
                          },
                          "labelGroupIds": {
                            "type": "array",
                            "uniqueItems": true,
                            "maxItems": 100,
                            "items": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_-]{1,64}$"
                            },
                            "description": "Label groups the link shows and offers. Up to 100 group ids, no repeats. Empty means every active label. Each must be an active label group of your company, or the whole save returns 400 \"Choose active label groups from this workspace.\" Groups are refused rather than dropped, because dropping them all would widen the link to every label. If every chosen group is archived later, the link shows no labels."
                          }
                        },
                        "required": [
                          "isEnabled",
                          "mode",
                          "labelGroupIds"
                        ]
                      },
                      "comments": {
                        "type": "object",
                        "description": "Comments on the shared media pages. Off unless you turn it on.",
                        "properties": {
                          "isEnabled": {
                            "type": "boolean",
                            "description": "Show comments on media pages opened from the share link."
                          },
                          "mode": {
                            "type": "string",
                            "enum": [
                              "view",
                              "reply"
                            ],
                            "description": "`view` shows comments read-only. `reply` also lets a viewer comment and reply under one of the reviewer names."
                          }
                        },
                        "required": [
                          "isEnabled",
                          "mode"
                        ]
                      },
                      "profiles": {
                        "type": "array",
                        "maxItems": 5,
                        "description": "Profiles: an image, a description and a link for values of a custom field, such as speakers, events or sponsors. Up to 5 groups, one per field (a field may appear only once). Sending `profiles` replaces the whole list. On an update it also needs the dashboard's current `revision` at the top level of the body: without it the request returns 400, and a stale one returns 409. Saving only `profiles` does not change which fields media pages show. Names, images, descriptions and links are visible to anyone with the dashboard link. Optional.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "fieldId": {
                              "type": "string",
                              "maxLength": 100,
                              "description": "Id of the custom field the profiles are for. Required."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 40,
                              "description": "Name of the group, such as `Speakers`. 1 to 40 characters. Required."
                            },
                            "imageShape": {
                              "type": "string",
                              "enum": [
                                "round",
                                "square"
                              ],
                              "description": "How images are cropped. Optional; round when left out."
                            },
                            "entries": {
                              "type": "array",
                              "maxItems": 60,
                              "description": "Up to 60 profiles. Required; send an empty array for none.",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
                                    "description": "Stable id of the entry: lowercase letters, digits and hyphens, up to 64 characters. Optional."
                                  },
                                  "name": {
                                    "type": "string",
                                    "maxLength": 80,
                                    "description": "The field value this profile is for, up to 80 characters. It matches the value ignoring case and extra spaces, and a name may appear only once in a group. Required."
                                  },
                                  "imageKey": {
                                    "type": "string",
                                    "maxLength": 1024,
                                    "description": "The `imageKey` returned by `POST /dashboards/{dashboardId}/profile-image`, or one read back from the dashboard unchanged. Optional."
                                  },
                                  "description": {
                                    "type": "string",
                                    "maxLength": 600,
                                    "description": "Plain text shown with the profile, up to 600 characters. Optional."
                                  },
                                  "link": {
                                    "type": "string",
                                    "maxLength": 2048,
                                    "description": "An `http` or `https` link, up to 2048 characters. Optional."
                                  }
                                },
                                "required": [
                                  "name"
                                ]
                              }
                            }
                          },
                          "required": [
                            "fieldId",
                            "label",
                            "entries"
                          ]
                        }
                      }
                    }
                  },
                  "isDefault": {
                    "type": "boolean",
                    "description": "Make this your default dashboard. Setting it clears the flag on your other dashboards. Optional."
                  }
                },
                "required": [
                  "spec"
                ]
              },
              "example": {
                "spec": {
                  "title": "Sales calls",
                  "source": {
                    "type": "workspace"
                  },
                  "dateRange": {
                    "preset": "last30days"
                  },
                  "sections": [],
                  "widgets": []
                },
                "settings": {
                  "feedback": {
                    "isEnabled": true,
                    "fieldIds": [],
                    "submitters": [
                      "Reviewer A",
                      "Reviewer B"
                    ],
                    "removeReasons": []
                  },
                  "labels": {
                    "isEnabled": true,
                    "mode": "apply",
                    "labelGroupIds": [
                      "Gr7kQ2pLm9xZ"
                    ]
                  },
                  "comments": {
                    "isEnabled": true,
                    "mode": "reply"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "dashboardId": {
                          "type": "string",
                          "description": "Id of the new dashboard."
                        },
                        "droppedFieldIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Field ids removed from `settings` because they are not fields of your company. Present only when some were removed."
                        },
                        "message": {
                          "type": "string",
                          "description": "Confirmation text."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "dashboardId": "Db4kX9mQ2pLr",
                    "message": "Sales calls dashboard created successfully"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 400,
                  "message": "Choose active label groups from this workspace."
                }
              }
            }
          }
        }
      }
    },
    "/dashboards/{dashboardId}": {
      "put": {
        "tags": [
          "Dashboards"
        ],
        "summary": "Update a dashboard",
        "operationId": "dashboards-update",
        "description": "Update a dashboard. Send only the keys you want to change. To change the dashboard itself, send the full `spec` with the `revision` you read: the write is accepted only while it still matches, and returns 409 otherwise. Settings, icon, sharing, filters and the default flag can be changed without a `spec`.\n\n#### Viewer settings\n\n`settings` controls what viewers of the dashboard's share link see on each media page. Each section (`fields`, `feedback`, `labels`, `comments`, `profiles`) is saved on its own: the section you send replaces the stored one in full, and a section you leave out keeps its stored value. Read the dashboard first and resend every key of the section you change.\n\nLabels and comments are off until you turn them on. With `labels.mode` set to `apply` or `comments.mode` set to `reply`, a viewer picks one of the dashboard's feedback submitter names (`feedback.submitters`, even while feedback itself is off), or types another name when `feedback.allowOtherSubmitter` is on, and writes under that name. With no names and other names off, nobody can write. The link has no sign-in, so these writes are not authenticated: the link holder chooses the name and Speak AI records the entry under it without checking who sent it, the same as feedback. Only the dashboard's feedback names are accepted, plus any other name when `feedback.allowOtherSubmitter` is on. Speak AI accepts this risk by design and limits it: every entry written through the link is shown as made via the dashboard, a name can change or delete only the entries written under it from that dashboard, a name that is not allowed is refused on every write, and revoking the link stops every write at once. List only the names you are happy for link holders to write as.\n\n#### Errors\n\n- `400` when a field fails validation, the spec is invalid, the payload is too large, or a label group is not an active group of your company (\"Choose active label groups from this workspace.\"). Nothing is saved.\n- `404` when the dashboard does not exist or you cannot edit it.\n- `409` when the spec `revision` is stale: \"Dashboard was modified by another update. Reload and try again.\"",
        "parameters": [
          {
            "name": "dashboardId",
            "in": "path",
            "required": true,
            "description": "Id of the dashboard, as returned when it was created.",
            "schema": {
              "type": "string"
            },
            "example": "Db4kX9mQ2pLr"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "spec": {
                    "type": "object",
                    "description": "The dashboard itself: `title` (1 to 60 characters), `description` (up to 280), `source` (`{\"type\": \"workspace\"}`, `{\"type\": \"team\"}` or `{\"type\": \"folders\", \"folderIds\": [...]}`), `dateRange` (`{\"preset\": \"last30days\"}`), `sections` and `widgets`. It is checked against the dashboard spec schema, and unknown keys return 400. When sent it must be the full spec, with `revision`."
                  },
                  "revision": {
                    "type": "number",
                    "description": "The dashboard's current revision, a whole number. Required when you send `settings.profiles` without a `spec`; a stale one returns 409."
                  },
                  "icon": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "Icon identifier. Optional. An empty string is allowed."
                  },
                  "assignTo": {
                    "type": "array",
                    "maxItems": 100,
                    "items": {
                      "type": "string"
                    },
                    "description": "User ids, or group ids written as `<groupId> (G)`, that can view the dashboard. Optional."
                  },
                  "filters": {
                    "type": "object",
                    "description": "Saved filters for the dashboard. Optional. Up to 100 keys; `filterList` holds up to 20 filters."
                  },
                  "settings": {
                    "type": "object",
                    "description": "What viewers of the dashboard's share link see on each media page. Optional. Every section is saved on its own: a section you send replaces that whole section, and a section you leave out keeps its stored value. Unknown keys return 400.",
                    "properties": {
                      "fields": {
                        "type": "object",
                        "description": "Which custom fields the media page shows, and how its Fields tab groups them.",
                        "properties": {
                          "includeIds": {
                            "type": "array",
                            "uniqueItems": true,
                            "items": {
                              "type": "string"
                            },
                            "description": "Field ids shown, in this order, private fields included. Empty shows the company's public fields. Required in the section. Ids that are not fields of your company are dropped and listed in `droppedFieldIds`."
                          },
                          "orderIds": {
                            "type": "array",
                            "uniqueItems": true,
                            "items": {
                              "type": "string"
                            },
                            "description": "Used only when `includeIds` is empty: these fields show first, in this order. Optional."
                          },
                          "groups": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "key": {
                                  "type": "string",
                                  "description": "Stable key of the group, unique in the list."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Name shown on the pill."
                                },
                                "fieldIds": {
                                  "type": "array",
                                  "uniqueItems": true,
                                  "items": {
                                    "type": "string"
                                  },
                                  "minItems": 1,
                                  "description": "Field ids in the group, in order. At least one."
                                }
                              },
                              "required": [
                                "key",
                                "label",
                                "fieldIds"
                              ]
                            },
                            "description": "Pills on the Fields tab. Unique by `key`. Required in the section; send an empty array for none."
                          }
                        },
                        "required": [
                          "includeIds",
                          "groups"
                        ]
                      },
                      "feedback": {
                        "type": "object",
                        "description": "The Feedback button on the media page.",
                        "properties": {
                          "isEnabled": {
                            "type": "boolean",
                            "description": "Show the Feedback button."
                          },
                          "fieldIds": {
                            "type": "array",
                            "uniqueItems": true,
                            "items": {
                              "type": "string"
                            },
                            "description": "Fields a reviewer scores. Empty means every field the page shows."
                          },
                          "submitters": {
                            "type": "array",
                            "uniqueItems": true,
                            "items": {
                              "type": "string",
                              "minLength": 1
                            },
                            "description": "Names a reviewer picks from. Empty lets them type their own."
                          },
                          "removeReasons": {
                            "type": "array",
                            "uniqueItems": true,
                            "items": {
                              "type": "string",
                              "minLength": 1
                            },
                            "description": "Reasons for removing a call from scoring. Empty hides that option."
                          },
                          "reviewScope": {
                            "type": "string",
                            "enum": [
                              "dashboard",
                              "company"
                            ],
                            "description": "`dashboard` (the default) or `company`. Optional."
                          },
                          "allowOtherSubmitter": {
                            "type": "boolean",
                            "description": "Lets a reviewer type a name that is not in `submitters`. Optional."
                          },
                          "groups": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "key": {
                                  "type": "string",
                                  "description": "Stable key of the group, unique in the list."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Name shown on the pill."
                                },
                                "fieldIds": {
                                  "type": "array",
                                  "uniqueItems": true,
                                  "items": {
                                    "type": "string"
                                  },
                                  "minItems": 1,
                                  "description": "Field ids in the group, in order. At least one."
                                }
                              },
                              "required": [
                                "key",
                                "label",
                                "fieldIds"
                              ]
                            },
                            "description": "Pills in the Feedback dialog. Optional."
                          },
                          "fieldRules": {
                            "type": "object",
                            "description": "Per field id: an optional row `label` and the allowed `min` and `max` score. Optional.",
                            "additionalProperties": {
                              "type": "object",
                              "properties": {
                                "label": {
                                  "type": "string"
                                },
                                "min": {
                                  "type": "number"
                                },
                                "max": {
                                  "type": "number"
                                }
                              }
                            }
                          },
                          "sheetWebhookUrl": {
                            "type": "string",
                            "description": "Google Apps Script web app URL that receives one row per submission. Never shown to viewers. Optional."
                          }
                        },
                        "required": [
                          "isEnabled",
                          "fieldIds",
                          "submitters",
                          "removeReasons"
                        ]
                      },
                      "labels": {
                        "type": "object",
                        "description": "Labels on the shared media pages. Off unless you turn it on.",
                        "properties": {
                          "isEnabled": {
                            "type": "boolean",
                            "description": "Show labels on media pages opened from the share link."
                          },
                          "mode": {
                            "type": "string",
                            "enum": [
                              "view",
                              "apply"
                            ],
                            "description": "`view` shows labels read-only. `apply` also lets a viewer add and remove labels under one of the reviewer names."
                          },
                          "labelGroupIds": {
                            "type": "array",
                            "uniqueItems": true,
                            "maxItems": 100,
                            "items": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_-]{1,64}$"
                            },
                            "description": "Label groups the link shows and offers. Up to 100 group ids, no repeats. Empty means every active label. Each must be an active label group of your company, or the whole save returns 400 \"Choose active label groups from this workspace.\" Groups are refused rather than dropped, because dropping them all would widen the link to every label. If every chosen group is archived later, the link shows no labels."
                          }
                        },
                        "required": [
                          "isEnabled",
                          "mode",
                          "labelGroupIds"
                        ]
                      },
                      "comments": {
                        "type": "object",
                        "description": "Comments on the shared media pages. Off unless you turn it on.",
                        "properties": {
                          "isEnabled": {
                            "type": "boolean",
                            "description": "Show comments on media pages opened from the share link."
                          },
                          "mode": {
                            "type": "string",
                            "enum": [
                              "view",
                              "reply"
                            ],
                            "description": "`view` shows comments read-only. `reply` also lets a viewer comment and reply under one of the reviewer names."
                          }
                        },
                        "required": [
                          "isEnabled",
                          "mode"
                        ]
                      },
                      "profiles": {
                        "type": "array",
                        "maxItems": 5,
                        "description": "Profiles: an image, a description and a link for values of a custom field, such as speakers, events or sponsors. Up to 5 groups, one per field (a field may appear only once). Sending `profiles` replaces the whole list. On an update it also needs the dashboard's current `revision` at the top level of the body: without it the request returns 400, and a stale one returns 409. Saving only `profiles` does not change which fields media pages show. Names, images, descriptions and links are visible to anyone with the dashboard link. Optional.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "fieldId": {
                              "type": "string",
                              "maxLength": 100,
                              "description": "Id of the custom field the profiles are for. Required."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 40,
                              "description": "Name of the group, such as `Speakers`. 1 to 40 characters. Required."
                            },
                            "imageShape": {
                              "type": "string",
                              "enum": [
                                "round",
                                "square"
                              ],
                              "description": "How images are cropped. Optional; round when left out."
                            },
                            "entries": {
                              "type": "array",
                              "maxItems": 60,
                              "description": "Up to 60 profiles. Required; send an empty array for none.",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
                                    "description": "Stable id of the entry: lowercase letters, digits and hyphens, up to 64 characters. Optional."
                                  },
                                  "name": {
                                    "type": "string",
                                    "maxLength": 80,
                                    "description": "The field value this profile is for, up to 80 characters. It matches the value ignoring case and extra spaces, and a name may appear only once in a group. Required."
                                  },
                                  "imageKey": {
                                    "type": "string",
                                    "maxLength": 1024,
                                    "description": "The `imageKey` returned by `POST /dashboards/{dashboardId}/profile-image`, or one read back from the dashboard unchanged. Optional."
                                  },
                                  "description": {
                                    "type": "string",
                                    "maxLength": 600,
                                    "description": "Plain text shown with the profile, up to 600 characters. Optional."
                                  },
                                  "link": {
                                    "type": "string",
                                    "maxLength": 2048,
                                    "description": "An `http` or `https` link, up to 2048 characters. Optional."
                                  }
                                },
                                "required": [
                                  "name"
                                ]
                              }
                            }
                          },
                          "required": [
                            "fieldId",
                            "label",
                            "entries"
                          ]
                        }
                      }
                    }
                  },
                  "isDefault": {
                    "type": "boolean",
                    "description": "Make this your default dashboard. Setting it clears the flag on your other dashboards. Optional."
                  }
                }
              },
              "example": {
                "settings": {
                  "labels": {
                    "isEnabled": true,
                    "mode": "apply",
                    "labelGroupIds": [
                      "Gr7kQ2pLm9xZ"
                    ]
                  },
                  "comments": {
                    "isEnabled": true,
                    "mode": "reply"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "dashboardId": {
                          "type": "string",
                          "description": "Id of the dashboard."
                        },
                        "revision": {
                          "type": "integer",
                          "description": "The dashboard's revision after the update."
                        },
                        "droppedFieldIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Field ids removed from `settings` because they are not fields of your company. Present only when some were removed."
                        },
                        "message": {
                          "type": "string",
                          "description": "Confirmation text."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "dashboardId": "Db4kX9mQ2pLr",
                    "revision": 4,
                    "message": "Dashboard updated successfully"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 400,
                  "message": "Choose active label groups from this workspace."
                }
              }
            }
          },
          "404": {
            "description": "The dashboard does not exist or you cannot edit it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "Dashboard not found!"
                }
              }
            }
          },
          "409": {
            "description": "The spec revision is stale",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 409,
                  "message": "Dashboard was modified by another update. Reload and try again."
                }
              }
            }
          }
        }
      }
    },
    "/dashboards/{dashboardId}/profile-image": {
      "post": {
        "tags": [
          "Dashboards"
        ],
        "summary": "Upload a profile image",
        "operationId": "dashboards-profile-image-upload",
        "description": "Upload one image for a dashboard profile, then put the returned `imageKey` on the profile entry in `settings.profiles` and save the dashboard with `PUT /dashboards/{dashboardId}`. Uploading alone does not change the dashboard.\n\nSend the file as multipart form data, for example `-F 'image=@speaker.png'`. Send exactly one JPEG, PNG, WebP or GIF image of up to 2 MB. The server checks the file's content, not its name or declared type.\n\nOnly people who can edit the dashboard can upload. Each user can upload up to 30 images in 10 minutes.\n\n#### Errors\n\n- `400` when there is not exactly one file, or the file is not a JPEG, PNG, WebP or GIF of up to 2 MB: \"Upload one JPEG, PNG, WEBP, or GIF image of up to 2 MB.\"\n- `404` when the dashboard does not exist or you cannot edit it.\n- `429` after 30 uploads in 10 minutes.",
        "parameters": [
          {
            "name": "dashboardId",
            "in": "path",
            "required": true,
            "description": "Id of the dashboard, as returned when it was created.",
            "schema": {
              "type": "string"
            },
            "example": "Db4kX9mQ2pLr"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "binary",
                    "description": "The image file: JPEG, PNG, WebP or GIF, up to 2 MB."
                  }
                },
                "required": [
                  "image"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "imageKey": {
                          "type": "string",
                          "description": "Where the image is stored. Put it on a profile entry as `imageKey` and save the dashboard."
                        },
                        "imageUrl": {
                          "type": "string",
                          "description": "A signed link to preview the image. It expires, so do not store it."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "imageKey": "https://example-bucket.s3.amazonaws.com/dashboard-profiles/abc123.png",
                    "imageUrl": "https://media.example.com/dashboard-profiles/abc123.png?Expires=1767225600&Signature=abc"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Not exactly one JPEG, PNG, WebP or GIF image of up to 2 MB",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 400,
                  "message": "Upload one JPEG, PNG, WEBP, or GIF image of up to 2 MB."
                }
              }
            }
          },
          "404": {
            "description": "The dashboard does not exist or you cannot edit it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "Dashboard not found!"
                }
              }
            }
          },
          "429": {
            "description": "More than 30 uploads in 10 minutes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 429,
                  "message": "You have reached the limit of 30 profile image uploads in 10 minutes. Please wait a few minutes."
                }
              }
            }
          }
        }
      }
    },
    "/embed/media/{mediaId}/labels": {
      "get": {
        "tags": [
          "Shared Links"
        ],
        "summary": "List labels through a share link",
        "operationId": "shared-links-labels-list",
        "description": "Read the labelled passages of a media file through a dashboard share link. Allowed while the dashboard's `labels.isEnabled` is true. Only the labels the dashboard shows are returned (its label groups, or every active label when it lists none). No API key or access token: the share link `token` is the only credential. The media must be in one of the dashboard's folders. Every refusal returns the same `404 {\"message\": \"Not found.\"}`, so a link holder cannot tell which check failed. A media or folder embed token also works here while the embed's `meta.isLabels` is true, for the embed's own media or media in its folders; an embed shows every active label and can never write. Reads are limited to 120 requests a minute per IP address.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "token",
            "in": "query",
            "required": true,
            "description": "The share link token of a dashboard, or of a media or folder embed on the read routes. Up to 200 characters.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "dsh_3kQm9XpL2vRt"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "transcriptRevision": {
                          "type": "integer",
                          "description": "The media's current transcript revision. Send it as `expectedTranscriptRevision` when you label or comment."
                        },
                        "labels": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "labelId": {
                                "type": "string",
                                "description": "Id of the label."
                              },
                              "name": {
                                "type": "string",
                                "description": "Name of the label."
                              },
                              "color": {
                                "type": "string",
                                "description": "Hex colour, such as `#6366f1`."
                              },
                              "description": {
                                "type": "string",
                                "description": "Description of the label."
                              },
                              "parentId": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Id of the label's group, or null."
                              }
                            }
                          },
                          "description": "Name, colour and description of every label used in `mediaLabels`."
                        },
                        "mediaLabels": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "mediaLabelId": {
                                "type": "string",
                                "description": "Id of the labelled passage."
                              },
                              "mediaId": {
                                "type": "string",
                                "description": "Id of the media."
                              },
                              "labelIds": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Labels on the passage."
                              },
                              "anchor": {
                                "type": "object",
                                "properties": {
                                  "startWord": {
                                    "type": "integer",
                                    "description": "Position of the first word."
                                  },
                                  "endWord": {
                                    "type": "integer",
                                    "description": "Position of the last word, inclusive."
                                  },
                                  "exact": {
                                    "type": "string",
                                    "description": "The quoted words, joined by single spaces."
                                  },
                                  "prefix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text before the quote."
                                  },
                                  "suffix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text after the quote."
                                  },
                                  "startInSec": {
                                    "type": "number",
                                    "description": "Start time of the first word, in seconds."
                                  },
                                  "endInSec": {
                                    "type": "number",
                                    "description": "End time of the last word, in seconds."
                                  },
                                  "speakerIds": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    },
                                    "description": "Speakers of the quoted words."
                                  },
                                  "transcriptRevision": {
                                    "type": "integer",
                                    "description": "The transcript revision these positions refer to."
                                  }
                                },
                                "description": "Where the passage sits in the transcript. Built by the server from the word range you send."
                              },
                              "status": {
                                "type": "string",
                                "description": "`active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                                "enum": [
                                  "active",
                                  "shifted",
                                  "needs_review"
                                ]
                              },
                              "lastResolved": {
                                "type": "object",
                                "properties": {
                                  "startWord": {
                                    "type": "integer",
                                    "description": "Position of the first word."
                                  },
                                  "endWord": {
                                    "type": "integer",
                                    "description": "Position of the last word, inclusive."
                                  },
                                  "exact": {
                                    "type": "string",
                                    "description": "The quoted words, joined by single spaces."
                                  },
                                  "prefix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text before the quote."
                                  },
                                  "suffix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text after the quote."
                                  },
                                  "startInSec": {
                                    "type": "number",
                                    "description": "Start time of the first word, in seconds."
                                  },
                                  "endInSec": {
                                    "type": "number",
                                    "description": "End time of the last word, in seconds."
                                  },
                                  "speakerIds": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    },
                                    "description": "Speakers of the quoted words."
                                  },
                                  "transcriptRevision": {
                                    "type": "integer",
                                    "description": "The transcript revision these positions refer to."
                                  }
                                },
                                "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "When it was created.",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "description": "When it last changed.",
                                "format": "date-time"
                              },
                              "authorName": {
                                "type": "string",
                                "description": "The author's display name: the name a share-link viewer wrote as, or the team member's name, or \"Team member\" when a member has none or has left the company."
                              }
                            },
                            "description": "Labels on one passage of a transcript."
                          },
                          "description": "Labelled passages, each narrowed to the labels the link shows. A passage left with none is dropped."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "transcriptRevision": 3,
                        "mediaLabels": [
                          {
                            "mediaLabelId": "Ml5RtB7nZc2GyQs",
                            "mediaId": "b4994aa1267c",
                            "labelIds": [
                              "Lb3NcY8sDf4HqPe"
                            ],
                            "anchor": {
                              "startWord": 42,
                              "endWord": 49,
                              "exact": "we need the pricing sheet by Friday",
                              "prefix": "Before we close the quarter, ",
                              "suffix": ". Can you send it over?",
                              "startInSec": 61.4,
                              "endInSec": 64.2,
                              "speakerIds": [
                                "1"
                              ],
                              "transcriptRevision": 3
                            },
                            "status": "active",
                            "createdAt": "2026-10-06T14:05:12.000Z",
                            "updatedAt": "2026-10-06T14:05:12.000Z",
                            "authorName": "Reviewer A"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A path or query value failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "A path or query value failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "\"status\" must be one of [active, shifted, needs_review]",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Any refusal: unknown or revoked token, expired subscription, the setting is off, view mode on a write, media outside the link, a name that is not allowed, or someone else's entry",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "Not found."
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "example": "Too many requests. Please wait one minute before trying again."
              }
            }
          }
        },
        "security": [],
        "x-doc-group": "Labels on a transcript"
      },
      "post": {
        "tags": [
          "Shared Links"
        ],
        "summary": "Label a passage through a share link",
        "operationId": "shared-links-labels-create",
        "description": "Label a passage through a dashboard share link. Allowed while labels are on with `labels.mode` set to `apply`. Word positions and `expectedTranscriptRevision` work as on `POST /media/{mediaId}/labels`, and a stale revision returns 409. Every label must be one the dashboard offers, or the request returns 400 \"Choose labels this dashboard offers.\" Adding labels to the same words merges only into your own passage from this dashboard. No API key or access token: the share link `token` is the only credential. The media must be in one of the dashboard's folders. Every refusal returns the same `404 {\"message\": \"Not found.\"}`, so a link holder cannot tell which check failed. The entry is recorded under `reviewerName` via this dashboard. The name is chosen by the link holder and not authenticated, the same as feedback; only a name the dashboard allows is accepted. A name can change or delete only the entries written under it from the same dashboard. Writes are limited to 30 requests a minute per IP address.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "token",
            "in": "query",
            "required": true,
            "description": "The share link token of a dashboard, or of a media or folder embed on the read routes. Up to 200 characters.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "dsh_3kQm9XpL2vRt"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reviewerName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "The name you write as: one of `annotationSettings.reviewers`, or any name when `allowOtherReviewer` is true. Chosen by the link holder and not authenticated. Trimmed; a listed name in another case is stored with the listed spelling. Required."
                  },
                  "range": {
                    "type": "object",
                    "properties": {
                      "start": {
                        "type": "integer",
                        "description": "Position of the first word. Integer, 0 or more.",
                        "minimum": 0
                      },
                      "end": {
                        "type": "integer",
                        "description": "Position of the last word, inclusive. Integer, at least `start`. A range that runs past the last word returns 400 \"The selected words are outside this transcript.\"",
                        "minimum": 0
                      }
                    },
                    "required": [
                      "start",
                      "end"
                    ],
                    "description": "Inclusive range of word positions. Word positions count every word of the transcript in order, starting at 0. Within each sentence, words come from `entities` in order (an entity that holds several words, such as \"New York\", counts as several), or from the sentence `text` split on whitespace when the sentence has no entities. A token that is only punctuation is not counted."
                  },
                  "labelIds": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 20,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "pattern": "^[A-Za-z0-9_-]{1,64}$"
                    },
                    "description": "Labels to put on the passage. 1 to 20 ids, no repeats. Each must be an active label (not a group) in your company, or the request returns 400 \"Choose active labels from this workspace (groups cannot be applied).\""
                  },
                  "expectedTranscriptRevision": {
                    "type": "integer",
                    "description": "The `transcriptRevision` you read the transcript at. Integer, 0 or more. A stale value returns 409.",
                    "minimum": 0
                  }
                },
                "required": [
                  "reviewerName",
                  "range",
                  "labelIds",
                  "expectedTranscriptRevision"
                ]
              },
              "example": {
                "reviewerName": "Reviewer A",
                "range": {
                  "start": 42,
                  "end": 49
                },
                "labelIds": [
                  "Lb3NcY8sDf4HqPe"
                ],
                "expectedTranscriptRevision": 3
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "mediaLabelId": {
                          "type": "string",
                          "description": "Id of the labelled passage."
                        },
                        "mediaId": {
                          "type": "string",
                          "description": "Id of the media."
                        },
                        "labelIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Labels on the passage."
                        },
                        "anchor": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "Where the passage sits in the transcript. Built by the server from the word range you send."
                        },
                        "status": {
                          "type": "string",
                          "description": "`active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                          "enum": [
                            "active",
                            "shifted",
                            "needs_review"
                          ]
                        },
                        "lastResolved": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "When it was created.",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "When it last changed.",
                          "format": "date-time"
                        },
                        "authorName": {
                          "type": "string",
                          "description": "The author's display name: the name a share-link viewer wrote as, or the team member's name, or \"Team member\" when a member has none or has left the company."
                        }
                      },
                      "description": "Labels on one passage of a transcript."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "mediaLabelId": "Ml5RtB7nZc2GyQs",
                        "mediaId": "b4994aa1267c",
                        "labelIds": [
                          "Lb3NcY8sDf4HqPe"
                        ],
                        "anchor": {
                          "startWord": 42,
                          "endWord": 49,
                          "exact": "we need the pricing sheet by Friday",
                          "prefix": "Before we close the quarter, ",
                          "suffix": ". Can you send it over?",
                          "startInSec": 61.4,
                          "endInSec": 64.2,
                          "speakerIds": [
                            "1"
                          ],
                          "transcriptRevision": 3
                        },
                        "status": "active",
                        "createdAt": "2026-10-06T14:05:12.000Z",
                        "updatedAt": "2026-10-06T14:05:12.000Z",
                        "authorName": "Reviewer A"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation, range, label or limit problem",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "Validation, range, label or limit problem",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "The selected words are outside this transcript.",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The transcript changed since you read it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-409": {
                    "summary": "The transcript changed since you read it",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 409,
                      "message": "This transcript changed since you opened it. Reload to keep editing.",
                      "hints": [
                        "Please use PUT for update instead of POST",
                        "The requested operation failed because it tried to create a resource that already exists."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Any refusal: unknown or revoked token, expired subscription, the setting is off, view mode on a write, media outside the link, a name that is not allowed, or someone else's entry",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "Not found."
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "example": "Too many requests. Please wait one minute before trying again."
              }
            }
          }
        },
        "security": [],
        "x-doc-group": "Labels on a transcript"
      }
    },
    "/embed/media/{mediaId}/labels/{mediaLabelId}": {
      "patch": {
        "tags": [
          "Shared Links"
        ],
        "summary": "Change a passage's labels through a share link",
        "operationId": "shared-links-labels-update",
        "description": "Replace the labels on your own passage through a dashboard share link. Allowed while labels are on with `labels.mode` set to `apply`. Every label must be one the dashboard offers, or the request returns 400 \"Choose labels this dashboard offers.\" Moving a passage and reviewing re-anchored passages stay in the app. No API key or access token: the share link `token` is the only credential. The media must be in one of the dashboard's folders. Every refusal returns the same `404 {\"message\": \"Not found.\"}`, so a link holder cannot tell which check failed. The entry is recorded under `reviewerName` via this dashboard. The name is chosen by the link holder and not authenticated, the same as feedback; only a name the dashboard allows is accepted. A name can change or delete only the entries written under it from the same dashboard. Writes are limited to 30 requests a minute per IP address.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "mediaLabelId",
            "in": "path",
            "required": true,
            "description": "Id of the labelled passage, from `mediaLabelId`. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "Ml5RtB7nZc2GyQs"
          },
          {
            "name": "token",
            "in": "query",
            "required": true,
            "description": "The share link token of a dashboard, or of a media or folder embed on the read routes. Up to 200 characters.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "dsh_3kQm9XpL2vRt"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reviewerName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "The name you write as: one of `annotationSettings.reviewers`, or any name when `allowOtherReviewer` is true. Chosen by the link holder and not authenticated. Trimmed; a listed name in another case is stored with the listed spelling. Required."
                  },
                  "labelIds": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 20,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "pattern": "^[A-Za-z0-9_-]{1,64}$"
                    },
                    "description": "Labels to put on the passage. 1 to 20 ids, no repeats. Each must be an active label (not a group) in your company, or the request returns 400 \"Choose active labels from this workspace (groups cannot be applied).\""
                  }
                },
                "required": [
                  "reviewerName",
                  "labelIds"
                ]
              },
              "example": {
                "reviewerName": "Reviewer A",
                "labelIds": [
                  "Lb3NcY8sDf4HqPe"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "mediaLabelId": {
                          "type": "string",
                          "description": "Id of the labelled passage."
                        },
                        "mediaId": {
                          "type": "string",
                          "description": "Id of the media."
                        },
                        "labelIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Labels on the passage."
                        },
                        "anchor": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "Where the passage sits in the transcript. Built by the server from the word range you send."
                        },
                        "status": {
                          "type": "string",
                          "description": "`active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                          "enum": [
                            "active",
                            "shifted",
                            "needs_review"
                          ]
                        },
                        "lastResolved": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "When it was created.",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "When it last changed.",
                          "format": "date-time"
                        },
                        "authorName": {
                          "type": "string",
                          "description": "The author's display name: the name a share-link viewer wrote as, or the team member's name, or \"Team member\" when a member has none or has left the company."
                        }
                      },
                      "description": "Labels on one passage of a transcript."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "mediaLabelId": "Ml5RtB7nZc2GyQs",
                        "mediaId": "b4994aa1267c",
                        "labelIds": [
                          "Lb3NcY8sDf4HqPe",
                          "Lb9TmK2vXa6JrWo"
                        ],
                        "anchor": {
                          "startWord": 42,
                          "endWord": 49,
                          "exact": "we need the pricing sheet by Friday",
                          "prefix": "Before we close the quarter, ",
                          "suffix": ". Can you send it over?",
                          "startInSec": 61.4,
                          "endInSec": 64.2,
                          "speakerIds": [
                            "1"
                          ],
                          "transcriptRevision": 3
                        },
                        "status": "active",
                        "createdAt": "2026-10-06T14:05:12.000Z",
                        "updatedAt": "2026-10-06T14:05:12.000Z",
                        "authorName": "Reviewer A"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body broke a rule or failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "The body broke a rule or failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "\"value\" must contain at least one of [labelIds, action]",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The transcript changed since you read it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-409": {
                    "summary": "The transcript changed since you read it",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 409,
                      "message": "This transcript changed since you opened it. Reload to keep editing.",
                      "hints": [
                        "Please use PUT for update instead of POST",
                        "The requested operation failed because it tried to create a resource that already exists."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Any refusal: unknown or revoked token, expired subscription, the setting is off, view mode on a write, media outside the link, a name that is not allowed, or someone else's entry",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "Not found."
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "example": "Too many requests. Please wait one minute before trying again."
              }
            }
          }
        },
        "security": [],
        "x-doc-group": "Labels on a transcript"
      },
      "delete": {
        "tags": [
          "Shared Links"
        ],
        "summary": "Remove a passage through a share link",
        "operationId": "shared-links-labels-delete",
        "description": "Remove your own labelled passage through a dashboard share link. Allowed while labels are on with `labels.mode` set to `apply`. No API key or access token: the share link `token` is the only credential. The media must be in one of the dashboard's folders. Every refusal returns the same `404 {\"message\": \"Not found.\"}`, so a link holder cannot tell which check failed. The entry is recorded under `reviewerName` via this dashboard. The name is chosen by the link holder and not authenticated, the same as feedback; only a name the dashboard allows is accepted. A name can change or delete only the entries written under it from the same dashboard. Writes are limited to 30 requests a minute per IP address.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "mediaLabelId",
            "in": "path",
            "required": true,
            "description": "Id of the labelled passage, from `mediaLabelId`. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "Ml5RtB7nZc2GyQs"
          },
          {
            "name": "token",
            "in": "query",
            "required": true,
            "description": "The share link token of a dashboard, or of a media or folder embed on the read routes. Up to 200 characters.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "dsh_3kQm9XpL2vRt"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "mediaLabelId": {
                          "type": "string",
                          "description": "Id of the passage you removed."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "mediaLabelId": "Ml5RtB7nZc2GyQs"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Any refusal: unknown or revoked token, expired subscription, the setting is off, view mode on a write, media outside the link, a name that is not allowed, or someone else's entry",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "Not found."
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "example": "Too many requests. Please wait one minute before trying again."
              }
            }
          }
        },
        "security": [],
        "x-doc-group": "Labels on a transcript",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reviewerName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "The name you write as: one of `annotationSettings.reviewers`, or any name when `allowOtherReviewer` is true. Chosen by the link holder and not authenticated. Trimmed; a listed name in another case is stored with the listed spelling. Required."
                  }
                },
                "required": [
                  "reviewerName"
                ]
              },
              "example": {
                "reviewerName": "Reviewer A"
              }
            }
          }
        }
      }
    },
    "/embed/media/{mediaId}/comments": {
      "get": {
        "tags": [
          "Shared Links"
        ],
        "summary": "List comments through a share link",
        "operationId": "shared-links-comments-list",
        "description": "Read every comment thread on a media file through a dashboard share link. Allowed while the dashboard's `comments.isEnabled` is true. `resolvedBy` and `mediaLabelId` are left out. No API key or access token: the share link `token` is the only credential. The media must be in one of the dashboard's folders. Every refusal returns the same `404 {\"message\": \"Not found.\"}`, so a link holder cannot tell which check failed. A media or folder embed token also works here while the embed's `meta.isComments` is true, for the embed's own media or media in its folders; an embed shows every active label and can never write. Reads are limited to 120 requests a minute per IP address.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "token",
            "in": "query",
            "required": true,
            "description": "The share link token of a dashboard, or of a media or folder embed on the read routes. Up to 200 characters.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "dsh_3kQm9XpL2vRt"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "transcriptRevision": {
                          "type": "integer",
                          "description": "The media's current transcript revision."
                        },
                        "threads": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "commentId": {
                                "type": "string",
                                "description": "Id of the comment."
                              },
                              "mediaId": {
                                "type": "string",
                                "description": "Id of the media."
                              },
                              "anchor": {
                                "type": "object",
                                "properties": {
                                  "startWord": {
                                    "type": "integer",
                                    "description": "Position of the first word."
                                  },
                                  "endWord": {
                                    "type": "integer",
                                    "description": "Position of the last word, inclusive."
                                  },
                                  "exact": {
                                    "type": "string",
                                    "description": "The quoted words, joined by single spaces."
                                  },
                                  "prefix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text before the quote."
                                  },
                                  "suffix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text after the quote."
                                  },
                                  "startInSec": {
                                    "type": "number",
                                    "description": "Start time of the first word, in seconds."
                                  },
                                  "endInSec": {
                                    "type": "number",
                                    "description": "End time of the last word, in seconds."
                                  },
                                  "speakerIds": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    },
                                    "description": "Speakers of the quoted words."
                                  },
                                  "transcriptRevision": {
                                    "type": "integer",
                                    "description": "The transcript revision these positions refer to."
                                  }
                                },
                                "description": "The passage the comment is on, or `null` for a comment on the whole file. Replies carry `null`.",
                                "nullable": true
                              },
                              "parentId": {
                                "type": "string",
                                "description": "`commentId` of the thread's first comment for a reply, `null` for the first comment.",
                                "nullable": true
                              },
                              "body": {
                                "type": "string",
                                "description": "Comment text. Empty on a deleted first comment that still has replies."
                              },
                              "status": {
                                "type": "string",
                                "description": "Present only on comments with an anchor. `active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                                "enum": [
                                  "active",
                                  "shifted",
                                  "needs_review"
                                ]
                              },
                              "lastResolved": {
                                "type": "object",
                                "properties": {
                                  "startWord": {
                                    "type": "integer",
                                    "description": "Position of the first word."
                                  },
                                  "endWord": {
                                    "type": "integer",
                                    "description": "Position of the last word, inclusive."
                                  },
                                  "exact": {
                                    "type": "string",
                                    "description": "The quoted words, joined by single spaces."
                                  },
                                  "prefix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text before the quote."
                                  },
                                  "suffix": {
                                    "type": "string",
                                    "description": "Up to 32 characters of transcript text after the quote."
                                  },
                                  "startInSec": {
                                    "type": "number",
                                    "description": "Start time of the first word, in seconds."
                                  },
                                  "endInSec": {
                                    "type": "number",
                                    "description": "End time of the last word, in seconds."
                                  },
                                  "speakerIds": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    },
                                    "description": "Speakers of the quoted words."
                                  },
                                  "transcriptRevision": {
                                    "type": "integer",
                                    "description": "The transcript revision these positions refer to."
                                  }
                                },
                                "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                              },
                              "isResolved": {
                                "type": "boolean",
                                "description": "`true` once the thread is resolved. Only set on the first comment of a thread."
                              },
                              "isDeleted": {
                                "type": "boolean",
                                "description": "`true` on a deleted first comment kept because it has replies."
                              },
                              "createdAt": {
                                "type": "string",
                                "description": "When it was posted.",
                                "format": "date-time"
                              },
                              "updatedAt": {
                                "type": "string",
                                "description": "When it last changed.",
                                "format": "date-time"
                              },
                              "replies": {
                                "type": "array",
                                "description": "Replies, oldest first, with the same fields. Deleted replies are left out.",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "commentId": {
                                      "type": "string",
                                      "description": "Id of the comment."
                                    },
                                    "mediaId": {
                                      "type": "string",
                                      "description": "Id of the media."
                                    },
                                    "anchor": {
                                      "type": "object",
                                      "properties": {
                                        "startWord": {
                                          "type": "integer",
                                          "description": "Position of the first word."
                                        },
                                        "endWord": {
                                          "type": "integer",
                                          "description": "Position of the last word, inclusive."
                                        },
                                        "exact": {
                                          "type": "string",
                                          "description": "The quoted words, joined by single spaces."
                                        },
                                        "prefix": {
                                          "type": "string",
                                          "description": "Up to 32 characters of transcript text before the quote."
                                        },
                                        "suffix": {
                                          "type": "string",
                                          "description": "Up to 32 characters of transcript text after the quote."
                                        },
                                        "startInSec": {
                                          "type": "number",
                                          "description": "Start time of the first word, in seconds."
                                        },
                                        "endInSec": {
                                          "type": "number",
                                          "description": "End time of the last word, in seconds."
                                        },
                                        "speakerIds": {
                                          "type": "array",
                                          "items": {
                                            "type": "string"
                                          },
                                          "description": "Speakers of the quoted words."
                                        },
                                        "transcriptRevision": {
                                          "type": "integer",
                                          "description": "The transcript revision these positions refer to."
                                        }
                                      },
                                      "description": "The passage the comment is on, or `null` for a comment on the whole file. Replies carry `null`.",
                                      "nullable": true
                                    },
                                    "parentId": {
                                      "type": "string",
                                      "description": "`commentId` of the thread's first comment for a reply, `null` for the first comment.",
                                      "nullable": true
                                    },
                                    "body": {
                                      "type": "string",
                                      "description": "Comment text. Empty on a deleted first comment that still has replies."
                                    },
                                    "status": {
                                      "type": "string",
                                      "description": "Present only on comments with an anchor. `active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                                      "enum": [
                                        "active",
                                        "shifted",
                                        "needs_review"
                                      ]
                                    },
                                    "lastResolved": {
                                      "type": "object",
                                      "properties": {
                                        "startWord": {
                                          "type": "integer",
                                          "description": "Position of the first word."
                                        },
                                        "endWord": {
                                          "type": "integer",
                                          "description": "Position of the last word, inclusive."
                                        },
                                        "exact": {
                                          "type": "string",
                                          "description": "The quoted words, joined by single spaces."
                                        },
                                        "prefix": {
                                          "type": "string",
                                          "description": "Up to 32 characters of transcript text before the quote."
                                        },
                                        "suffix": {
                                          "type": "string",
                                          "description": "Up to 32 characters of transcript text after the quote."
                                        },
                                        "startInSec": {
                                          "type": "number",
                                          "description": "Start time of the first word, in seconds."
                                        },
                                        "endInSec": {
                                          "type": "number",
                                          "description": "End time of the last word, in seconds."
                                        },
                                        "speakerIds": {
                                          "type": "array",
                                          "items": {
                                            "type": "string"
                                          },
                                          "description": "Speakers of the quoted words."
                                        },
                                        "transcriptRevision": {
                                          "type": "integer",
                                          "description": "The transcript revision these positions refer to."
                                        }
                                      },
                                      "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                                    },
                                    "isResolved": {
                                      "type": "boolean",
                                      "description": "`true` once the thread is resolved. Only set on the first comment of a thread."
                                    },
                                    "isDeleted": {
                                      "type": "boolean",
                                      "description": "`true` on a deleted first comment kept because it has replies."
                                    },
                                    "createdAt": {
                                      "type": "string",
                                      "description": "When it was posted.",
                                      "format": "date-time"
                                    },
                                    "updatedAt": {
                                      "type": "string",
                                      "description": "When it last changed.",
                                      "format": "date-time"
                                    },
                                    "authorName": {
                                      "type": "string",
                                      "description": "The author's display name: the name a share-link viewer wrote as, or the team member's name, or \"Team member\" when a member has none or has left the company."
                                    }
                                  }
                                }
                              },
                              "authorName": {
                                "type": "string",
                                "description": "The author's display name: the name a share-link viewer wrote as, or the team member's name, or \"Team member\" when a member has none or has left the company."
                              }
                            }
                          },
                          "description": "Threads, oldest first."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "transcriptRevision": 3,
                        "threads": [
                          {
                            "commentId": "Cm8WpE3kLv6NdHa",
                            "mediaId": "b4994aa1267c",
                            "anchor": {
                              "startWord": 42,
                              "endWord": 49,
                              "exact": "we need the pricing sheet by Friday",
                              "prefix": "Before we close the quarter, ",
                              "suffix": ". Can you send it over?",
                              "startInSec": 61.4,
                              "endInSec": 64.2,
                              "speakerIds": [
                                "1"
                              ],
                              "transcriptRevision": 3
                            },
                            "parentId": null,
                            "body": "Can we confirm this date with finance?",
                            "status": "active",
                            "isResolved": false,
                            "isDeleted": false,
                            "createdAt": "2026-10-06T14:05:12.000Z",
                            "updatedAt": "2026-10-06T14:05:12.000Z",
                            "replies": [
                              {
                                "commentId": "Cm2YsF9qJt4BxMr",
                                "mediaId": "b4994aa1267c",
                                "anchor": null,
                                "parentId": "Cm8WpE3kLv6NdHa",
                                "body": "Confirmed, Friday works.",
                                "isResolved": false,
                                "isDeleted": false,
                                "createdAt": "2026-10-06T15:20:40.000Z",
                                "updatedAt": "2026-10-06T15:20:40.000Z",
                                "authorName": "Reviewer A"
                              }
                            ],
                            "authorName": "Reviewer A"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A path or query value failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "A path or query value failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "\"filter\" must be one of [all, open, resolved, file]",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Any refusal: unknown or revoked token, expired subscription, the setting is off, view mode on a write, media outside the link, a name that is not allowed, or someone else's entry",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "Not found."
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "example": "Too many requests. Please wait one minute before trying again."
              }
            }
          }
        },
        "security": []
      },
      "post": {
        "tags": [
          "Shared Links"
        ],
        "summary": "Comment through a share link",
        "operationId": "shared-links-comments-create",
        "description": "Start a thread or reply through a dashboard share link. Allowed while comments are on with `comments.mode` set to `reply`. Send `range` with `expectedTranscriptRevision` to comment on a passage, `parentId` to reply, or neither to comment on the whole file. `mediaLabelId` is not accepted here. No API key or access token: the share link `token` is the only credential. The media must be in one of the dashboard's folders. Every refusal returns the same `404 {\"message\": \"Not found.\"}`, so a link holder cannot tell which check failed. The entry is recorded under `reviewerName` via this dashboard. The name is chosen by the link holder and not authenticated, the same as feedback; only a name the dashboard allows is accepted. A name can change or delete only the entries written under it from the same dashboard. Writes are limited to 30 requests a minute per IP address.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "token",
            "in": "query",
            "required": true,
            "description": "The share link token of a dashboard, or of a media or folder embed on the read routes. Up to 200 characters.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "dsh_3kQm9XpL2vRt"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reviewerName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "The name you write as: one of `annotationSettings.reviewers`, or any name when `allowOtherReviewer` is true. Chosen by the link holder and not authenticated. Trimmed; a listed name in another case is stored with the listed spelling. Required."
                  },
                  "body": {
                    "type": "string",
                    "description": "Comment text. Trimmed, then 1 to 5,000 characters.",
                    "minLength": 1,
                    "maxLength": 5000
                  },
                  "range": {
                    "type": "object",
                    "properties": {
                      "start": {
                        "type": "integer",
                        "description": "Position of the first word. Integer, 0 or more.",
                        "minimum": 0
                      },
                      "end": {
                        "type": "integer",
                        "description": "Position of the last word, inclusive. Integer, at least `start`. A range that runs past the last word returns 400 \"The selected words are outside this transcript.\"",
                        "minimum": 0
                      }
                    },
                    "required": [
                      "start",
                      "end"
                    ],
                    "description": "The passage to comment on. Send it with `expectedTranscriptRevision`; leave both out for a whole-file comment. Not allowed on a reply. Inclusive range of word positions. Word positions count every word of the transcript in order, starting at 0. Within each sentence, words come from `entities` in order (an entity that holds several words, such as \"New York\", counts as several), or from the sentence `text` split on whitespace when the sentence has no entities. A token that is only punctuation is not counted."
                  },
                  "expectedTranscriptRevision": {
                    "type": "integer",
                    "description": "Required when you send `range`, not allowed without it. The `transcriptRevision` you read the transcript at. Integer, 0 or more. A stale value returns 409.",
                    "minimum": 0
                  },
                  "parentId": {
                    "type": "string",
                    "description": "`commentId` of the thread's first comment, to post a reply. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
                    "pattern": "^[A-Za-z0-9_-]{1,64}$"
                  }
                },
                "required": [
                  "reviewerName",
                  "body"
                ]
              },
              "example": {
                "reviewerName": "Reviewer A",
                "body": "Can we confirm this date with finance?",
                "range": {
                  "start": 42,
                  "end": 49
                },
                "expectedTranscriptRevision": 3
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "commentId": {
                          "type": "string",
                          "description": "Id of the comment."
                        },
                        "mediaId": {
                          "type": "string",
                          "description": "Id of the media."
                        },
                        "anchor": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "The passage the comment is on, or `null` for a comment on the whole file. Replies carry `null`.",
                          "nullable": true
                        },
                        "parentId": {
                          "type": "string",
                          "description": "`commentId` of the thread's first comment for a reply, `null` for the first comment.",
                          "nullable": true
                        },
                        "body": {
                          "type": "string",
                          "description": "Comment text. Empty on a deleted first comment that still has replies."
                        },
                        "status": {
                          "type": "string",
                          "description": "Present only on comments with an anchor. `active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                          "enum": [
                            "active",
                            "shifted",
                            "needs_review"
                          ]
                        },
                        "lastResolved": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                        },
                        "isResolved": {
                          "type": "boolean",
                          "description": "`true` once the thread is resolved. Only set on the first comment of a thread."
                        },
                        "isDeleted": {
                          "type": "boolean",
                          "description": "`true` on a deleted first comment kept because it has replies."
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "When it was posted.",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "When it last changed.",
                          "format": "date-time"
                        },
                        "authorName": {
                          "type": "string",
                          "description": "The author's display name: the name a share-link viewer wrote as, or the team member's name, or \"Team member\" when a member has none or has left the company."
                        }
                      },
                      "description": "A comment."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "commentId": "Cm8WpE3kLv6NdHa",
                        "mediaId": "b4994aa1267c",
                        "anchor": {
                          "startWord": 42,
                          "endWord": 49,
                          "exact": "we need the pricing sheet by Friday",
                          "prefix": "Before we close the quarter, ",
                          "suffix": ". Can you send it over?",
                          "startInSec": 61.4,
                          "endInSec": 64.2,
                          "speakerIds": [
                            "1"
                          ],
                          "transcriptRevision": 3
                        },
                        "parentId": null,
                        "body": "Can we confirm this date with finance?",
                        "status": "active",
                        "isResolved": false,
                        "isDeleted": false,
                        "createdAt": "2026-10-06T14:05:12.000Z",
                        "updatedAt": "2026-10-06T14:05:12.000Z",
                        "authorName": "Reviewer A"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation, reply depth, range or limit problem",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "Validation, reply depth, range or limit problem",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "Replies can only be added to the first comment in a thread.",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The transcript changed since you read it",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-409": {
                    "summary": "The transcript changed since you read it",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 409,
                      "message": "This transcript changed since you opened it. Reload to keep editing.",
                      "hints": [
                        "Please use PUT for update instead of POST",
                        "The requested operation failed because it tried to create a resource that already exists."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Any refusal: unknown or revoked token, expired subscription, the setting is off, view mode on a write, media outside the link, a name that is not allowed, or someone else's entry",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "Not found."
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "example": "Too many requests. Please wait one minute before trying again."
              }
            }
          }
        },
        "security": []
      }
    },
    "/embed/media/{mediaId}/comments/{commentId}": {
      "patch": {
        "tags": [
          "Shared Links"
        ],
        "summary": "Edit a comment through a share link",
        "operationId": "shared-links-comments-update",
        "description": "Edit the text of your own comment through a dashboard share link. Allowed while comments are on with `comments.mode` set to `reply`. Resolving threads stays in the app. No API key or access token: the share link `token` is the only credential. The media must be in one of the dashboard's folders. Every refusal returns the same `404 {\"message\": \"Not found.\"}`, so a link holder cannot tell which check failed. The entry is recorded under `reviewerName` via this dashboard. The name is chosen by the link holder and not authenticated, the same as feedback; only a name the dashboard allows is accepted. A name can change or delete only the entries written under it from the same dashboard. Writes are limited to 30 requests a minute per IP address.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "commentId",
            "in": "path",
            "required": true,
            "description": "Id of the comment. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "Cm8WpE3kLv6NdHa"
          },
          {
            "name": "token",
            "in": "query",
            "required": true,
            "description": "The share link token of a dashboard, or of a media or folder embed on the read routes. Up to 200 characters.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "dsh_3kQm9XpL2vRt"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reviewerName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "The name you write as: one of `annotationSettings.reviewers`, or any name when `allowOtherReviewer` is true. Chosen by the link holder and not authenticated. Trimmed; a listed name in another case is stored with the listed spelling. Required."
                  },
                  "body": {
                    "type": "string",
                    "description": "New text. Author only. Comment text. Trimmed, then 1 to 5,000 characters.",
                    "minLength": 1,
                    "maxLength": 5000
                  }
                },
                "required": [
                  "reviewerName",
                  "body"
                ]
              },
              "example": {
                "reviewerName": "Reviewer A",
                "body": "Agreed, follow up on pricing."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "commentId": {
                          "type": "string",
                          "description": "Id of the comment."
                        },
                        "mediaId": {
                          "type": "string",
                          "description": "Id of the media."
                        },
                        "anchor": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "The passage the comment is on, or `null` for a comment on the whole file. Replies carry `null`.",
                          "nullable": true
                        },
                        "parentId": {
                          "type": "string",
                          "description": "`commentId` of the thread's first comment for a reply, `null` for the first comment.",
                          "nullable": true
                        },
                        "body": {
                          "type": "string",
                          "description": "Comment text. Empty on a deleted first comment that still has replies."
                        },
                        "status": {
                          "type": "string",
                          "description": "Present only on comments with an anchor. `active`: the same words, possibly at new positions after an edit. `shifted`: most of the words survived an edit near the same time, but the text changed. `needs_review`: the words changed too much to follow; `anchor` then holds a suggested passage on the new transcript and `lastResolved` the last position a person confirmed.",
                          "enum": [
                            "active",
                            "shifted",
                            "needs_review"
                          ]
                        },
                        "lastResolved": {
                          "type": "object",
                          "properties": {
                            "startWord": {
                              "type": "integer",
                              "description": "Position of the first word."
                            },
                            "endWord": {
                              "type": "integer",
                              "description": "Position of the last word, inclusive."
                            },
                            "exact": {
                              "type": "string",
                              "description": "The quoted words, joined by single spaces."
                            },
                            "prefix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text before the quote."
                            },
                            "suffix": {
                              "type": "string",
                              "description": "Up to 32 characters of transcript text after the quote."
                            },
                            "startInSec": {
                              "type": "number",
                              "description": "Start time of the first word, in seconds."
                            },
                            "endInSec": {
                              "type": "number",
                              "description": "End time of the last word, in seconds."
                            },
                            "speakerIds": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Speakers of the quoted words."
                            },
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "The transcript revision these positions refer to."
                            }
                          },
                          "description": "Present only while `status` is `needs_review`: the last position a person confirmed."
                        },
                        "isResolved": {
                          "type": "boolean",
                          "description": "`true` once the thread is resolved. Only set on the first comment of a thread."
                        },
                        "isDeleted": {
                          "type": "boolean",
                          "description": "`true` on a deleted first comment kept because it has replies."
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "When it was posted.",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "When it last changed.",
                          "format": "date-time"
                        },
                        "authorName": {
                          "type": "string",
                          "description": "The author's display name: the name a share-link viewer wrote as, or the team member's name, or \"Team member\" when a member has none or has left the company."
                        }
                      },
                      "description": "A comment."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "commentId": "Cm8WpE3kLv6NdHa",
                        "mediaId": "b4994aa1267c",
                        "anchor": {
                          "startWord": 42,
                          "endWord": 49,
                          "exact": "we need the pricing sheet by Friday",
                          "prefix": "Before we close the quarter, ",
                          "suffix": ". Can you send it over?",
                          "startInSec": 61.4,
                          "endInSec": 64.2,
                          "speakerIds": [
                            "1"
                          ],
                          "transcriptRevision": 3
                        },
                        "parentId": null,
                        "body": "Can we confirm this date with finance?",
                        "status": "active",
                        "isResolved": true,
                        "isDeleted": false,
                        "createdAt": "2026-10-06T14:05:12.000Z",
                        "updatedAt": "2026-10-06T16:30:00.000Z",
                        "resolvedBy": "65f0c1a2b3c4d5e6f7a8b9c0",
                        "authorName": "Reviewer A"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body broke a rule or failed validation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "examples": {
                  "error-400": {
                    "summary": "The body broke a rule or failed validation",
                    "value": {
                      "status": "failed",
                      "requestId": "req_0000000000000000",
                      "code": 400,
                      "message": "Only the first comment in a thread can be resolved.",
                      "hints": [
                        "The API request is invalid or improperly formed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Any refusal: unknown or revoked token, expired subscription, the setting is off, view mode on a write, media outside the link, a name that is not allowed, or someone else's entry",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "Not found."
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "example": "Too many requests. Please wait one minute before trying again."
              }
            }
          }
        },
        "security": []
      },
      "delete": {
        "tags": [
          "Shared Links"
        ],
        "summary": "Delete a comment through a share link",
        "operationId": "shared-links-comments-delete",
        "description": "Delete your own comment through a dashboard share link. Allowed while comments are on with `comments.mode` set to `reply`. No API key or access token: the share link `token` is the only credential. The media must be in one of the dashboard's folders. Every refusal returns the same `404 {\"message\": \"Not found.\"}`, so a link holder cannot tell which check failed. The entry is recorded under `reviewerName` via this dashboard. The name is chosen by the link holder and not authenticated, the same as feedback; only a name the dashboard allows is accepted. A name can change or delete only the entries written under it from the same dashboard. Writes are limited to 30 requests a minute per IP address.",
        "parameters": [
          {
            "name": "mediaId",
            "in": "path",
            "required": true,
            "description": "Id of the media file. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "b4994aa1267c"
          },
          {
            "name": "commentId",
            "in": "path",
            "required": true,
            "description": "Id of the comment. Trimmed, then 1 to 64 characters from `A-Z`, `a-z`, `0-9`, `_` and `-` (pattern `^[A-Za-z0-9_-]{1,64}$`). Anything else returns 400.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,64}$",
              "maxLength": 64
            },
            "example": "Cm8WpE3kLv6NdHa"
          },
          {
            "name": "token",
            "in": "query",
            "required": true,
            "description": "The share link token of a dashboard, or of a media or folder embed on the read routes. Up to 200 characters.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "dsh_3kQm9XpL2vRt"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "commentId": {
                          "type": "string",
                          "description": "Id of the comment you deleted."
                        }
                      },
                      "description": "The result."
                    }
                  }
                },
                "examples": {
                  "success": {
                    "summary": "Success",
                    "value": {
                      "status": "success",
                      "data": {
                        "commentId": "Cm8WpE3kLv6NdHa"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Any refusal: unknown or revoked token, expired subscription, the setting is off, view mode on a write, media outside the link, a name that is not allowed, or someone else's entry",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "Not found."
                }
              }
            }
          },
          "429": {
            "description": "Rate limit reached",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                },
                "example": "Too many requests. Please wait one minute before trying again."
              }
            }
          }
        },
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reviewerName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "The name you write as: one of `annotationSettings.reviewers`, or any name when `allowOtherReviewer` is true. Chosen by the link holder and not authenticated. Trimmed; a listed name in another case is stored with the listed spelling. Required."
                  }
                },
                "required": [
                  "reviewerName"
                ]
              },
              "example": {
                "reviewerName": "Reviewer A"
              }
            }
          }
        }
      }
    },
    "/embed/dashboards/config": {
      "get": {
        "tags": [
          "Shared Links"
        ],
        "summary": "Read a shared dashboard's layout and annotation settings",
        "operationId": "shared-links-dashboard-config",
        "description": "Read what a dashboard share link renders before any media is opened: its title, sections, widgets and `annotationSettings`, which lists the labels the \"has label\" filter may offer. No API key or access token: the `token` is the only credential. Changes to the dashboard's settings reach the link within about 15 seconds.",
        "security": [],
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "description": "The share link token of a dashboard, or of a media or folder embed on the read routes. Up to 200 characters.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "dsh_3kQm9XpL2vRt"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "description": "The dashboard's public layout. Only the keys relevant to labels and comments are listed here.",
                      "properties": {
                        "title": {
                          "type": "string",
                          "description": "Dashboard title."
                        },
                        "annotationSettings": {
                          "type": "object",
                          "description": "What the link allows for labels and comments, resolved from the dashboard's settings.",
                          "properties": {
                            "labels": {
                              "type": "object",
                              "properties": {
                                "isEnabled": {
                                  "type": "boolean",
                                  "description": "Whether labels are on."
                                },
                                "mode": {
                                  "type": "string",
                                  "enum": [
                                    "view",
                                    "apply"
                                  ],
                                  "description": "`view` or `apply`."
                                },
                                "groups": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "labelId": {
                                        "type": "string"
                                      },
                                      "name": {
                                        "type": "string"
                                      }
                                    }
                                  },
                                  "description": "The allowed label groups. Empty while labels are off."
                                },
                                "labels": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "labelId": {
                                        "type": "string",
                                        "description": "Id of the label."
                                      },
                                      "name": {
                                        "type": "string",
                                        "description": "Name of the label."
                                      },
                                      "color": {
                                        "type": "string",
                                        "description": "Hex colour, such as `#6366f1`."
                                      },
                                      "description": {
                                        "type": "string",
                                        "description": "Description of the label."
                                      },
                                      "parentId": {
                                        "type": [
                                          "string",
                                          "null"
                                        ],
                                        "description": "Id of the label's group, or null."
                                      }
                                    }
                                  },
                                  "description": "Active labels of the allowed groups. Empty while labels are off."
                                }
                              }
                            },
                            "comments": {
                              "type": "object",
                              "properties": {
                                "isEnabled": {
                                  "type": "boolean",
                                  "description": "Whether comments are on."
                                },
                                "mode": {
                                  "type": "string",
                                  "enum": [
                                    "view",
                                    "reply"
                                  ],
                                  "description": "`view` or `reply`."
                                }
                              }
                            },
                            "reviewers": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Names a viewer may write as, sent as `reviewerName`: the dashboard's feedback submitter names. Empty unless `apply` or `reply` mode is on."
                            },
                            "allowOtherReviewer": {
                              "type": "boolean",
                              "description": "A viewer may also type a name that is not listed. True when the dashboard's `feedback.allowOtherSubmitter` is on and `apply` or `reply` mode is on."
                            }
                          }
                        },
                        "version": {
                          "type": "string",
                          "description": "Changes whenever the dashboard changes."
                        }
                      },
                      "additionalProperties": true
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "title": "Sales calls",
                    "annotationSettings": {
                      "labels": {
                        "isEnabled": true,
                        "mode": "apply",
                        "groups": [
                          {
                            "labelId": "Gr7kQ2pLm9xZ",
                            "name": "Objections"
                          }
                        ],
                        "labels": [
                          {
                            "labelId": "Lb3NcY8sDf4HqPe",
                            "name": "Pricing",
                            "color": "#6366f1",
                            "description": "",
                            "parentId": "Gr7kQ2pLm9xZ"
                          }
                        ]
                      },
                      "comments": {
                        "isEnabled": true,
                        "mode": "reply"
                      },
                      "reviewers": [
                        "Reviewer A"
                      ],
                      "allowOtherReviewer": false
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown or revoked token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "Dashboard not found!"
                }
              }
            }
          }
        }
      }
    },
    "/embed/insight": {
      "get": {
        "tags": [
          "Shared Links"
        ],
        "summary": "Read a shared media page",
        "operationId": "shared-links-media-insight",
        "description": "Read the media page a share link opens: the media, its transcript and insights. For a dashboard link it also carries `annotationSettings`, and the media must be in one of the dashboard's folders. `mediaData.transcriptRevision` is read with the transcript: place labels and comments only while it matches the `transcriptRevision` from the labels and comments routes, and read again otherwise. This response is never cached. No API key or access token: the `token` is the only credential.",
        "security": [],
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "description": "The share link token of a dashboard, or of a media or folder embed on the read routes. Up to 200 characters.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "dsh_3kQm9XpL2vRt"
          },
          {
            "name": "mediaId",
            "in": "query",
            "required": false,
            "description": "The media to open. Required for a dashboard link.",
            "schema": {
              "type": "string"
            },
            "example": "b4994aa1267c"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "description": "The media page. Only the keys relevant to labels, comments and the thumbnail are listed here.",
                      "properties": {
                        "mediaData": {
                          "type": "object",
                          "properties": {
                            "transcriptRevision": {
                              "type": "integer",
                              "description": "Revision of the transcript in this response. 0 for media saved before revisions existed."
                            },
                            "thumbnailUrl": {
                              "type": "string",
                              "description": "A signed link to the video's thumbnail, custom or automatic. Present only when the file has one. It expires, so do not store it."
                            }
                          },
                          "additionalProperties": true
                        },
                        "annotationSettings": {
                          "type": "object",
                          "description": "What the link allows for labels and comments, resolved from the dashboard's settings. Present for dashboard links only.",
                          "properties": {
                            "labels": {
                              "type": "object",
                              "properties": {
                                "isEnabled": {
                                  "type": "boolean",
                                  "description": "Whether labels are on."
                                },
                                "mode": {
                                  "type": "string",
                                  "enum": [
                                    "view",
                                    "apply"
                                  ],
                                  "description": "`view` or `apply`."
                                },
                                "groups": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "labelId": {
                                        "type": "string"
                                      },
                                      "name": {
                                        "type": "string"
                                      }
                                    }
                                  },
                                  "description": "The allowed label groups. Empty while labels are off."
                                },
                                "labels": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "labelId": {
                                        "type": "string",
                                        "description": "Id of the label."
                                      },
                                      "name": {
                                        "type": "string",
                                        "description": "Name of the label."
                                      },
                                      "color": {
                                        "type": "string",
                                        "description": "Hex colour, such as `#6366f1`."
                                      },
                                      "description": {
                                        "type": "string",
                                        "description": "Description of the label."
                                      },
                                      "parentId": {
                                        "type": [
                                          "string",
                                          "null"
                                        ],
                                        "description": "Id of the label's group, or null."
                                      }
                                    }
                                  },
                                  "description": "Active labels of the allowed groups. Empty while labels are off."
                                }
                              }
                            },
                            "comments": {
                              "type": "object",
                              "properties": {
                                "isEnabled": {
                                  "type": "boolean",
                                  "description": "Whether comments are on."
                                },
                                "mode": {
                                  "type": "string",
                                  "enum": [
                                    "view",
                                    "reply"
                                  ],
                                  "description": "`view` or `reply`."
                                }
                              }
                            },
                            "reviewers": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Names a viewer may write as, sent as `reviewerName`: the dashboard's feedback submitter names. Empty unless `apply` or `reply` mode is on."
                            },
                            "allowOtherReviewer": {
                              "type": "boolean",
                              "description": "A viewer may also type a name that is not listed. True when the dashboard's `feedback.allowOtherSubmitter` is on and `apply` or `reply` mode is on."
                            }
                          }
                        }
                      },
                      "additionalProperties": true
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "mediaData": {
                      "transcriptRevision": 3
                    },
                    "annotationSettings": {
                      "labels": {
                        "isEnabled": true,
                        "mode": "apply",
                        "groups": [
                          {
                            "labelId": "Gr7kQ2pLm9xZ",
                            "name": "Objections"
                          }
                        ],
                        "labels": [
                          {
                            "labelId": "Lb3NcY8sDf4HqPe",
                            "name": "Pricing",
                            "color": "#6366f1",
                            "description": "",
                            "parentId": "Gr7kQ2pLm9xZ"
                          }
                        ]
                      },
                      "comments": {
                        "isEnabled": true,
                        "mode": "reply"
                      },
                      "reviewers": [
                        "Reviewer A"
                      ],
                      "allowOtherReviewer": false
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The media is not in the dashboard's folders",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 403,
                  "message": "This media is not part of the shared dashboard."
                }
              }
            }
          },
          "404": {
            "description": "Unknown token or no active subscription",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`failed`.",
                      "enum": [
                        "failed"
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "description": "Id of this request, for support."
                    },
                    "code": {
                      "type": "integer",
                      "description": "The HTTP status code again."
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, in words you can show to a person."
                    },
                    "hints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Generic hints for this kind of error."
                    }
                  }
                },
                "example": {
                  "status": "failed",
                  "code": 404,
                  "message": "No embeddable details found"
                }
              }
            }
          }
        }
      }
    },
    "/notification": {
      "get": {
        "tags": [
          "Notifications"
        ],
        "summary": "List notifications",
        "operationId": "notifications-list",
        "description": "Returns your company's in-app notifications, newest first, a page at a time. The Speak app shows the same list under **Notifications**.\n\n#### Who sees what\n\nAn owner sees every notification in the company. A member of one or more user groups sees their own notifications, the ones written for the people in those groups, and the ones assigned to those groups. Anyone else sees every notification in the company. `filterUserId` narrows the list to one person.\n\n`totalUnReadCount` always counts only your own unread notifications, whatever filters you send.\n\n#### Categories and actions\n\n`type` is the category of a notification and `action` is what happened. Send either as a filter. An unknown `type` is ignored and returns every category, while an unknown `action` matches nothing.\n\n#### Labels and comments\n\n- **Label library**: creating, editing, archiving, restoring or merging a label, or adding Speak label sets, writes `type` `label` with `mediaType` `label` for the person who made the change. `mediaId` holds the `labelId`.\n- **Labels on a transcript**: applying, changing or removing labels writes `type` `label` with actions `created`, `updated` or `deleted`. `mediaId` and `mediaType` name the file.\n- **Comments**: adding, editing, resolving, reopening or deleting a comment writes `type` `comment` for the person who did it, with actions `created`, `updated`, `resolved`, `reopened` or `deleted`.\n- **Thread starters**: the person who started a thread also gets a `comment` notification when someone else replies (`replied`), resolves it (`resolved`) or reopens it (`reopened`). They are not told about their own replies, and people who are no longer active members are not told.\n- **Dashboard share links**: turning labels or comments on or off on a dashboard's share link, or changing its modes or reviewer names, writes `type` `dashboard` with `mediaType` `dashboard`, and `mediaId` holds the `dashboardId`.\n\nChanges made through a dashboard share link are written for the link's owner and end with \"by <name> from a shared dashboard\".",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page to return, counting from 0. Leave it out for the first page.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "example": 0
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "description": "Notifications per page. Leave it out for 50.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 50
            },
            "example": 50
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Only this category. One of the `type` values listed in the response schema, such as `label`, `comment` or `dashboard`. Any other value is ignored.",
            "schema": {
              "type": "string",
              "enum": [
                "clip",
                "audio",
                "account",
                "automation",
                "embed",
                "integration",
                "magic prompt",
                "media",
                "payment",
                "presentation",
                "recorder",
                "survey",
                "subscription",
                "team",
                "text",
                "transcription",
                "translate",
                "video",
                "zapier",
                "meeting assistant",
                "google calendar",
                "outlook calendar",
                "auto reload",
                "folder",
                "fields",
                "assistant template",
                "knowledge base",
                "label",
                "comment",
                "dashboard"
              ]
            },
            "example": "comment"
          },
          {
            "name": "action",
            "in": "query",
            "required": false,
            "description": "Only this action, such as `replied`, `resolved` or `reopened`. Matched exactly.",
            "schema": {
              "type": "string",
              "enum": [
                "analyzed",
                "created",
                "credit",
                "debit",
                "deleted",
                "export",
                "paid",
                "updated",
                "uploaded",
                "error",
                "failed",
                "cloned",
                "replied",
                "archived",
                "restored",
                "merged",
                "resolved",
                "reopened"
              ]
            },
            "example": "replied"
          },
          {
            "name": "description",
            "in": "query",
            "required": false,
            "description": "Text to look for in the description, ignoring case.",
            "schema": {
              "type": "string"
            },
            "example": "Customer call"
          },
          {
            "name": "filterUserId",
            "in": "query",
            "required": false,
            "description": "Only notifications written for this user id.",
            "schema": {
              "type": "string"
            },
            "example": "65f0c1a2b3c4d5e6f7a8b9c0"
          },
          {
            "name": "startDate",
            "in": "query",
            "required": false,
            "description": "Start of a date range on `createdAt`. Applied only together with `endDate`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-01T00:00:00.000Z"
          },
          {
            "name": "endDate",
            "in": "query",
            "required": false,
            "description": "End of a date range on `createdAt`. Applied only together with `startDate`.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-07T23:59:59.000Z"
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Field to sort by. Leave it out to sort by `createdAt`, newest first. Any other value is ignored.",
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "description",
                "type",
                "isRead"
              ]
            },
            "example": "createdAt"
          },
          {
            "name": "sortDir",
            "in": "query",
            "required": false,
            "description": "`asc` for ascending. Anything else sorts descending.",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            },
            "example": "desc"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "totalCount": {
                          "type": "integer",
                          "description": "How many notifications match the filters, across all pages."
                        },
                        "totalUnReadCount": {
                          "type": "integer",
                          "description": "How many of your own notifications are unread."
                        },
                        "notificationList": {
                          "type": "array",
                          "description": "This page of notifications.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "_id": {
                                "type": "string",
                                "description": "Id of the notification."
                              },
                              "mediaId": {
                                "type": "string",
                                "description": "Id of what the notification is about: a media file, or a `labelId` when `mediaType` is `label`, or a `dashboardId` when `mediaType` is `dashboard`. Left out when it is about nothing in particular."
                              },
                              "mediaType": {
                                "type": "string",
                                "description": "What kind of thing `mediaId` names: `audio`, `video` or `text` for a file, `label` for a label or group, `dashboard` for a dashboard. Left out when there is no `mediaId`."
                              },
                              "description": {
                                "type": "string",
                                "description": "What happened, in words you can show to a person."
                              },
                              "type": {
                                "type": "string",
                                "description": "Category.",
                                "enum": [
                                  "clip",
                                  "audio",
                                  "account",
                                  "automation",
                                  "embed",
                                  "integration",
                                  "magic prompt",
                                  "media",
                                  "payment",
                                  "presentation",
                                  "recorder",
                                  "survey",
                                  "subscription",
                                  "team",
                                  "text",
                                  "transcription",
                                  "translate",
                                  "video",
                                  "zapier",
                                  "meeting assistant",
                                  "google calendar",
                                  "outlook calendar",
                                  "auto reload",
                                  "folder",
                                  "fields",
                                  "assistant template",
                                  "knowledge base",
                                  "label",
                                  "comment",
                                  "dashboard"
                                ]
                              },
                              "action": {
                                "type": "string",
                                "description": "What happened.",
                                "enum": [
                                  "analyzed",
                                  "created",
                                  "credit",
                                  "debit",
                                  "deleted",
                                  "export",
                                  "paid",
                                  "updated",
                                  "uploaded",
                                  "error",
                                  "failed",
                                  "cloned",
                                  "replied",
                                  "archived",
                                  "restored",
                                  "merged",
                                  "resolved",
                                  "reopened"
                                ]
                              },
                              "amount": {
                                "type": "number",
                                "description": "Amount on payment and credit notifications."
                              },
                              "transactionType": {
                                "type": "string",
                                "description": "How a payment was made, on payment notifications."
                              },
                              "isRead": {
                                "type": "boolean",
                                "description": "`true` once marked as read."
                              },
                              "createdAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "When it was written."
                              },
                              "updatedAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "When it last changed."
                              },
                              "user": {
                                "type": "object",
                                "description": "The person the notification was written for. Left out when that user no longer exists.",
                                "properties": {
                                  "_id": {
                                    "type": "string",
                                    "description": "User id."
                                  },
                                  "firstName": {
                                    "type": "string",
                                    "description": "First name."
                                  },
                                  "lastName": {
                                    "type": "string",
                                    "description": "Last name."
                                  },
                                  "picture": {
                                    "type": "string",
                                    "description": "Profile picture URL, when set."
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "comment-replies": {
                    "summary": "Replies to your comments",
                    "value": {
                      "status": "success",
                      "data": {
                        "totalCount": 1,
                        "totalUnReadCount": 3,
                        "notificationList": [
                          {
                            "_id": "6702b1f0c3a4d5e6f7a8b9c1",
                            "mediaId": "d8c2a1f4e5b6",
                            "mediaType": "audio",
                            "description": "Ana Reviewer replied to your comment on \"Customer call\"",
                            "type": "comment",
                            "action": "replied",
                            "isRead": false,
                            "createdAt": "2026-10-07T15:20:00.000Z",
                            "updatedAt": "2026-10-07T15:20:00.000Z",
                            "user": {
                              "_id": "65f0c1a2b3c4d5e6f7a8b9c0",
                              "firstName": "Alex",
                              "lastName": "Lee"
                            }
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Notifications"
      },
      "put": {
        "tags": [
          "Notifications"
        ],
        "summary": "Mark notifications as read",
        "operationId": "notifications-mark-read",
        "description": "Marks every one of your own notifications as read, so `totalUnReadCount` drops to 0. It takes no body and does not touch anyone else's notifications.",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "`success` on every 2xx response.",
                      "enum": [
                        "success"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "Confirmation."
                    }
                  }
                },
                "examples": {
                  "marked": {
                    "summary": "Marked as read",
                    "value": {
                      "status": "success",
                      "message": "Notifications flag is updated successfully."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": [],
            "AccessTokenAuth": []
          }
        ],
        "x-doc-group": "Notifications"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-speakai-key",
        "description": "Your Speak AI API key, from the developer page in your Speak AI account."
      },
      "AccessTokenAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-access-token",
        "description": "The access token returned by POST /auth/accessToken. Expires after 80 minutes."
      }
    }
  }
}