openapi: 3.0.0 info: title: Agent Management API version: 1.0.0 description: API for managing agents, their templates, and call logs paths: /user: get: summary: Get user details tags: - User security: - BearerAuth: [] responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: _id: type: string description: The ID of the user firstName: type: string description: The first name of the user lastName: type: string description: The last name of the user userEmail: type: string description: The email of the user authProvider: type: string description: The authentication provider of the user isEmailVerified: type: boolean description: Whether the user's email is verified organizationId: type: string description: The organization ID of the user "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /organization: get: summary: Get organization details tags: - Organization security: - BearerAuth: [] responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: _id: type: string description: The organization ID name: type: string description: The organization name members: type: array items: type: object properties: _id: type: string description: The member ID userEmail: type: string description: The member email subscription: type: object properties: planId: type: string description: The subscription plan ID "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/template: get: summary: Get agent templates x-fern-sdk-group-name: agent_templates x-fern-sdk-method-name: list_agent_templates tags: - Agent Templates security: - BearerAuth: [] parameters: - name: region in: query required: false description: Filter templates by region. Omit to return all templates. schema: type: string enum: - us - in responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: array items: type: object properties: _id: type: string description: Stable unique identifier for the template (24-character hex string, e.g. `6942a64ac74fc65e7bc94e47`). Surfaced as `object_id` in the generated SDK to keep it distinct from the human-readable `id` slug. x-fern-property-name: object_id id: type: string description: Human-readable slug for the agent template (e.g. `sp-medical-centre-receptionist-in`). Distinct from `_id`. name: type: string description: The name of the agent template description: type: string description: The description of the agent template avatarUrl: type: string description: The avatar URL of the agent template referenceUrl: type: string description: The docs URL of the agent template industry: type: string description: The industry the template is designed for (e.g. "Finance", "Healthcare") useCase: type: string description: The use case the template addresses (e.g. "Lead Generation") callType: type: string description: The type of calls the template handles enum: - Inbound - Outbound - Both workflowType: type: string description: The workflow architecture of the template enum: - SINGLE_PROMPT - WORKFLOW_GRAPH region: type: string description: Human-readable region the template is available in enum: - India - US trending: type: boolean description: Whether the template is featured or trending defaultLanguage: type: string description: The default language configured in the template enum: - English - Hindi - Marathi - Gujarati singlePromptConfig: type: object description: Configuration for single-prompt agents properties: _id: type: string description: Auto-generated unique identifier for the embedded single-prompt config (24-character hex string). Always present when `singlePromptConfig` is set. Surfaced as `object_id` in the generated SDK. x-fern-property-name: object_id prompt: type: string description: The system prompt used by the agent tools: type: array description: Tools available to the agent items: type: object properties: type: type: string description: The tool type — drives runtime dispatch. enum: - end_call - transfer_call - api_call - extract_dynamic_variables - knowledge_base_search name: type: string description: The name of the tool description: type: string description: What the tool does input_schema: type: object description: JSON Schema describing the tool's input parameters "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "400": $ref: "#/components/responses/BadRequestError" "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/from-template: post: summary: Create agent from template tags: - Agent Templates security: - BearerAuth: [] description: We have created templates for some common use cases. You can use these templates to create an agent. For getting list of templates, you can use the /agent/template endpoint. It will give you the list of templates with their description and id. You can pass the id of the template in the request body to create an agent from the template. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateAgentFromTemplateRequest" responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: string example: "60d0fe4f5311236168a109ca" description: The ID of the created agent "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent: get: summary: Get all agents x-fern-sdk-group-name: agents x-fern-sdk-method-name: list_agents tags: - Agents security: - BearerAuth: [] description: Agents are the main entities in the system. Agents are used to create conversations. You can create workflow for an agent and configure it for different use cases. You can also create custom workflows for an agent. This API will give you the list of agents created by organization you are a part of. parameters: - in: query name: page schema: type: integer default: 1 description: Page number - in: query name: offset schema: type: integer default: 10 description: Number of items to return per page - in: query name: search schema: type: string description: Search query - in: query name: type required: false schema: type: string enum: - single_prompt - workflow_graph description: Filter agents by workflow type - in: query name: sortField required: false schema: type: string default: createdAt enum: - createdAt - updatedAt - totalCalls - name - workflowType description: Field to sort results by - in: query name: sortOrder required: false schema: type: string default: desc enum: - asc - desc description: Sort direction - in: query name: archived required: false schema: type: boolean default: false description: When true, returns only archived agents. Omit or set to false to return active agents. responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: agents: type: array items: $ref: "#/components/schemas/AgentDTO" total: type: number description: Total number of agents "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "500": $ref: "#/components/responses/InternalServerErrorResponse" post: summary: Create a new agent x-fern-sdk-group-name: agents x-fern-sdk-method-name: create_agent tags: - Agents security: - BearerAuth: [] description: | Create a new agent by passing the agent name in the request body. New agents have versioning enabled by default. To set the prompt, `firstMessage`, tools, or any runtime config, fork a draft from the auto-created initial version, edit it, publish, and activate — see the [Versioning Lifecycle](/atoms/developer-guide/build/agents/versioning-lifecycle) guide for the full flow. The legacy `PATCH /workflow/{workflowId}` endpoint writes directly to the underlying workflow document and bypasses the version lifecycle; edits made that way are not captured as a version and may not propagate to live calls. Use the drafts flow above. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateAgentRequest" responses: "201": description: Agent created successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: string example: "60d0fe4f5311236168a109ca" description: The ID of the created agent "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}: get: summary: Get agent by ID x-fern-sdk-group-name: agents x-fern-sdk-method-name: get_agent description: | Returns the agent document merged with the resolved config of the active version under `_resolvedConfig`. Non-versioned fields (name, telephonyProductId, allowInboundCall, etc.) sit at the top level; versioned fields (prompt, tools, language, synthesizer, post-call analytics, …) are resolved from the target version and exposed under `_resolvedConfig`. **Previewing a draft or specific version** Pass `?draftId=` to resolve config from a specific draft instead of the active version. Pass `?versionId=` to resolve config from a specific published version. When either param is used, the response includes `_configSource: "draft" | "version" | "active"` indicating which config was resolved. Notable resolved fields in `_resolvedConfig`: - `prompt` — active version's single-prompt text - `tools` — configured tools on the resolved version - `postCallAnalyticsConfig` — disposition metrics + analytics model flags - `modelName` — LLM model name on the resolved version - `defaultLanguage`, `supportedLanguages` — active language config - `firstMessage`, `globalPrompt` — active messaging config - `workflowGraph` — full node graph for `workflow_graph` agents To read prompt + tools alone, use `GET /agent/{id}/workflow` (deprecated for new integrations but still live). To inspect a specific non-active version, use `GET /agent/{id}/versions/{versionId}`. **400 — also used for "not found":** if the agent ID does not exist in the organization, the API returns 400 with `errors: ["No agent found"]` rather than 404. tags: - Agents security: - BearerAuth: [] parameters: - in: path name: id required: true schema: type: string minLength: 1 description: | Agent identifier (Mongo ObjectId string). Must be non-empty. An empty `id` would resolve to `GET /agent/`, which is the list endpoint — Fern adds the `minLength: 1` guard so the generated SDK raises locally rather than silently calling the wrong route. - in: query name: draftId required: false schema: type: string description: Resolve `_resolvedConfig` from this draft instead of the active version. Sets `_configSource` to `"draft"` in the response. - in: query name: versionId required: false schema: type: string description: Resolve `_resolvedConfig` from this published version instead of the active version. Sets `_configSource` to `"version"` in the response. responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/AgentDTO" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "500": $ref: "#/components/responses/InternalServerErrorResponse" patch: summary: Update agent metadata x-fern-sdk-group-name: agents x-fern-sdk-method-name: update_agent description: | Update agent fields. Behavior depends on whether the agent has versioning enabled: **Versioned agents** (have an active published version): only metadata fields are accepted — `name`, `description`, `avatarUrl`, `telephonyProductId`, `allowInboundCall`, `visibleToEveryone`. Submitting any config-level field returns 400 with `"Agent has versioning enabled. Config changes must be made through drafts."`. Use `PATCH /agent/{id}/drafts/{draftId}/config` instead. **Non-versioned agents** (no active version): all configuration fields are accepted, the same full set as `POST /agent`. **400 is also returned when:** - The agent is locked (`"Agent is locked, please unlock it to update"`) - Cross-field constraint violated (e.g. `north_indic` language requires `transcriberType: pulse`) **403** is returned when selecting a gated model (`gpt-5.2`, `electron-kogta`, `electron-kogta-v2`) without org-level access. tags: - Agents security: - BearerAuth: [] parameters: - in: path name: id required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateAgentRequest" responses: "200": description: Agent updated successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: string example: "60d0fe4f5311236168a109ca" description: The ID of the updated agent "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent not found "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/archive: delete: operationId: deleteAgent summary: Archive or unarchive an agent x-fern-sdk-group-name: agents x-fern-sdk-method-name: archive_agent description: | Soft-archives the agent — it is excluded from listings and stops accepting calls, but all data is preserved and the operation is fully reversible. Pass `?on=false` to unarchive (restore) a previously archived agent. **409 is returned when:** - The agent is already in the requested state (`"Agent is already archived"` / `"Agent is already active"`) - The agent is linked to an active campaign (`"Agent is associated with the [status] campaign "[name]". Complete or remove the campaign before archiving."`) tags: - Agents security: - BearerAuth: [] parameters: - in: path name: id required: true schema: type: string - in: query name: on required: false schema: type: boolean default: true description: | `true` (default) — archive the agent. `false` — unarchive (restore) a previously archived agent. responses: "200": description: Agent archived or unarchived successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: message: type: string description: Human-readable outcome message enum: - Agent archived - Agent unarchived "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent not found "409": description: | Conflict — agent is already in the requested state, or is linked to an active campaign. "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/duplicate: post: summary: Duplicate agent to another organization x-fern-sdk-group-name: agents x-fern-sdk-method-name: duplicate_agent description: | Duplicates a SINGLE_PROMPT agent's live active version into a target organization (can also be the same organization). Copies all versioned configuration but strips organization-specific resources: knowledge base tools are removed, default variable values are blanked, and a new avatar is generated. The duplicate starts with a published V1 as its active version. **400 is returned when:** - The source agent is archived (`"Cannot duplicate an archived agent"`) - The agent has no `activeVersionId` (`"This agent has no active version and cannot be duplicated"`) - The active version exists but is not published/active (`"This agent has no active published version and cannot be duplicated"`) - The agent is not `SINGLE_PROMPT` workflow type tags: - Agents security: - BearerAuth: [] parameters: - in: path name: id required: true schema: type: string description: The ID of the source agent to duplicate requestBody: required: true content: application/json: schema: type: object required: - targetOrganizationId properties: targetOrganizationId: type: string pattern: "^[a-fA-F0-9]{24}$" description: | MongoDB ObjectId of the target organization. Must be a 24-character hex string. The authenticated user must be a member of this organization. example: "60d0fe4f5311236168a109ca" responses: "201": description: Agent duplicated successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: _id: type: string example: "60d0fe4f5311236168a109cb" description: The ID of the newly created agent "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": description: Forbidden — authenticated user is not a member of the target organization content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "404": description: | Not found. Possible messages: - `"Agent not found"` — source agent doesn't exist or doesn't belong to the caller's org - `"Target organization not found"` — the `targetOrganizationId` doesn't exist content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" # ── Deprecated: Workflow endpoints (still live) ──────────────────────── # Both still work in production and are actively used by customers, but # they bypass the versioning system. Prefer PATCH /agent/{id}/drafts/{draftId}/config # for writes and GET /agent/{id} for reads. /agent/{id}/workflow: get: summary: Get agent workflow deprecated: true description: | **Deprecated** — prefer `GET /agent/{id}` (config is resolved into `_resolvedConfig` including prompt, tools, and post-call analytics). Returns the active version's prompt and tools for single-prompt agents, or the workflow graph data for workflow_graph agents. Customers still rely on this to fetch their current prompt + tools — endpoint is kept live for now. **Caveat:** the `versionId` query param (if passed) is silently ignored. The response always reflects the currently-active version. To inspect a non-active version, use `GET /agent/{id}/versions/{versionId}`. tags: - Agents security: - BearerAuth: [] parameters: - in: path name: id required: true description: The ID of the agent schema: type: string responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object description: The active version's workflow. properties: prompt: type: string description: Active prompt (single-prompt agents only). tools: type: array items: $ref: "#/components/schemas/Tool" description: Active tool list (single-prompt agents only). type: $ref: "#/components/schemas/WorkflowType" description: Workflow type. Present for workflow_graph agents. data: oneOf: - $ref: "#/components/schemas/WorkflowGraphData" - $ref: "#/components/schemas/SinglePromptData" description: Graph data for workflow_graph agents. "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Agent not found "500": $ref: "#/components/responses/InternalServerErrorResponse" /workflow/{id}: patch: summary: Update workflow configuration deprecated: true x-fern-availability: deprecated x-fern-sdk-group-name: agents x-fern-sdk-method-name: update_workflow_configuration description: | **Deprecated** — use `PATCH /agent/{id}/drafts/{draftId}/config` instead. Directly mutates the legacy workflow document for an agent. This write path bypasses the versioning system entirely: the change is not captured as a new version, and future version activations may overwrite the legacy doc back to whatever the version snapshot contains. ⚠ **Writing here on a versioned agent can silently wipe tools, prompt, or other fields that were missing from the PATCH payload.** Only use this if you know the agent is not using versioning, or if you are intentionally hot-patching the legacy doc. tags: - Agents security: - BearerAuth: [] parameters: - in: path name: id required: true description: The workflow ID (found at `agent.workflowId` on the agent document). schema: type: string example: "60d0fe4f5311236168a109ca" requestBody: required: true content: application/json: schema: type: object required: [type] properties: type: $ref: "#/components/schemas/WorkflowType" workflowGraph: type: object description: Required when `type = workflow_graph`. Exactly one of `workflowGraph` or `singlePromptConfig` must be provided. properties: nodes: type: array items: type: object edges: type: array items: type: object singlePromptConfig: $ref: "#/components/schemas/SinglePromptConfig" responses: "200": description: Workflow updated successfully. "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Workflow not found. "500": $ref: "#/components/responses/InternalServerErrorResponse" /conversation: get: summary: Get all conversation logs x-fern-sdk-group-name: calls x-fern-sdk-method-name: list description: Retrieve paginated conversation logs with support for various filters. Returns call logs for agents belonging to the authenticated user's organization. tags: - Logs security: - BearerAuth: [] parameters: - in: query name: page schema: type: integer default: 1 minimum: 1 description: Page number for pagination example: 1 - in: query name: limit schema: type: integer default: 5 minimum: 1 maximum: 500 description: Number of items per page. Server-side cap is 500 — values above 500 are silently clamped. example: 10 - in: query name: agentIds schema: type: string description: Comma-separated list of agent IDs to filter by example: "60d0fe4f5311236168a109ca,60d0fe4f5311236168a109cb" - in: query name: campaignIds schema: type: string description: Comma-separated list of campaign IDs to filter by example: "60d0fe4f5311236168a109ca,60d0fe4f5311236168a109cb" - in: query name: callTypes schema: type: string enum: - telephony_inbound - telephony_outbound - webcall description: Comma-separated list of call types to filter by example: "telephony_outbound,telephony_inbound" - in: query name: search schema: type: string description: Search query to filter by callId, fromNumber, or toNumber example: "+1234567890" - in: query name: statusFilter schema: type: string description: | Comma-separated list of call statuses to filter by. Available statuses: pending, in_progress, in_queue, processing, active, completed, failed, no_answer, cancelled example: "completed,failed" - in: query name: disconnectReasonFilter schema: type: string description: | Comma-separated list of disconnect reasons to filter by. Available reasons: user_hangup, agent_hangup, connection_error, timeout, system_error, transfer_complete example: "user_hangup,agent_hangup" - in: query name: callAttemptFilter schema: type: string description: | Comma-separated list of call attempt types to filter by. Available filters: initial (first attempt calls), retry (retry attempt calls), all (all calls) example: "initial" - in: query name: durationFilter schema: type: string description: | Comma-separated list of duration ranges to filter by. Available ranges: 0-30 (0-30 seconds), 30-60 (30-60 seconds), 1-5 (1-5 minutes), 5+ (more than 5 minutes) example: "0-30,30-60" - in: query name: sortBy required: false schema: type: string enum: - createdAt - updatedAt - callDuration - avgLatency description: Field to sort results by - in: query name: sortOrder required: false schema: type: string enum: - asc - desc description: Sort direction - in: query name: dateFrom required: false schema: type: string format: date-time description: ISO date — return calls created on or after this date example: "2025-01-01T00:00:00.000Z" - in: query name: dateTo required: false schema: type: string format: date-time description: ISO date — return calls created on or before this date example: "2025-01-31T23:59:59.999Z" - in: query name: versionFilter required: false schema: type: string description: Comma-separated version IDs to filter calls by the agent version that handled them responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: logs: type: array items: type: object properties: _id: type: string description: The database ID of the call log example: "60d0fe4f5311236168a109ca" callId: type: string description: The unique call identifier example: "CALL-1737000000000-abc123" status: type: string description: The status of the call enum: [pending, in_progress, in_queue, processing, active, completed, failed, no_answer, cancelled] example: "completed" duration: type: number description: The duration of the call in seconds example: 120 from: type: string description: The phone number the call was made from example: "+15551234567" to: type: string description: The phone number the call was made to example: "+15559876543" type: type: string description: The type of call enum: [telephony_inbound, telephony_outbound, webcall] example: "telephony_outbound" agentId: type: string description: The ID of the agent that handled the call example: "60d0fe4f5311236168a109ca" recordingUrl: type: string description: URL to the call recording (if available) example: "https://storage.example.com/recordings/call-123.mp3" recordingDualUrl: type: string description: URL to the dual-channel call recording (if available) example: "https://storage.example.com/recordings/call-123-dual.mp3" disconnectionReason: type: string description: The reason the call was disconnected example: "user_hangup" retryCount: type: integer description: Number of retry attempts for this call example: 0 createdAt: type: string format: date-time description: When the call was created example: "2025-01-15T10:30:00.000Z" dispositionMetrics: type: object description: Custom disposition metrics for the call additionalProperties: type: string example: interested: "yes" follow_up_needed: "no" agentDispositionConfig: type: array description: Configuration for disposition metrics items: type: object properties: identifier: type: string type: type: string callFailureReason: type: string description: Reason the call failed, if applicable callCost: type: number description: Discounted total cost of the call versionId: type: string description: ID of the agent version that handled this call versionNumber: type: number description: Human-readable version number of the agent version used isTest: type: boolean description: Whether this was a test call retryCallId: type: string description: ID of the retry call if this call was retried retryAttemptNumber: type: number description: Which retry attempt this was (0 = initial, 1 = first retry, etc.) postCallAnalytics: type: object description: | Post-call analytics results evaluated against the call transcript. Contains disposition metric values with confidence scores. properties: summary: type: string description: Auto-generated summary of the call dispositionMetrics: type: array description: Evaluated disposition metrics for this call items: type: object properties: identifier: type: string description: Metric identifier matching the agent config value: type: string description: The evaluated value for this metric confidence: type: number description: Confidence score for the evaluation (0–1) turnLatencyMetrics: type: object description: Per-turn latency statistics for the call properties: avgLatency: type: number description: Average turn latency in milliseconds medianLatency: type: number description: Median turn latency in milliseconds minLatency: type: number description: Minimum turn latency in milliseconds maxLatency: type: number description: Maximum turn latency in milliseconds turns: type: number description: Total number of turns in the call latencies: type: array items: type: number description: Array of individual turn latencies in milliseconds transitions: type: array description: Per-turn timing breakdown. items: type: object properties: turn: type: number user_end: type: number description: Timestamp (ms) when the user finished speaking bot_start: type: number description: Timestamp (ms) when the agent started responding latency: type: number description: Latency for this turn in milliseconds processedAt: type: string format: date-time description: When the latency metrics were computed. pagination: type: object properties: total: type: integer description: Total number of matching call logs example: 150 page: type: integer description: Current page number example: 1 limit: type: integer description: Number of items per page (page size) example: 10 hasMore: type: boolean description: Whether there are more pages available example: true totalPages: type: integer description: Total number of pages example: 15 dispositionMetricsConfig: type: array description: Global disposition metrics configuration items: type: object properties: identifier: type: string type: type: string "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /conversation/search: post: summary: Search conversation logs by call IDs x-fern-sdk-group-name: calls x-fern-sdk-method-name: search description: | Fetch specific conversation logs by their callIds. This endpoint allows you to retrieve up to 100 specific calls at once. Only returns calls that belong to agents in your organization (security check enforced). Unlike the GET /conversation endpoint, this endpoint can also return retry calls (non-root calls). **Differences from GET /conversation response:** each log item has the same base structure but the following three fields are **not** included here: - `dispositionMetrics` — not enriched - `agentDispositionConfig` — not enriched - `versionNumber` — not enriched tags: - Logs security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: - callIds properties: callIds: type: array items: type: string minItems: 1 maxItems: 100 description: | Array of callIds to fetch. Format: `CALL-{13-digit-timestamp}-{6-char-hex}` (e.g. `CALL-1737000000000-abc123`). Minimum 1, maximum 100 per request. example: ["CALL-1737000000000-abc123", "CALL-1737000000001-def456"] responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: logs: type: array items: type: object properties: _id: type: string description: The database ID of the call log example: "60d0fe4f5311236168a109ca" callId: type: string description: The unique call identifier example: "CALL-1737000000000-abc123" status: type: string description: The status of the call enum: [pending, in_progress, in_queue, processing, active, completed, failed, no_answer, cancelled] example: "completed" duration: type: number description: The duration of the call in seconds example: 120 from: type: string description: The phone number the call was made from example: "+15551234567" to: type: string description: The phone number the call was made to example: "+15559876543" type: type: string description: The type of call enum: [telephony_inbound, telephony_outbound, webcall] example: "telephony_outbound" agentId: type: string description: The ID of the agent that handled the call example: "60d0fe4f5311236168a109ca" recordingUrl: type: string description: URL to the call recording (if available) recordingDualUrl: type: string description: URL to the dual-channel call recording (if available) disconnectionReason: type: string description: The reason the call was disconnected retryCount: type: integer description: Number of retry attempts for this call createdAt: type: string format: date-time description: When the call was created callFailureReason: type: string description: Reason the call failed, if applicable callCost: type: number description: Discounted total cost of the call versionId: type: string description: ID of the agent version that handled this call isTest: type: boolean description: Whether this was a test call retryCallId: type: string description: ID of the retry call if this call was retried retryAttemptNumber: type: number description: Which retry attempt this was (0 = initial) postCallAnalytics: type: object description: Post-call analytics results evaluated against the call transcript properties: summary: type: string dispositionMetrics: type: array items: type: object properties: identifier: type: string value: type: string confidence: type: number turnLatencyMetrics: type: object description: Per-turn latency statistics for the call properties: avgLatency: type: number medianLatency: type: number minLatency: type: number maxLatency: type: number turns: type: number latencies: type: array items: type: number transitions: type: array items: type: object properties: turn: type: number user_end: type: number bot_start: type: number latency: type: number processedAt: type: string format: date-time total: type: integer description: Number of logs returned example: 2 requestedCount: type: integer description: Number of callIds requested example: 3 "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /conversation/{id}: get: summary: Get conversation log by ID x-fern-sdk-group-name: calls x-fern-sdk-method-name: get description: Retrieve detailed information about a specific conversation including transcript, events, and latency metrics. tags: - Logs security: - BearerAuth: [] parameters: - in: path name: id required: true description: The callId of the conversation (format `CALL-{13-digit-timestamp}-{6-char-hex}`). You can get the callId from the conversation logs endpoint. schema: type: string example: "CALL-1737000000000-abc123" responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: _id: type: string description: The database ID of the conversation log example: "60d0fe4f5311236168a109ca" callId: type: string description: The unique call identifier example: "CALL-1737000000000-abc123" agent: $ref: "#/components/schemas/AgentDTO" status: type: string description: The status of the conversation enum: [pending, in_progress, in_queue, processing, active, completed, failed, no_answer, cancelled] example: "completed" duration: type: number description: The duration of the conversation in seconds example: 300 recordingUrl: type: string description: The recording URL of the conversation recordingDualUrl: type: string description: URL to the dual-channel recording of the conversation from: type: string description: The phone number of the caller to: type: string description: The phone number of the callee type: type: string description: The type of the conversation enum: - telephony_inbound - telephony_outbound - webcall transcript: type: array description: The reconstructed transcript of the conversation items: type: object properties: role: type: string enum: [agent, user] description: Who spoke this turn content: type: string description: The spoken text for this turn timestamp: type: number description: Timestamp offset in milliseconds from call start variables: type: object description: Runtime variables resolved and used during the call additionalProperties: true events: type: array description: Raw event stream from the relay service items: type: object additionalProperties: true callCost: type: number description: Discounted total cost of the call callFailureReason: type: string description: Reason the call failed, if applicable retryCallId: type: string description: ID of the retry call if this call was retried postCallAnalytics: type: object description: Post-call analytics results evaluated against the call transcript properties: summary: type: string description: Auto-generated summary of the call dispositionMetrics: type: array description: Evaluated disposition metrics for this call items: type: object properties: identifier: type: string description: Metric identifier matching the agent config value: type: string description: The evaluated value for this metric confidence: type: number description: Confidence score for the evaluation (0–1) turnLatencyMetrics: type: object description: Per-turn latency statistics for the call. Replaces the deprecated average_*_latency fields. properties: turns: type: number description: Total number of turns in the call avgLatency: type: number description: Average turn latency in milliseconds medianLatency: type: number description: Median turn latency in milliseconds minLatency: type: number description: Minimum turn latency in milliseconds maxLatency: type: number description: Maximum turn latency in milliseconds latencies: type: array items: type: number description: Array of individual turn latencies in milliseconds transitions: type: array description: Per-turn timing breakdown items: type: object properties: turn: type: number user_end: type: number description: Timestamp (ms) when the user finished speaking bot_start: type: number description: Timestamp (ms) when the agent started responding latency: type: number description: Latency for this turn in milliseconds processedAt: type: string format: date-time description: When the latency metrics were computed voiceConfigUsed: type: object description: The voice configuration that was actually used for this call properties: model: type: string description: The TTS model used for the call voiceId: type: string description: The voice ID used for the call gender: type: string description: The gender of the voice used for the call slmModelUsed: type: string description: The SLM/LLM model that was actually used for this call "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Conversation log not found — the callId does not exist or does not belong to the caller's organization "500": $ref: "#/components/responses/InternalServerErrorResponse" /conversation/{callId}/recording/download-url: get: summary: Get a time-limited recording download URL description: | Returns a presigned S3 URL for the call's recording. Hand the URL straight to the customer or pull bytes server-side. The presigned URL is **time-limited** — typically usable for a few minutes — so don't cache it; request a fresh one each time you need the recording. Returns `404` if the call has no recording (call hasn't started, was cancelled before audio captured, or was deleted by the platform's retention policy). Returns `400 Invalid call ID format` if you pass a Mongo `_id` instead of the `callId` string. tags: - Conversations security: - BearerAuth: [] parameters: - in: path name: callId required: true schema: type: string example: CALL-1781127346211-e765f7 description: The `callId` string for the conversation (e.g. `CALL-1778226705739-7e4c17`). This is the `callId` field returned by `GET /conversation`, **not** the Mongo `_id` — passing `_id` returns `400 Invalid call ID format`. responses: "200": description: Successful response — presigned URL ready to fetch. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: presignedUrl: type: string format: uri description: Time-limited HTTPS URL pointing at the recording in S3. The URL expires after a short window; request a fresh one if needed. "400": description: Invalid call ID format. "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: No recording found for this call. "500": $ref: "#/components/responses/InternalServerErrorResponse" /conversation/{callId}/retries: get: summary: List retry attempts for a call x-fern-sdk-group-name: conversations x-fern-sdk-method-name: list_retry_attempts description: | Returns the **parent call** plus every retry attempt that branched from it, ordered by attempt index. Use this when a customer asks "did the platform retry this call?" — typically driven by an outbound agent's auto-retry configuration (`maxRetries`, `retryDelay`). - If the `callId` you pass is the original (parent), the response contains that parent plus all child retries. - If the `callId` you pass is itself a retry, the response still includes the parent and every sibling retry — the API resolves to the family root automatically. Returns `404` if no call exists with that ID in your organization. tags: - Conversations security: - BearerAuth: [] parameters: - in: path name: callId required: true schema: type: string description: Any `callId` in the retry family (parent or any retry). responses: "200": description: Successful response — full retry family. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: retries: type: array description: All calls in the retry family — parent first, then retries in attempt order. Each entry has the same shape as a single call log returned by `GET /conversation`. items: type: object description: A call log entry. Mirrors the per-row shape in `GET /conversation`. "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": description: Access denied — the call belongs to a different organization. "404": description: No call exists with that ID. "500": $ref: "#/components/responses/InternalServerErrorResponse" /conversation/cancel: post: summary: Cancel an in-flight call x-fern-sdk-group-name: conversations x-fern-sdk-method-name: cancel description: | Cancels an outbound call that has been queued or is in progress. Use the body form to look the call up by `callId`; the path-param form (`POST /conversation/{callId}/cancel`) is the equivalent for REST conventions, but only handles `IN_QUEUE` calls. Returns `404` if no call with that ID exists in your organization. Returns `400` if the call is already in a terminal state (completed / failed / cancelled). tags: - Conversations security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [callId] properties: callId: type: string description: The `callId` returned by `POST /conversation/outbound` or visible in `GET /conversation`. example: "CALL-1778226705739-7e4c17" reason: type: string description: Optional free-text reason for cancellation. Logged for support / audit. responses: "200": description: Call cancelled. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: callId: type: string status: type: string example: "cancelled" previousStatus: type: string description: The call's status immediately before cancellation (e.g. `queued`, `ringing`, `in-progress`). "400": description: Call is already in a terminal state and cannot be cancelled. "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: No call found with that callId in your organization. "500": $ref: "#/components/responses/InternalServerErrorResponse" /conversation/{callId}/cancel: post: summary: Cancel a queued call (path-param form) x-fern-sdk-group-name: conversations x-fern-sdk-method-name: cancel_queued description: | REST-conventional path-param variant of [`POST /conversation/cancel`](#operation/cancelCallByBody). **Behavior differs from the body form.** This path-param endpoint only cancels calls that are still in the `IN_QUEUE` state — calls that have already started dialing or are in progress return `400 Bad Request` with `errors: ["Conversation with ID ... is not in queue and cannot be cancelled"]`. Use the body form (`POST /conversation/cancel`) if you need to cancel an in-progress call. The path param is the `callId` string (e.g. `CALL-1778226705739-7e4c17`), **not** the Mongo `_id`. Passing `_id` returns `404 No conversation found`. tags: - Conversations security: - BearerAuth: [] parameters: - in: path name: callId required: true schema: type: string example: CALL-1781127346211-e765f7 description: The `callId` string for the conversation to cancel. responses: "200": description: Call cancelled. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: callId: type: string status: type: string example: "cancelled" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: No call found with that callId in your organization. "500": $ref: "#/components/responses/InternalServerErrorResponse" /conversation/outbound: post: summary: Start an outbound call x-fern-sdk-group-name: calls x-fern-sdk-method-name: start_outbound_call description: | Initiates an outbound telephony call with a specified agent and phone number. ## Caller-ID resolution When `fromProductId` is omitted **and** the agent has no telephony product attached, the call dispatches from a Smallest-managed Plivo trunk using a default caller-ID number (chosen by destination country). The call still places and the response is still `200 + conversationId`, but the recipient sees the default Smallest number rather than your own. For production traffic, either: - pass `fromProductId` explicitly (look up your owned numbers via `GET /product/phone-numbers`), or - attach a phone-number product to the agent. ## Resolved-config check The call uses the agent's currently-active version. If your most recent prompt change went through `PATCH /workflow/{workflowId}` and the agent has versioning enabled, that change may not have propagated to the active version — and the call will play the platform-default greeting instead of your prompt. Before placing a production call, fetch `GET /agent/{agentId}` and confirm `_resolvedConfig.firstMessage` (and related fields) match what you intended. The [Versioning Lifecycle](/atoms/developer-guide/build/agents/versioning-lifecycle) guide covers the correct edit flow. **400 is returned for:** - Invalid `agentId` format (`"Invalid agent id"`) - Invalid `phoneNumber` format (`"Invalid phone number"`) - Invalid `fromProductId` format (`"Invalid product id"`) - Agent not found or not in the caller's org (`"Agent not found"`) - Agent is archived (`"Agent is archived and cannot initiate calls"`) - `workflow_graph` agent has no workflow configured (`"Workflow not found"`) - Workflow has validation errors (`"Invalid workflow, please fix the errors..."`) **403** is returned for `workflow_graph` agents when the org lacks conversational agents access. **Test calls:** set the `x-test-call: true` header to mark the resulting call log as a test call (`isTest: true`). Test calls are subject to concurrent slot limits. tags: - Calls security: - BearerAuth: [] parameters: - in: header name: x-test-call required: false schema: type: string enum: ["true"] description: | Set to "true" to mark this as a test call. The call log will have isTest=true and counts against concurrent test-call slot limits. requestBody: required: true content: application/json: schema: type: object required: - agentId - phoneNumber properties: agentId: type: string description: MongoDB ObjectId of the agent initiating the conversation example: "60d0fe4f5311236168a109ca" phoneNumber: type: string description: The E.164 phone number to call example: "+1234567890" variables: type: object description: | Variables to inject into the agent's prompt at call time. Values must be string, number, or boolean — nested objects are not supported. additionalProperties: oneOf: - type: string - type: number - type: boolean example: { "name": "John", "age": 30, "vip": true } fromProductId: type: string description: ID of the telephony product (phone number) to call from. Get this from `GET /product/phone-numbers`. example: "60d0fe4f5311236168a109ca" versionId: type: string description: | ID of a specific published agent version to use for this call. Useful for test calls — attributes the call log to that version so you can track which version was tested. operatorId: type: string description: | Integration operator identifier. Pass `"webengage"` to trigger the WebEngage integration flow. operatorData: type: object description: Arbitrary data passed to the operator (e.g. `userId`, `journeyId` for WebEngage). additionalProperties: true responses: "200": description: Successfully started the outbound conversation content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: conversationId: type: string description: | The callId of the initiated call (format `CALL-{13-digit-timestamp}-{6-char-hex}`). Use this value as the `id` path parameter in `GET /conversation/{id}` and as an entry in `POST /conversation/search`. example: "CALL-1737000000000-abc123" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "500": $ref: "#/components/responses/InternalServerErrorResponse" /events: get: summary: Subscribe to live call events (SSE) x-fern-sdk-group-name: live_transcripts x-fern-sdk-method-name: subscribe_to_live_events description: | Real-time streaming of user speech (STT) and agent speech (TTS) events for an active call via Server-Sent Events. The connection is real-time — events stream directly from the call runtime as they are produced. The SSE connection auto-closes when the call ends (`sse_close` event). Only active calls can be subscribed to; completed calls return a 400 error. **Transcript event types:** - `user_interim_transcription` — Partial, in-progress transcription as the user speaks. Use for live preview only; will be superseded by `user_transcription`. - `user_transcription` — Final transcription for a completed user speech turn. - `tts_completed` — Fired when the agent finishes speaking a TTS segment. Includes the spoken text and optionally TTS latency. **Lifecycle events:** - `sse_init` — Sent immediately when the SSE connection is established. - `sse_close` — Sent when the call ends, right before the server closes the connection. Other event types (e.g. `tool_call_start`, `pre_call_api`, `agent_log`, metrics) are also sent on this stream. - `call_start` - `call_end` - `turn_latency` - `metrics` - `agent_node_state` - `hopping` - `knowledgebase` - `variable_extraction` - `pre_call_api` - `post_call_api` - `agent_error` - `agent_log` - `tool_call_start` - `tool_call_end` - `tool_call_error` - `call_cancelled` - `call_recording` tags: - Live Transcripts security: - BearerAuth: [] parameters: - name: X-Organization-Id in: header required: false description: Required when using session-cookie auth. API-token auth may infer the organization from the token. schema: type: string - name: callId in: query required: true description: The call ID to subscribe events for. Missing or invalid values return 400. schema: type: string example: "CALL-1758124225863-80752e" x-codeSamples: - lang: Python label: Python requests stream source: | import requests url = "https://api.smallest.ai/atoms/v1/events" headers = { "Authorization": "Bearer YOUR_API_KEY", "Accept": "text/event-stream", } params = {"callId": "CALL-1758124225863-80752e"} with requests.get(url, headers=headers, params=params, stream=True) as response: response.raise_for_status() for line in response.iter_lines(decode_unicode=True): if line: print(line) - lang: JavaScript label: JavaScript fetch stream source: | const response = await fetch( "https://api.smallest.ai/atoms/v1/events?callId=CALL-1758124225863-80752e", { headers: { Authorization: "Bearer YOUR_API_KEY", Accept: "text/event-stream", }, }, ); if (!response.ok) { throw new Error(`SSE request failed: ${response.status}`); } const reader = response.body.getReader(); const decoder = new TextDecoder(); while (true) { const { value, done } = await reader.read(); if (done) break; console.log(decoder.decode(value, { stream: true })); } // Browser EventSource cannot set custom Authorization headers directly. - lang: Go label: Go stream reader source: | req, err := http.NewRequest("GET", "https://api.smallest.ai/atoms/v1/events?callId=CALL-1758124225863-80752e", nil) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer YOUR_API_KEY") req.Header.Set("Accept", "text/event-stream") resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() scanner := bufio.NewScanner(resp.Body) for scanner.Scan() { line := scanner.Text() if line != "" { fmt.Println(line) } } - lang: Ruby label: Ruby line stream source: | require "net/http" require "uri" uri = URI("https://api.smallest.ai/atoms/v1/events?callId=CALL-1758124225863-80752e") request = Net::HTTP::Get.new(uri) request["Authorization"] = "Bearer YOUR_API_KEY" request["Accept"] = "text/event-stream" Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| http.request(request) do |response| response.read_body do |chunk| puts chunk end end end - lang: PHP label: PHP stream source: | $ch = curl_init("https://api.smallest.ai/atoms/v1/events?callId=CALL-1758124225863-80752e"); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer YOUR_API_KEY", "Accept: text/event-stream", ]); curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) { echo $chunk; return strlen($chunk); }); curl_exec($ch); curl_close($ch); responses: "200": description: SSE event stream established successfully content: text/event-stream: schema: type: object description: | Events are sent as `data: \n\n`. Forwarded runtime events commonly include `event_type`, `event_id`, `timestamp`, and `call_id`. `sse_init` and `sse_close` include `event_type` and `event_time`. properties: event_type: type: string description: The type of event enum: - sse_init - call_start - call_end - turn_latency - user_interim_transcription - user_transcription - tts_completed - metrics - agent_node_state - hopping - knowledgebase - variable_extraction - pre_call_api - post_call_api - agent_error - agent_log - tool_call_start - tool_call_end - tool_call_error - call_cancelled - call_recording - sse_close event_id: type: string description: Unique identifier for the event timestamp: type: string format: date-time description: ISO 8601 timestamp of the event call_id: type: string description: The call ID this event belongs to event_time: type: string format: date-time description: Timestamp used by `sse_init` and `sse_close` telephony_id: type: string description: Telephony ID for `call_start` metadata: type: object additionalProperties: true description: Metadata for `call_end`, `agent_error`, or `agent_log` turn_latency: type: number description: Turn latency value for `turn_latency` stt_api_ms: type: number description: STT API latency in milliseconds for `turn_latency` stt_to_llm_ms: type: number description: STT-to-LLM latency in milliseconds for `turn_latency` smart_turn_ms: type: number description: Smart-turn latency in milliseconds for `turn_latency` llm_api_ms: type: number description: LLM API latency in milliseconds for `turn_latency` llm_to_tts_ms: type: number description: LLM-to-TTS latency in milliseconds for `turn_latency` tts_api_ms: type: number description: TTS API latency in milliseconds for `turn_latency` tts_to_audio_ms: type: number description: TTS-to-audio latency in milliseconds for `turn_latency` total_turn_ms: type: number description: Total turn latency in milliseconds for `turn_latency` turn_index: type: integer description: Turn index for `turn_latency` interrupted: type: boolean description: Whether the turn was interrupted for `turn_latency` smart_turn_enabled: type: boolean description: Whether smart turn was enabled for `turn_latency` interim_transcription_text: type: string description: Partial transcription text (only for `user_interim_transcription`) user_transcription_text: type: string description: Final transcription text (only for `user_transcription`) tts_text: type: string description: Text spoken by the agent (only for `tts_completed`) tts_latency: type: integer description: TTS latency in milliseconds (only for `tts_completed`) metrics: type: array description: | Per-turn metrics payload for `metrics` events. Server emits an **array** of `{processor, model, value}` entries (one per pipeline stage), not a single object. The SDK previously dropped every `metrics` SSE event with a pydantic ValidationError when this was typed as an object (122 events on a 40s call); typing it as an array of objects fixes the decode. items: type: object properties: processor: type: string description: Pipeline stage that produced the metric (e.g. `pulse_stt`, `electron_llm`, `lightning_tts`). model: type: string description: Concrete model/version identifier within the processor (e.g. `pulse-large english_v4.1`). value: type: number description: Metric value — typically milliseconds for latency metrics. node_id: type: string description: Node ID for `agent_node_state` node_name: type: string description: Node name for `agent_node_state` node_type: type: string description: Node type for `agent_node_state` context: type: object additionalProperties: true description: Context payload for agent-node and tool-call events from_node_id: type: string description: Source node ID for `hopping` to_node_id: type: string description: Destination node ID for `hopping` knowledge_base_id: type: string description: Knowledge base ID for `knowledgebase` user_transcript: type: string description: User transcript for `knowledgebase` response: nullable: true description: Response payload for knowledgebase, API, or tool-call events latency: type: number description: Latency for `knowledgebase` or `variable_extraction` error: nullable: true description: Error payload for knowledgebase, variable extraction, API, tool, or agent error events variables: type: object additionalProperties: true description: Variables extracted by `variable_extraction` variable_extraction_prompt: type: string description: Prompt used for `variable_extraction` method: type: string description: HTTP method for `pre_call_api` or `post_call_api` headers: type: object additionalProperties: true description: Headers for `pre_call_api` or `post_call_api` body: nullable: true description: Body for `pre_call_api` or `post_call_api` timeout: type: number description: Timeout for `pre_call_api` or `post_call_api` extracted_variables: type: object additionalProperties: true description: Extracted variables for `pre_call_api` or `post_call_api` next_node_id: type: string description: Next node ID for `pre_call_api` or `post_call_api` success: type: boolean description: Success status for API and tool-call events turn_id: type: string description: Turn ID for tool-call events tool_call_id: type: string description: Tool call ID for tool-call events function_name: type: string description: Function name for tool-call events latency_ms: type: number description: Latency in milliseconds for `tool_call_end` recording_url: type: string description: Recording URL for `call_recording` status: type: string description: Recording status for `call_recording` examples: sse_init: summary: SSE connection initialized value: event_type: sse_init event_time: "2026-03-02T10:00:00.000Z" call_start: summary: Call started value: event_type: call_start event_id: evt_call_start timestamp: "2026-03-02T10:00:00.100Z" call_id: "CALL-1758124225863-80752e" telephony_id: tel_abc123 user_interim_transcription: summary: Partial user speech value: event_type: user_interim_transcription event_id: evt_abc123 timestamp: "2026-03-02T10:00:01.123Z" call_id: "CALL-1758124225863-80752e" interim_transcription_text: "I wanted to ask about my" user_transcription: summary: Final user speech value: event_type: user_transcription event_id: evt_abc456 timestamp: "2026-03-02T10:00:02.456Z" call_id: "CALL-1758124225863-80752e" user_transcription_text: "I wanted to ask about my recent order" tts_completed: summary: Agent finished speaking value: event_type: tts_completed event_id: evt_abc789 timestamp: "2026-03-02T10:00:03.789Z" call_id: "CALL-1758124225863-80752e" tts_latency: 245 tts_text: "Sure, I can help you with your recent order. Could you provide your order number?" tool_call_end: summary: Tool call completed value: event_type: tool_call_end event_id: evt_tool_end timestamp: "2026-03-02T10:00:04.100Z" call_id: "CALL-1758124225863-80752e" turn_id: turn_123 tool_call_id: tool_456 function_name: lookup_order latency_ms: 180 success: true response: status: found call_recording: summary: Recording available value: event_type: call_recording event_id: evt_recording timestamp: "2026-03-02T10:04:59.000Z" call_id: "CALL-1758124225863-80752e" recording_url: "https://example.com/recordings/CALL-1758124225863-80752e.wav" status: available sse_close: summary: Stream closed after call_end value: event_type: sse_close event_time: "2026-03-02T10:05:00.000Z" "400": description: Missing or invalid `callId`, missing or invalid organization header, or call is already completed. content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "401": description: Missing or invalid bearer token or session. content: application/json: schema: $ref: "#/components/schemas/UnauthorizedErrorResponse" "403": description: User is not a member of the organization or does not have member access. content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "404": description: Organization not found, call log not found, or agent not found/org mismatch. content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "500": description: Internal server error. content: application/json: schema: $ref: "#/components/schemas/InternalServerErrorResponse" /campaign: get: summary: Retrieve all campaigns x-fern-sdk-group-name: campaigns x-fern-sdk-method-name: list description: Get all campaigns for the authenticated organization. tags: - Campaigns security: - BearerAuth: [] parameters: - in: query name: page required: false schema: type: integer default: 1 description: Page number for pagination - in: query name: offset required: false schema: type: integer default: 5 description: Number of campaigns per page - in: query name: status required: false schema: type: string enum: [draft, scheduled, processing, running, paused, completed, failed] description: Filter campaigns by status - in: query name: search required: false schema: type: string description: Search campaigns by name - in: query name: sortField required: false schema: type: string default: createdAt enum: [createdAt, updatedAt] description: Field to sort by - in: query name: sortOrder required: false schema: type: string default: desc enum: [asc, desc] description: Sort direction responses: "200": description: A list of campaigns content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: campaigns: type: array items: type: object properties: _id: type: string description: The unique identifier for the campaign name: type: string description: The name of the campaign description: type: string description: The description of the campaign organization: type: string description: The ID of the organization agent: type: object description: The agent assigned to this campaign properties: _id: type: string name: type: string workflowType: type: string audience: type: object description: The audience assigned to this campaign properties: _id: type: string name: type: string createdBy: type: string description: The ID of the user who created the campaign participantsCount: type: integer description: The number of participants in the campaign status: type: string enum: [draft, scheduled, processing, running, paused, completed, failed] description: Current status of the campaign maxRetries: type: integer description: Maximum retry attempts per failed call retryDelay: type: integer description: Delay in minutes between retry attempts retryAttempts: type: integer description: Total retry attempts made so far scheduledAt: type: string format: date-time pausedAt: type: string format: date-time cancelledCallsCount: type: integer createdAt: type: string format: date-time description: The date and time when the campaign was created updatedAt: type: string format: date-time description: The date and time when the campaign was last updated pagination: type: object properties: total: type: integer page: type: integer offset: type: integer hasMore: type: boolean totalPages: type: integer totalCampaignCount: type: integer description: Total number of campaigns in the organization (unfiltered) "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" post: summary: Create a campaign x-fern-sdk-group-name: campaigns x-fern-sdk-method-name: create description: Create a campaign tags: - Campaigns security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: The name of the campaign example: "My Campaign" description: type: string description: The description of the campaign example: "This is a campaign to test the API" audienceId: type: string description: The ID of the audience example: "60d0fe4f5311236168a109ca" agentId: type: string description: The ID of the agent example: "60d0fe4f5311236168a109ca" phoneNumberIds: type: array description: | Optional list of caller-ID phone number IDs to rotate across when placing outbound calls for this campaign. If omitted, the agent's default phone number is used. items: type: string example: ["60d0fe4f5311236168a109cb"] scheduledAt: type: string format: date-time description: | Optional ISO-8601 timestamp for when the campaign should start dialing. Must be in the future. If provided, the campaign is created in `scheduled` status; otherwise it starts in `draft` status and must be started manually. example: "2026-04-24T10:00:00.000Z" maxRetries: type: integer minimum: 0 maximum: 10 default: 3 description: | Maximum number of times a failed call is retried before the participant is marked as failed. `0` disables retries. example: 3 retryDelay: type: integer minimum: 1 maximum: 1440 default: 15 description: | Delay in minutes between retry attempts for a failed call. example: 15 required: - name - audienceId - agentId responses: "201": description: | Campaign created successfully. Note: the response is the raw Mongoose document — `agentId` and `audienceId` are plain ObjectId strings here, not nested objects as returned by GET endpoints. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: _id: type: string description: The unique identifier for the campaign name: type: string description: The name of the campaign description: type: string description: The description of the campaign organization: type: string description: The ID of the organization agentId: type: string description: Raw ObjectId of the agent (not a nested object) createdBy: type: string description: The ID of the user who created the campaign audienceId: type: string description: Raw ObjectId of the audience (not a nested object) participantsCount: type: integer description: The number of participants in the campaign scheduledAt: type: string format: date-time description: The scheduled start time, if provided at creation. maxRetries: type: integer description: Maximum retries per failed call (echoes request). retryDelay: type: integer description: Delay in minutes between retry attempts (echoes request). retryAttempts: type: integer description: Number of retries attempted so far across the campaign. status: type: string enum: [draft, scheduled, processing, running, paused, completed, failed] description: Current campaign status. createdAt: type: string format: date-time description: The date and time when the campaign was created updatedAt: type: string format: date-time description: The date and time when the campaign was last updated "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "500": $ref: "#/components/responses/InternalServerErrorResponse" /campaign/{id}: get: summary: Get a campaign x-fern-sdk-group-name: campaigns x-fern-sdk-method-name: get description: Get a campaign with detailed metrics tags: - Campaigns security: - BearerAuth: [] parameters: - in: path name: id required: true description: The ID of the campaign schema: type: string responses: "200": description: Campaign details with metrics content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: campaign: type: object properties: _id: type: string description: The unique identifier for the campaign name: type: string description: The name of the campaign description: type: string description: The description of the campaign organization: type: string description: The ID of the organization agent: type: object description: The agent assigned to this campaign properties: _id: type: string name: type: string workflowType: type: string audience: type: object description: The audience assigned to this campaign properties: _id: type: string name: type: string createdBy: type: string description: The ID of the user who created the campaign participantsCount: type: integer description: The number of participants in the campaign status: type: string enum: [draft, scheduled, processing, running, paused, completed, failed] description: The current status of the campaign maxRetries: type: integer description: Maximum number of retry attempts example: 3 retryDelay: type: integer description: Delay between retries in minutes example: 15 retryAttempts: type: integer description: Total retry attempts made so far scheduledAt: type: string format: date-time description: Scheduled start time for the campaign pausedAt: type: string format: date-time description: When the campaign was paused cancelledCallsCount: type: integer description: Number of calls cancelled (e.g. when campaign was paused) error: type: string description: Error message if the campaign failed failedAt: type: string format: date-time description: When the campaign entered failed state createdAt: type: string format: date-time description: The date and time when the campaign was created updatedAt: type: string format: date-time description: The date and time when the campaign was last updated events: type: array description: Campaign events history items: type: object properties: _id: type: string triggerSource: type: string eventAction: type: string createdAt: type: string format: date-time updatedAt: type: string format: date-time metrics: type: object description: Campaign performance metrics properties: total_participants: type: integer description: Total number of contacts in the campaign audience example: 500 contacts_called: type: integer description: Number of unique contacts where a call was attempted (statuses ACTIVE, COMPLETED, FAILED, NO_ANSWER) example: 247 contacts_connected: type: integer description: Number of unique contacts who answered and had a conversation (status COMPLETED) example: 150 "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" delete: summary: Delete a campaign x-fern-sdk-group-name: campaigns x-fern-sdk-method-name: delete description: Delete a campaign tags: - Campaigns security: - BearerAuth: [] parameters: - in: path name: id required: true description: The ID of the campaign schema: type: string responses: "200": description: Campaign deleted successfully content: application/json: schema: type: object properties: status: type: boolean example: true "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Campaign not found "500": $ref: "#/components/responses/InternalServerErrorResponse" /campaign/{id}/start: post: summary: Start or resume a campaign x-fern-sdk-group-name: campaigns x-fern-sdk-method-name: start_or_resume description: | Queues the campaign for processing and returns immediately — the campaign is **not** yet running when the 202 is returned. Poll `GET /campaign/{id}` and watch for `status: "running"`. This endpoint also acts as a **resume** endpoint: if the campaign is currently paused, calling this endpoint resumes it (`status` transitions from `paused` → `running`). tags: - Campaigns security: - BearerAuth: [] parameters: - in: path name: id required: true description: The ID of the campaign schema: type: string responses: "202": description: Campaign queued for processing content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: message: type: string example: "Campaign is being processed" taskId: type: string description: Internal task identifier for the queued job campaignId: type: string description: The ID of the campaign "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Campaign not found "500": $ref: "#/components/responses/InternalServerErrorResponse" /campaign/{id}/pause: post: summary: Pause a campaign x-fern-sdk-group-name: campaigns x-fern-sdk-method-name: pause description: | Queues a pause task and returns immediately — the campaign is **not** immediately paused. Poll `GET /campaign/{id}` and watch for `status: "paused"`. tags: - Campaigns security: - BearerAuth: [] parameters: - in: path name: id required: true description: The ID of the campaign schema: type: string responses: "200": description: Pause task queued successfully content: application/json: schema: type: object properties: status: type: boolean example: true "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /knowledgebase: get: summary: Get all knowledge bases description: Get all knowledge bases tags: - Knowledge Base x-fern-sdk-group-name: knowledge_base x-fern-sdk-method-name: list security: - BearerAuth: [] responses: "200": description: A list of knowledge bases content: application/json: schema: type: object properties: status: type: boolean example: true data: type: array items: $ref: "#/components/schemas/KnowledgeBase" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" post: summary: Create a knowledge base description: Create a knowledge base tags: - Knowledge Base x-fern-sdk-group-name: knowledge_base x-fern-sdk-method-name: create security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: name: type: string minLength: 1 maxLength: 40 description: Name of the knowledge base (1–40 characters, trimmed) description: type: string required: - name responses: "201": description: Knowledge base created successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: string example: "60d0fe4f5311236168a109ca" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /knowledgebase/{id}: get: summary: Get a knowledge base description: Get a knowledge base tags: - Knowledge Base x-fern-sdk-group-name: knowledge_base x-fern-sdk-method-name: get security: - BearerAuth: [] parameters: - in: path name: id required: true description: The ID of the knowledge base schema: type: string responses: "200": description: A knowledge base content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/KnowledgeBase" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Knowledge base not found "500": $ref: "#/components/responses/InternalServerErrorResponse" delete: summary: Delete a knowledge base x-fern-sdk-group-name: knowledge_base x-fern-sdk-method-name: delete description: | Delete a knowledge base. **400 is returned when the knowledge base is still linked to an agent:** `"This knowledge base is connected to an agent. Please detach it from the agent before deleting."` Detach the KB from all agents (via agent config) before attempting deletion. tags: - Knowledge Base security: - BearerAuth: [] parameters: - in: path name: id required: true description: The ID of the knowledge base schema: type: string responses: "200": description: Knowledge base deleted successfully content: application/json: schema: type: object properties: status: type: boolean example: true "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Knowledge base not found "500": $ref: "#/components/responses/InternalServerErrorResponse" post: summary: Update a knowledge base (name + description) description: | Updates the metadata of a knowledge base. **Note**: the platform uses `POST` (not `PATCH`) on this path — preserved here as-is. Only `name` and `description` are mutable through this endpoint. To add or remove content (files, URLs, text snippets), use the items endpoints. tags: - Knowledge Base security: - BearerAuth: [] parameters: - in: path name: id required: true schema: type: string description: 24-char hex ObjectId of the knowledge base. requestBody: required: true content: application/json: schema: type: object required: [name] properties: name: type: string minLength: 1 maxLength: 40 description: Display name. 1–40 characters; trimmed server-side. example: "Q4 Pricing Updates" description: type: string description: Optional free-text description shown in the dashboard. responses: "200": description: Knowledge base updated. content: application/json: schema: type: object properties: status: type: boolean example: true "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Knowledge base not found in your organization. "500": $ref: "#/components/responses/InternalServerErrorResponse" /knowledgebase/{id}/items: get: summary: Get all knowledge base items description: Get all knowledge base items tags: - Knowledge Base security: - BearerAuth: [] parameters: - in: path name: id required: true description: The ID of the knowledge base schema: type: string responses: "200": description: A list of knowledge base items content: application/json: schema: type: object properties: status: type: boolean example: true data: type: array items: $ref: "#/components/schemas/KnowledgeBaseItem" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /knowledgebase/{knowledgeBaseId}/items/{knowledgeBaseItemId}: delete: summary: Delete a knowledge base item description: Delete a knowledge base item tags: - Knowledge Base security: - BearerAuth: [] parameters: - in: path name: knowledgeBaseId required: true description: The ID of the knowledge base schema: type: string - in: path name: knowledgeBaseItemId required: true description: The ID of the knowledge base item schema: type: string responses: "200": description: Knowledge base item deleted successfully content: application/json: schema: type: object properties: status: type: boolean example: true "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /knowledgebase/{id}/items/upload-media: post: summary: Upload a PDF file to a knowledge base description: | Upload a PDF file to a knowledge base. Only PDF files are accepted (validated by MIME type and extension). **400 is returned for billing/entitlement failures before the file is processed:** - `"Insufficient credits for KB storage upload."` — account lacks upload credits - `"KB storage access is not enabled for your account."` — plan doesn't include KB storage No application-level file size limit is enforced — any proxy or infrastructure limits (e.g. nginx) apply instead. tags: - Knowledge Base security: - BearerAuth: [] parameters: - in: path name: id required: true description: The ID of the knowledge base schema: type: string requestBody: required: true content: multipart/form-data: schema: type: object properties: media: type: string format: binary required: - media responses: "201": description: Knowledge base item created successfully content: application/json: schema: type: object properties: status: type: boolean example: true "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /knowledgebase/get-presigned-url: post: summary: Get a presigned S3 URL for direct file upload description: | Two-step file upload flow that bypasses Atoms' API for the file bytes themselves — useful when files exceed the multipart upload limit on `POST /knowledgebase/{id}/items/upload-media` or when you want to upload from the browser without round-tripping through your backend. **Step 1**: Call this endpoint with file metadata. Atoms returns a presigned URL + a storage `key`. **Step 2**: `PUT` the file bytes directly to the presigned URL (set `Content-Type` to the same value you sent here). **Step 3**: Call [`POST /knowledgebase/compelete-file-upload`](#operation/completeKnowledgeBaseFileUpload) with the same `key` to commit the upload and start processing. Same end result as `POST /knowledgebase/{id}/items/upload-media`, just without the multipart-through-our-API hop. tags: - Knowledge Base security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [fileName, fileSize, contentType, knowledgeBaseId] properties: fileName: type: string description: Original filename — used for display in the Atoms dashboard. Doesn't have to match the S3 key. example: "company-handbook.pdf" fileSize: type: integer minimum: 1 description: Size in bytes. Atoms uses this to enforce per-file limits before issuing the URL. example: 2457600 contentType: type: string description: MIME type. You must send this EXACT value as `Content-Type` on the subsequent PUT to the presigned URL. example: "application/pdf" knowledgeBaseId: type: string description: 24-char hex ObjectId of the target knowledge base (from `GET /knowledgebase`). example: "6867ca76d0f8f2e0f4201281" responses: "200": description: Presigned URL ready — upload directly to it. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: url: type: string format: uri description: Time-limited presigned URL. PUT the file bytes here with `Content-Type` matching what you sent above. key: type: string description: S3 storage key — pass this back in `POST /knowledgebase/compelete-file-upload`. "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /knowledgebase/compelete-file-upload: post: summary: Complete a presigned-URL upload and start processing description: | Step 3 of the presigned-URL upload flow. Commits a file that was uploaded directly to S3 via `POST /knowledgebase/get-presigned-url`, registers it as a knowledge-base item, and triggers async processing. **Note**: The path includes `compelete` (sic) — that's the actual route name on the platform. Don't fix the spelling in your client; it's a stable URL. tags: - Knowledge Base security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [fileName, contentType, knowledgeBaseId, key, fileSize] properties: fileName: type: string description: Filename — pass the same value used in `get-presigned-url`. example: "company-handbook.pdf" contentType: type: string example: "application/pdf" knowledgeBaseId: type: string description: Target knowledge base ID. example: "6867ca76d0f8f2e0f4201281" key: type: string description: S3 storage key returned by `get-presigned-url`. fileSize: type: integer minimum: 1 responses: "200": description: File registered as a knowledge-base item. Processing runs async — poll `GET /knowledgebase/{id}/items` for the item to surface with the desired processing status. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object description: Created knowledge-base item record. "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /knowledgebase/get-sitemap-urls: post: summary: Extract URLs from a sitemap.xml x-fern-sdk-group-name: knowledge_base x-fern-sdk-method-name: extract_sitemap_urls description: | Fetches a website's `sitemap.xml`, parses it, and returns the list of URLs inside. Use this before calling `POST /knowledgebase/{id}/scrape-urls` to let the customer pick which URLs they actually want indexed. Returns `422` if the URL doesn't return a fetchable sitemap or if the XML is malformed. tags: - Knowledge Base security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [siteUrl, knowledgeBaseId] properties: siteUrl: type: string format: uri description: URL of the sitemap.xml file (or a homepage that links to one). example: "https://example.com/sitemap.xml" knowledgeBaseId: type: string description: Target knowledge base ID — used for ownership validation only. The endpoint doesn't write any URLs at this stage. example: "6867ca76d0f8f2e0f4201281" responses: "200": description: Extracted URLs, ready to be filtered + passed to `/scrape-urls`. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: urls: type: array items: type: string format: uri description: All URLs discovered in the sitemap. extractedAt: type: string format: date-time "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Knowledge base not found in your organization. "422": description: Could not fetch sitemap, or the sitemap XML is malformed. "500": $ref: "#/components/responses/InternalServerErrorResponse" /knowledgebase/{id}/scrape-urls: post: summary: Scrape a list of URLs into a knowledge base x-fern-sdk-group-name: knowledge_base x-fern-sdk-method-name: scrape_urls description: | Adds one or more URLs to a knowledge base by scraping each page's content, chunking it, and indexing for retrieval. Typical flow: 1. Discover candidate URLs (`POST /knowledgebase/get-sitemap-urls` or paste your own list). 2. Call this endpoint with the curated list — scraping runs async. 3. Poll `GET /knowledgebase/{id}/scraped-urls` for the per-URL status. Returns `400` if your account's KB billing precheck fails (quota or plan limits). Returns `404` if the KB doesn't belong to your organization. tags: - Knowledge Base security: - BearerAuth: [] parameters: - in: path name: id required: true schema: type: string description: 24-char hex ObjectId of the target knowledge base. requestBody: required: true content: application/json: schema: type: object required: [urls] properties: urls: type: array minItems: 1 items: type: string format: uri example: ["https://example.com/pricing", "https://example.com/faq"] responses: "200": description: Scrape job(s) queued. Poll `/scraped-urls` for per-URL status. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object description: Async job acknowledgement. Inspect `/scraped-urls` for per-URL progress. "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Knowledge base not found in your organization. "500": $ref: "#/components/responses/InternalServerErrorResponse" /knowledgebase/{id}/scraped-urls: get: summary: List scraped URLs in a knowledge base + their status description: | Returns every URL added to the knowledge base via `POST /knowledgebase/{id}/scrape-urls`, with its current scrape/index status. Poll this after kicking off a scrape job to track progress. tags: - Knowledge Base security: - BearerAuth: [] parameters: - in: path name: id required: true schema: type: string description: 24-char hex ObjectId of the knowledge base. responses: "200": description: Successful response. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: array items: type: object properties: _id: type: string url: type: string format: uri status: type: string description: Current scrape/index status (e.g. `pending`, `scraping`, `indexed`, `failed`). createdAt: type: string format: date-time updatedAt: type: string format: date-time "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /knowledgebase/{knowledgeBaseId}/scraped-urls/{knowledgeBaseScrapedUrlsId}: delete: summary: Delete a scraped URL from a knowledge base description: | Removes a previously-scraped URL (and its indexed content) from the knowledge base. Permanent — there is no undo. tags: - Knowledge Base security: - BearerAuth: [] parameters: - in: path name: knowledgeBaseId required: true schema: type: string description: 24-char hex ObjectId of the knowledge base. - in: path name: knowledgeBaseScrapedUrlsId required: true schema: type: string description: 24-char hex ObjectId of the scraped-URL row to delete (from `GET /{id}/scraped-urls`). responses: "200": description: URL removed. content: application/json: schema: type: object properties: status: type: boolean example: true "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /product/phone-numbers: get: summary: Get acquired phone numbers x-fern-sdk-group-name: phone_numbers x-fern-sdk-method-name: list description: | Retrieve all platform-purchased telephony numbers (Twilio/Plivo) for the organization. **Note:** Imported SIP numbers added via `POST /product/import-phone-number` are **not** included in this response — they are stored as a separate product type and returned by a different internal call. tags: - Phone Numbers security: - BearerAuth: [] responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: array items: type: object properties: _id: type: string description: The unique identifier for the phone number example: "6867ca76d0f8f2e0f4201281" productType: type: string enum: [telephony] description: The product type — always `telephony` for numbers returned by this endpoint isActive: type: boolean description: Whether the phone number is active example: false agentId: type: string nullable: true description: ID of the agent currently assigned to this number, or null if unassigned attributes: type: object description: Telephony provider attributes for the phone number properties: provider: type: string enum: [twilio, plivo] description: The telephony provider example: "twilio" phoneNumber: type: string description: The actual phone number in E.164 format example: "+13412184691" countryCode: type: string description: ISO 3166-1 alpha-2 country code of the number example: "US" areaCode: type: string description: Area code of the number (if applicable) example: "341" complianceApplicationId: type: string description: Compliance application ID associated with the number (if applicable) createdAt: type: string format: date-time description: The date and time when the phone number was created example: "2025-07-04T12:35:02.821Z" updatedAt: type: string format: date-time description: The date and time when the phone number was last updated example: "2025-07-07T08:11:35.327Z" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /product/all-numbers: get: summary: List all phone numbers (platform + SIP) description: | Returns every phone number owned by the organization in one response: - `telephonyProducts` — numbers rented via the Atoms platform (Plivo / Twilio). - `customProducts` — numbers imported via [`POST /product/import-phone-number`](#operation/importSipPhoneNumber) with your own SIP trunks. Use this when you need a single combined view (e.g. a "Pick a number" dropdown). To list only platform-rented numbers, use [`GET /product/phone-numbers`](#operation/getAcquiredPhoneNumbers). tags: - Phone Numbers security: - BearerAuth: [] responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: telephonyProducts: type: array items: $ref: "#/components/schemas/Product" customProducts: type: array items: $ref: "#/components/schemas/Product" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /product/get-available-numbers: get: summary: Search rentable phone numbers in inventory x-fern-sdk-group-name: phone_numbers x-fern-sdk-method-name: search_rentable description: | Searches the telephony provider's inventory for available numbers matching the requested country (and optional area code). Returns up to 5 candidates per call. Use the returned `phoneNumber` value in [`POST /product/rent-number`](#operation/rentPhoneNumber) to actually rent it. tags: - Phone Numbers security: - BearerAuth: [] parameters: - in: query name: countryCode required: true schema: type: string example: "US" description: ISO 3166-1 alpha-2 country code (e.g. `US`, `IN`, `GB`). - in: query name: provider required: true schema: type: string enum: [plivo, twilio] description: Telephony provider to search. - in: query name: areaCode required: false schema: type: string description: Optional area-code / region filter — provider-dependent (US area codes for plivo/twilio, etc.). responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: array items: type: object properties: phoneNumber: type: string description: E.164-style number without the leading `+`. Pass exactly this value to `POST /product/rent-number`. example: "13183747513" countryCode: type: string example: "US" provider: type: string enum: [plivo, twilio] example: "plivo" areaCode: type: string description: Region / state / area-code label returned by the provider. example: "Louisiana" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /product/proration-amount: get: summary: Preview prorated rental cost for renting a phone number today description: | Returns the immediate prorated charge for renting one phone number from today through the end of the current billing cycle, plus the recurring monthly rate. Use this to show a "you'll be charged $X today" preview before calling [`POST /product/rent-number`](#operation/rentPhoneNumber). Returns `400` if the organization doesn't have the phone-numbers feature configured (contact support) or if the org is currently locked (e.g. unpaid invoices — call [`GET /product/unpaid-invoices`](#operation/getUnpaidInvoices) first to check). tags: - Phone Numbers security: - BearerAuth: [] responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: immediateCharge: type: number format: float description: Amount that will be charged today (USD). example: 5.3 perNumberRecurringAmount: type: number format: float description: Monthly per-number recurring charge after the prorated first period (USD). example: 10 monthlyRate: type: number format: float example: 10 prorationAmount: type: number format: float example: 5.3 daysRemaining: type: integer example: 16 daysInMonth: type: integer example: 30 proratedValue: type: number format: float description: Fraction of the month remaining (`daysRemaining / daysInMonth`). example: 0.53 "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /product/rent-number: post: summary: Rent a phone number from the telephony inventory x-fern-sdk-group-name: phone_numbers x-fern-sdk-method-name: rent description: | Rents an available number returned by [`GET /product/get-available-numbers`](#operation/searchAvailablePhoneNumbers). Charges the organization the prorated amount returned by [`GET /product/proration-amount`](#operation/getProrationAmount) immediately, then the monthly rate on each billing cycle. Always call `GET /product/proration-amount` first to surface the immediate charge to your customer. The endpoint may return `200` with a body containing `requiresAction: true` when payment requires customer interaction (3-D Secure, etc.) — handle that branch in your client. Released later via [`POST /product/release-number`](#operation/releasePhoneNumber). tags: - Phone Numbers security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [phoneNumber, provider] properties: phoneNumber: type: string description: The number to rent — exactly as returned by `GET /product/get-available-numbers` (no leading `+`). example: "13183747513" provider: type: string enum: [plivo, twilio] responses: "200": description: Rental processed. Inspect `data.requiresAction` to determine whether the customer needs to complete a payment-method action. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: requiresAction: type: boolean description: If `true`, payment requires further customer action (3-D Secure / SCA). Surface the client-secret flow. "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /product/release-number: post: summary: Release a rented phone number x-fern-sdk-group-name: phone_numbers x-fern-sdk-method-name: release description: | Releases a phone number previously rented via `POST /product/rent-number`. The number goes back into provider inventory and recurring charges stop. Returns `400` if the number is still assigned to an agent — detach it from the agent first (`PATCH /agent/{agentId}` with `productId: null`). tags: - Phone Numbers security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [productId] properties: productId: type: string description: 24-char hex MongoDB ObjectId of the phone-number product to release (the `_id` value returned by `GET /product/phone-numbers`). example: "6969109c84c74bed175f02a7" responses: "200": description: Number released content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: success: type: boolean example: true "400": description: | Number is still assigned to an agent (detach it first), or invalid product ID format. "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /product/manage-subscription: get: summary: Get Stripe Customer Portal URL description: | Returns a time-limited Stripe Customer Portal URL the user can open to manage their subscription (update payment method, view invoices, etc.). Returns an empty object if the organization isn't on a Stripe-backed plan. tags: - Phone Numbers security: - BearerAuth: [] responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: url: type: string format: uri description: Time-limited Stripe Customer Portal URL. Empty object if not applicable. "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /product/unpaid-invoices: get: summary: Check whether the organization has unpaid invoices description: | Returns whether the org has unpaid invoices that would block destructive actions (renting numbers, etc.). Call this before any billable mutation to surface the "Pay outstanding balance" flow. tags: - Phone Numbers security: - BearerAuth: [] responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: paymentRequired: type: boolean description: When `true`, the org has at least one unpaid invoice. Surface a "Pay balance" CTA before allowing further billable actions. example: false "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /product/import-phone-number: post: summary: Import a SIP phone number x-fern-sdk-group-name: phone_numbers x-fern-sdk-method-name: import_sip description: | Bring your own SIP trunk by importing an existing phone number with its SIP termination URL. Atoms creates both inbound and outbound SIP trunks so your number works for making and receiving calls through the platform. If `name` is omitted, a name is auto-generated from the phone number and user ID. tags: - Phone Numbers security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: - phoneNumber - sipTerminationUrl properties: phoneNumber: type: string description: Your existing phone number. E.164 format is recommended but not enforced server-side — any non-empty string is accepted. example: "+14155551234" sipTerminationUrl: type: string description: The SIP URI where calls should be routed to your infrastructure example: "sip:trunk.your-provider.com" name: type: string description: A friendly display name for this number example: "Main Support Line" sipUsername: type: string description: Username for SIP authentication (if your trunk requires it) example: "my-sip-user" sipPassword: type: string description: Password for SIP authentication (if your trunk requires it) example: "my-sip-password" example: phoneNumber: "+14155551234" sipTerminationUrl: "sip:trunk.your-provider.com" name: "Main Support Line" sipUsername: "" sipPassword: "" responses: "200": description: Phone number imported successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: _id: type: string description: Unique identifier of the created product example: "507f1f77bcf86cd799439011" productType: type: string enum: [custom] description: The type of product created — always `custom` for imported SIP numbers example: "custom" isActive: type: boolean description: Whether the number is active and ready to use example: true attributes: type: object properties: name: type: string description: Display name for the number example: "Main Support Line" phoneNumber: type: string description: The imported phone number example: "+14155551234" outboundSipTrunkId: type: string description: Identifier for the outbound SIP trunk created example: "ST_xxxxxxxxxxxx" inboundSipTrunkId: type: string description: Identifier for the inbound SIP trunk created example: "ST_xxxxxxxxxxxx" agentId: type: string nullable: true description: ID of the agent assigned to this number (null if unassigned) example: null createdAt: type: string format: date-time description: Timestamp when the product was created example: "2026-03-16T12:00:00.000Z" updatedAt: type: string format: date-time description: Timestamp when the product was last updated example: "2026-03-16T12:00:00.000Z" "400": description: | Bad request — missing required fields or phone number already imported. Exact error when a duplicate number is submitted: `"Number already present"` content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string description: List of validation error messages example: ["Phone number is required"] "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /compliance/status: get: summary: Get compliance status description: | Returns the current compliance status for a given country, number type, and user type. This is the single endpoint the frontend uses to determine which step to render (form, submitted, accepted, rejected, expired, or suspended). tags: - Compliance security: - BearerAuth: [] parameters: - name: countryIso in: query required: true schema: type: string minLength: 2 maxLength: 2 description: | ISO 3166-1 alpha-2 country code. Must be exactly 2 characters (e.g. "IN", "US"). Sending 3+ characters returns 400. example: "IN" - name: numberType in: query required: true schema: type: string enum: [local, mobile, tollfree] description: The type of phone number example: "local" - name: userType in: query required: true schema: type: string enum: [individual, business] description: The type of end user example: "business" responses: "200": description: Compliance status retrieved successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: step: type: string enum: [form, submitted, accepted, rejected, expired, suspended] description: | The current compliance step: - `form` — no application exists, user should submit one - `submitted` — application is under review - `accepted` — approved, user can rent numbers - `rejected` — rejected, user can resubmit with corrected documents - `expired` — compliance expired - `suspended` — compliance suspended example: "form" application: nullable: true description: The existing compliance application, or null if none exists $ref: "#/components/schemas/ComplianceApplication" requiredDocuments: type: array description: Document types required for this country/numberType/userType combination items: $ref: "#/components/schemas/RequiredDocumentType" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" "502": description: Bad gateway — Plivo's compliance API returned an error or is unavailable content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" /compliance/requirements: get: summary: Get compliance requirements description: | Discover what documents are required for a given country, number type, and user type. Results are cached for 1 hour. Returns an empty `documentTypes` array if no compliance is needed for the given combination. tags: - Compliance security: - BearerAuth: [] parameters: - name: countryIso in: query required: true schema: type: string minLength: 2 maxLength: 2 description: | ISO 3166-1 alpha-2 country code. Must be exactly 2 characters (e.g. "IN", "US"). Sending 3+ characters returns 400. example: "IN" - name: numberType in: query required: true schema: type: string enum: [local, mobile, tollfree] description: The type of phone number example: "local" - name: userType in: query required: true schema: type: string enum: [individual, business] description: The type of end user example: "business" responses: "200": description: Requirements retrieved successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/ComplianceRequirement" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" "502": description: Bad gateway — Plivo's compliance API returned an error or is unavailable content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" /compliance/applications: post: summary: Submit a compliance application x-fern-sdk-group-name: compliance x-fern-sdk-method-name: submit description: | Submit a new compliance application with end-user details and supporting documents. One application is allowed per organization per country per number type per user type. The request uses `multipart/form-data` because documents are uploaded inline. The `endUser` and `documents` fields are JSON strings embedded in the form data. tags: - Compliance security: - BearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: - countryIso - numberType - userType - endUser - documents - files properties: countryIso: type: string minLength: 2 maxLength: 2 description: ISO 3166-1 alpha-2 country code example: "IN" numberType: type: string enum: [local, mobile, tollfree] description: The type of phone number example: "local" userType: type: string enum: [individual, business] description: The type of end user example: "business" endUser: type: string description: | JSON-stringified end-user details. `name` is required; all other fields are optional but may be required by Plivo depending on country/numberType. Accepted fields: - `name` (required) — full name or business name - `lastName` — last name - `email` — email address - `addressLine1` — street address line 1 - `addressLine2` — street address line 2 - `city` — city - `state` — state or province - `postalCode` — postal/ZIP code - `country` — ISO country code; defaults to `countryIso` if omitted - `registrationNumber` — business registration number (required for some business applications) example: '{"name":"Acme Corp","email":"legal@acme.com","addressLine1":"123 Main St","city":"Mumbai","state":"MH","postalCode":"400001","country":"IN"}' documents: type: string description: | JSON string containing an array of document metadata. Each entry must have a `documentTypeId` (from the requirements endpoint) and optional `dataFields`. Example: ```json [{"documentTypeId": "dt_123", "dataFields": {"business_name": "Acme Corp"}}] ``` example: '[{"documentTypeId": "dt_123", "dataFields": {"business_name": "Acme Corp"}}]' files: type: array items: type: string format: binary description: | Document files in the same order as the `documents` metadata array. Accepted formats: PDF, JPEG, PNG. Maximum 5 MB per file, up to 10 files. responses: "201": description: Application submitted successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/ComplianceApplication" "400": description: Validation error — invalid JSON, unsupported file type, or file count mismatch (`"Expected X files, got Y"`) content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "409": description: | A compliance application already exists for this country/numberType combination. Exact message: `"A compliance application already exists for {countryIso}/{numberType}. Status: {status}"` content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" "502": description: Bad gateway — Plivo's compliance API returned an error or is unavailable content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" /compliance/applications/{id}: patch: summary: Resubmit a rejected compliance application x-fern-sdk-group-name: compliance x-fern-sdk-method-name: resubmit description: | Resubmit a previously rejected compliance application with corrected documents. Only applications in `rejected` status can be resubmitted. All documents must be re-uploaded — partial updates are not supported. File/document count must match exactly. Mismatch returns 400 with message `"Expected X files, got Y"`. tags: - Compliance security: - BearerAuth: [] parameters: - name: id in: path required: true schema: type: string description: The compliance application ID requestBody: required: true content: multipart/form-data: schema: type: object required: - documents - files properties: documents: type: string description: | JSON string containing an array of document metadata. Same format as the create endpoint. example: '[{"documentTypeId": "dt_123", "dataFields": {"business_name": "Acme Corp"}}]' files: type: array items: type: string format: binary description: | Replacement document files. Must match the length of the `documents` array. Accepted formats: PDF, JPEG, PNG. Maximum 5 MB per file. responses: "200": description: Application resubmitted successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/ComplianceApplication" "400": description: Application is not in rejected status, file count mismatch, or other validation error content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Application not found or does not belong to this organization content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" "502": description: Bad gateway — Plivo's compliance API returned an error or is unavailable content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" /compliance/applications/{id}/refresh: post: summary: Refresh compliance application status description: | Manually poll Plivo for the latest status of a compliance application. Use this as a fallback when webhooks are delayed. The frontend enforces a 60-second cooldown between refreshes. tags: - Compliance security: - BearerAuth: [] parameters: - name: id in: path required: true schema: type: string description: The compliance application ID responses: "200": description: Application status refreshed content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/ComplianceApplication" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Application not found or does not belong to this organization content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" "502": description: Bad gateway — Plivo's compliance API returned an error or is unavailable content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" /webhook: get: summary: Get webhooks description: Retrieve all webhooks for the organization or a specific webhook by ID tags: - Webhooks security: - BearerAuth: [] parameters: - in: query name: webhookId schema: type: string description: Optional MongoDB ObjectId (24-char hex) of a specific webhook to retrieve. If omitted, returns all webhooks for the organization. responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: oneOf: - $ref: "#/components/schemas/Webhook" - type: array items: $ref: "#/components/schemas/Webhook" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" post: summary: Create a webhook x-fern-sdk-group-name: webhooks x-fern-sdk-method-name: create description: | Create a new webhook with subscriptions for specific agents and events. **400 is also returned when the endpoint URL is already registered:** `"A webhook with this URL has already been registered"` tags: - Webhooks security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: endpoint: type: string description: The webhook endpoint URL example: "https://example.com/webhook" description: type: string description: The description of the webhook example: "Webhook for conversation events" events: type: array description: Array of events to subscribe to items: type: object required: - agentId - eventType properties: agentId: type: string description: The ID of the agent example: "60d0fe4f5311236168a109ca" eventType: type: string enum: [pre-conversation, post-conversation, analytics-completed] description: The type of event to subscribe to example: "post-conversation" required: - endpoint - description - events responses: "201": description: Webhook created successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: string description: The ID of the created webhook example: "60d0fe4f5311236168a109ca" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /webhook-events/pre-conversation: post: x-fern-webhook: true tags: - Webhooks summary: pre-conversation operationId: webhookEventPreConversation description: | Fired **before** the agent begins speaking. Use this to enrich CRM data, log call attempts, or gate outbound calls. Does **not** contain `callData`, `transcript`, `variables`, `analytics`, or `recordingUrl`. `callData` is on `post-conversation` and `analytics-completed`; `transcript`, `variables`, and `recordingUrl` are only on `post-conversation`; `analytics` is only on `analytics-completed`. For the full field-level reference, see the [Webhooks guide](/atoms/atoms-platform/features/webhooks). requestBody: description: Event body delivered to your configured webhook URL. required: true content: application/json: schema: $ref: "#/components/schemas/WebhookEventPreConversation" responses: "2XX": description: Your endpoint should return a 2XX status to acknowledge receipt. /webhook-events/post-conversation: post: x-fern-webhook: true tags: - Webhooks summary: post-conversation operationId: webhookEventPostConversation description: | Fired **after** the call ends. Contains the full transcript, call metadata, recording URL, and all agent variables that were in scope during the conversation. For the full field-level reference, see the [Webhooks guide](/atoms/atoms-platform/features/webhooks). requestBody: description: Event body delivered to your configured webhook URL. required: true content: application/json: schema: $ref: "#/components/schemas/WebhookEventPostConversation" responses: "2XX": description: Your endpoint should return a 2XX status to acknowledge receipt. /webhook-events/analytics-completed: post: x-fern-webhook: true tags: - Webhooks summary: analytics-completed operationId: webhookEventAnalyticsCompleted description: | Fired **after** Atoms finishes running the configured disposition and success metrics on the transcript. Arrives some time after `post-conversation`. For the full field-level reference, see the [Webhooks guide](/atoms/atoms-platform/features/webhooks). requestBody: description: Event body delivered to your configured webhook URL. required: true content: application/json: schema: $ref: "#/components/schemas/WebhookEventAnalyticsCompleted" responses: "2XX": description: Your endpoint should return a 2XX status to acknowledge receipt. /webhook/{id}: delete: summary: Delete a webhook x-fern-sdk-group-name: webhooks x-fern-sdk-method-name: delete description: | Delete a webhook by its ID. **400 is returned when the webhook still has active agent subscriptions:** `"Cannot delete webhook: It is currently assigned to one or more agents. Please remove all agent assignments first."` Call `DELETE /agent/{agentId}/webhook-subscriptions` for each assigned agent before deleting. **400 is also returned for an invalid webhook ID format:** `"The provided Webhook ID is invalid."` tags: - Webhooks security: - BearerAuth: [] parameters: - in: path name: id required: true description: The ID of the webhook to delete schema: type: string responses: "200": description: Webhook deleted successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: string description: Success message example: "Webhook deleted successfully" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Webhook not found content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Webhook not found"] "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{agentId}/webhook-subscriptions: get: summary: Get webhook subscriptions for an agent description: Retrieve webhook subscriptions for a given agent ID tags: - Webhooks security: - BearerAuth: [] parameters: - in: path name: agentId required: true description: The ID of the agent schema: type: string responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: array items: $ref: "#/components/schemas/WebhookSubscription" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent not found content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Agent not found"] "500": $ref: "#/components/responses/InternalServerErrorResponse" post: summary: Replace webhook subscriptions for an agent description: | **Replaces** all existing webhook subscriptions for the agent with the provided event types. Any previously configured subscriptions for this agent are deleted before the new ones are created. To add subscriptions without removing existing ones, retrieve current subscriptions first and include them in the request. tags: - Webhooks security: - BearerAuth: [] parameters: - in: path name: agentId required: true description: The ID of the agent to create subscriptions for schema: type: string requestBody: required: true content: application/json: schema: type: object properties: eventTypes: type: array description: Array of event types to subscribe to items: type: string enum: [pre-conversation, post-conversation, analytics-completed] description: The type of event to subscribe to example: "post-conversation" webhookId: type: string description: The ID of the webhook to subscribe to example: "60d0fe4f5311236168a109ca" required: - eventTypes - webhookId responses: "201": description: Subscriptions created successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: string description: Success message example: "Subscriptions created successfully" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent not found content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Agent not found"] "500": $ref: "#/components/responses/InternalServerErrorResponse" delete: summary: Delete webhook subscriptions for an agent description: | Deletes **all** webhook subscriptions for the agent, regardless of which webhook they belong to. If the agent has subscriptions across multiple webhooks, all of them are removed in a single call. tags: - Webhooks security: - BearerAuth: [] parameters: - in: path name: agentId required: true description: The ID of the agent to filter subscriptions by schema: type: string responses: "200": description: Subscriptions deleted successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: string description: Success message example: "Subscriptions deleted successfully" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent not found content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Agent not found"] "500": $ref: "#/components/responses/InternalServerErrorResponse" /audience: get: summary: Get all audiences x-fern-sdk-group-name: audience x-fern-sdk-method-name: list description: Retrieve all audiences created by the authenticated user. Users can only access audiences they have created. tags: - Audience security: - BearerAuth: [] responses: "200": description: Successfully retrieved audiences content: application/json: schema: type: object properties: status: type: boolean example: true data: type: array items: type: object properties: _id: type: string description: The unique identifier for the audience example: "60d0fe4f5311236168a109ca" name: type: string description: The name of the audience example: "My Customer List" description: type: string description: The description of the audience example: "List of customers for marketing campaign" phoneNumberColumnName: type: string description: The name of the column in the CSV that contains phone numbers example: "phoneNumber" organization: type: string description: The organization ID example: "60d0fe4f5311236168a109cb" createdBy: type: string description: The user ID who created the audience example: "60d0fe4f5311236168a109cc" createdAt: type: string format: date-time description: The date and time when the audience was created example: "2025-01-15T10:30:00.000Z" updatedAt: type: string format: date-time description: The date and time when the audience was last updated example: "2025-01-15T10:30:00.000Z" memberCount: type: number description: Current number of members in the audience hasCampaigns: type: boolean description: Whether any campaigns are currently using this audience campaigns: type: array description: Active campaigns using this audience items: type: object properties: _id: type: string name: type: string status: type: string createdAt: type: string format: date-time "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" post: summary: Create audience with CSV upload description: | Create a new audience by uploading a CSV file containing phone numbers. Only CSV text files are accepted — binary files will produce malformed data. **Additional 400 cases:** - Duplicate phone numbers in the CSV: `"Some phone numbers in your CSV already exist in this audience. Please remove duplicate entries and try again."` - Member limit exceeded: `"Audience cannot exceed X members"` tags: - Audience security: - BearerAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object properties: name: type: string description: The name of the audience example: "test_audience" description: type: string description: Optional description of the audience example: "List of customers for marketing campaign" phoneNumberColumnName: type: string description: The name of the column in the CSV that contains phone numbers example: "phoneNumber" identifierColumnName: type: string description: The name of the column in the CSV that contains identifiers (e.g., names) example: "Name" file: type: string format: binary description: CSV file containing phone numbers and identifiers (max 5MB) example: "audience_template.csv" required: - name - phoneNumberColumnName - file responses: "200": description: Audience created successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: _id: type: string description: The unique identifier for the audience example: "60d0fe4f5311236168a109ca" name: type: string description: The name of the audience example: "My Customer List" description: type: string description: The description of the audience example: "List of customers for marketing campaign" phoneNumberColumnName: type: string description: The name of the column in the CSV that contains phone numbers example: "phoneNumber" identifierColumnName: type: string description: The name of the column in the CSV that contains identifiers example: "Name" organization: type: string description: The organization ID example: "60d0fe4f5311236168a109cb" createdBy: type: string description: The user ID who created the audience example: "60d0fe4f5311236168a109cc" createdAt: type: string format: date-time description: The date and time when the audience was created example: "2025-01-15T10:30:00.000Z" updatedAt: type: string format: date-time description: The date and time when the audience was last updated example: "2025-01-15T10:30:00.000Z" "400": description: Bad request content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: [ "CSV file is required", "Some phone numbers in your CSV already exist in this audience. Please remove duplicate entries and try again.", ] "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /audience/{id}: get: summary: Get audience by ID x-fern-sdk-group-name: audience x-fern-sdk-method-name: get description: | Retrieve a specific audience by its ID. Note: if the audience belongs to a different organization, the API returns 404 (not 403) — ownership is deliberately obscured. tags: - Audience security: - BearerAuth: [] parameters: - name: id in: path required: true description: The unique identifier of the audience schema: type: string example: "60d0fe4f5311236168a109ca" responses: "200": description: Successfully retrieved audience content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: _id: type: string description: The unique identifier for the audience example: "60d0fe4f5311236168a109ca" name: type: string description: The name of the audience example: "My Customer List" description: type: string description: The description of the audience example: "List of customers for marketing campaign" phoneNumberColumnName: type: string description: The name of the column in the CSV that contains phone numbers example: "phoneNumber" organization: type: string description: The organization ID example: "60d0fe4f5311236168a109cb" createdBy: type: string description: The user ID who created the audience example: "60d0fe4f5311236168a109cc" createdAt: type: string format: date-time description: The date and time when the audience was created example: "2025-01-15T10:30:00.000Z" updatedAt: type: string format: date-time description: The date and time when the audience was last updated example: "2025-01-15T10:30:00.000Z" "400": description: Bad request content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Audience ID missing"] "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Audience not found (also returned when audience belongs to a different organization) "500": $ref: "#/components/responses/InternalServerErrorResponse" delete: summary: Delete audience description: | Delete a specific audience by its ID. Users can only delete audiences they created. **400 is returned if the audience is used by an active campaign:** `"can't delete audience, campaign with this audience exists"` Remove the campaign first, then retry deletion. On success, `data` is always an empty array `[]`. tags: - Audience security: - BearerAuth: [] parameters: - name: id in: path required: true description: The unique identifier of the audience to delete schema: type: string example: "60d0fe4f5311236168a109ca" responses: "200": description: Audience deleted successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: array example: [] "400": description: Bad request content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["can't delete audience, campaign with this audience 60d0fe4f5311236168a109ca exists"] "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Audience not found "500": $ref: "#/components/responses/InternalServerErrorResponse" /audience/{id}/members: get: summary: Get audience members description: Retrieve members of a specific audience with pagination support. Users can only access members of audiences they created. tags: - Audience security: - BearerAuth: [] parameters: - name: id in: path required: true description: The unique identifier of the audience schema: type: string example: "60d0fe4f5311236168a109ca" - name: page in: query required: false description: Page number for pagination (default is 1) schema: type: integer minimum: 1 default: 1 example: 1 - name: offset in: query required: false description: | Number of items per page (default is 5). Note: this parameter is named "offset", not "limit" — sending ?limit=N is silently ignored. schema: type: integer minimum: 1 default: 5 example: 10 responses: "200": description: Successfully retrieved audience members content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: members: type: array items: type: object properties: _id: type: string description: The unique identifier for the audience member example: "60d0fe4f5311236168a109cd" data: type: object description: Dynamic data from CSV, structure depends on uploaded file example: phoneNumber: "+1234567890" name: "John Doe" email: "john@example.com" totalCount: type: integer description: Total number of members in the audience example: 150 totalPages: type: integer description: Total number of pages available example: 15 hasMore: type: boolean description: Whether there are more pages available example: true "400": description: Bad request content: application/json: schema: type: object properties: status: type: string example: "error" errors: type: array items: type: string example: ["Audience ID is required"] "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": description: Forbidden — audience belongs to a different organization "404": description: Audience not found "500": description: Internal server error content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Failed to fetch audience members"] post: summary: Add audience members description: | Add new members to an existing audience. Each member object must include a key matching the audience's `phoneNumberColumnName`. If it's missing, the API returns 400: `"Each member must have a field"`. Adding members that would exceed the audience limit also returns 400. Note: if the audience belongs to a different organization, the API returns 404 (not 403). tags: - Audience security: - BearerAuth: [] parameters: - name: id in: path required: true description: The unique identifier of the audience schema: type: string example: "60d0fe4f5311236168a109ca" requestBody: required: true content: application/json: schema: type: object properties: members: type: array description: Array of member objects with dynamic structure based on audience configuration items: type: object description: Member data with keys matching the audience's CSV structure. Must include the phone number column. example: phoneNumber: "+1234567890" name: "John Doe" email: "john@example.com" required: - members responses: "200": description: Members added successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: array items: type: object properties: message: type: string example: "5 members added successfully" data: type: object properties: added: type: integer description: Number of members successfully added example: 5 skipped: type: integer description: Number of members skipped (e.g., duplicates) example: 2 "400": description: Bad request content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: [ "Each member must have a phoneNumber field", "Cannot add 15 members. You currently have 9990 members in this audience. The maximum limit is 10000 members. You can add up to 10 more members.", ] "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Audience not found (also returned when audience belongs to a different organization) "500": $ref: "#/components/responses/InternalServerErrorResponse" delete: summary: Delete audience members description: Remove specific members from an audience by their member IDs. Users can only delete members from audiences they created. tags: - Audience security: - BearerAuth: [] parameters: - name: id in: path required: true description: The unique identifier of the audience schema: type: string example: "60d0fe4f5311236168a109ca" requestBody: required: true content: application/json: schema: type: object properties: memberIds: type: array description: Array of member IDs to delete items: type: string example: "60d0fe4f5311236168a109cd" required: - memberIds responses: "200": description: Members deleted successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: deletedCount: type: integer description: Number of members successfully deleted example: 3 "400": description: Bad request content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Audience ID missing"] "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Audience not found (also returned when audience belongs to a different organization) "500": $ref: "#/components/responses/InternalServerErrorResponse" /audience/{id}/members/search: get: summary: Search audience members description: | Search for members within a specific audience using flexible search parameters. Users can only search members of audiences they created. **Search Types:** - **General Search** (`query`): Searches across all fields in the audience member data - **Field-Specific Search**: Use any field name as a parameter (e.g., `firstName=john`, `phoneNumber=123456`, `email=test@example.com`) **Examples:** - `?query=john` - General search across all fields - `?firstName=john` - Search specifically in firstName field - `?phoneNumber=555-1234` - Search specifically in phoneNumber field - `?firstName=john&lastName=doe` - Search for members matching both criteria **Note:** When using phoneNumber field, do not use quotes around the phone number. You can use either a general search OR field-specific searches, but not both simultaneously. tags: - Audience security: - BearerAuth: [] parameters: - name: id in: path required: true description: The unique identifier of the audience schema: type: string example: "60d0fe4f5311236168a109ca" - name: query in: query required: false description: General search term that searches across all fields in audience member data schema: type: string example: "john" - name: "*" in: query required: false description: | Any field name can be used as a query parameter for field-specific searches. Examples: firstName, lastName, phoneNumber, email, etc. The parameter name becomes the field to search in, and the value is the search term. When using phoneNumber field, do not use quotes around the phone number. schema: type: string example: "field_value" responses: "200": description: Search results returned successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: members: type: array items: type: object properties: _id: type: string description: The unique identifier for the audience member example: "60d0fe4f5311236168a109cd" data: type: object description: Dynamic data from CSV, structure depends on uploaded file example: phoneNumber: "+1234567890" name: "John Doe" email: "john@example.com" searchInfo: type: object description: Information about the search performed properties: searchType: type: string description: The type of search performed enum: ["general", "multiple"] example: "multiple" searchTerm: type: string description: The search term(s) used example: "john" searchFields: type: array items: type: string description: The specific fields searched (for field-specific searches) example: ["firstName", "lastName"] totalResults: type: integer description: The number of results returned example: 5 "400": description: Bad request content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: [ "At least one search parameter is required. Use 'query' for general search across all fields, or use field-specific searches like 'firstName=john' or 'phoneNumber=123456'.", ] "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": description: Audience not found "500": description: Internal server error content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Failed to search audience members"] # ── Agent Versioning: Drafts ─────────────────────────────────────────── /agent/{id}/drafts: post: summary: Create a draft x-fern-sdk-group-name: agent_versioning_drafts x-fern-sdk-method-name: create_draft description: Create a new draft from an existing published version or another draft. At least one of sourceVersionId or sourceDraftId is required (both may be sent simultaneously). tags: - Agent Versioning - Drafts security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateDraftRequest" responses: "201": description: Draft created successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/AgentVersion" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent not found "500": $ref: "#/components/responses/InternalServerErrorResponse" get: summary: List active drafts description: List all active (non-discarded) drafts for an agent. tags: - Agent Versioning - Drafts security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: array items: allOf: - $ref: "#/components/schemas/AgentVersion" - type: object properties: lastEditorName: type: string nullable: true description: Display name of the last editor "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent not found "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/drafts/{draftId}: get: summary: Get draft detail description: Returns the latest revision of a draft along with its edit history. tags: - Agent Versioning - Drafts security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - $ref: "#/components/parameters/DraftId" - name: limit in: query required: false description: Max number of edit history entries to return (1-100) schema: type: integer minimum: 1 maximum: 100 responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: latest: $ref: "#/components/schemas/AgentVersion" editHistory: type: array items: $ref: "#/components/schemas/DraftEditHistoryEntry" editCount: type: integer description: Total number of edits on this draft "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent or draft not found "500": $ref: "#/components/responses/InternalServerErrorResponse" patch: summary: Rename a draft x-fern-sdk-group-name: agent_versioning_drafts x-fern-sdk-method-name: rename_draft description: | Rename a draft. For config changes, use PATCH /agent/{id}/drafts/{draftId}/config instead. tags: - Agent Versioning - Drafts security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - $ref: "#/components/parameters/DraftId" requestBody: required: true content: application/json: schema: type: object required: - draftName properties: draftName: type: string minLength: 1 maxLength: 100 description: New name for the draft (1–100 characters) responses: "200": description: Draft renamed successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: draftName: type: string "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent or draft not found "500": $ref: "#/components/responses/InternalServerErrorResponse" delete: summary: Discard a draft x-fern-sdk-group-name: agent_versioning_drafts x-fern-sdk-method-name: discard_draft description: Discard (soft-delete) a draft. Only the draft creator or an admin can discard. tags: - Agent Versioning - Drafts security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - $ref: "#/components/parameters/DraftId" responses: "200": description: Draft discarded successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: "null" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": description: | Forbidden. Returned in two cases: - The caller is not the draft creator or an org admin - The agent uses workflow_graph and the org lacks conversational agents access content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "404": description: Agent or draft not found "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/drafts/{draftId}/diff: get: summary: Get draft diff description: Compare a draft against its source version or another specified version. tags: - Agent Versioning - Drafts security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - $ref: "#/components/parameters/DraftId" - name: compareTo in: query required: false description: Version ID to compare against. If omitted, compares against the source version. schema: type: string pattern: "^[a-f\\d]{24}$" responses: "200": description: Diff returned successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object description: Section-by-section diff between the draft and the comparison target "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent or draft not found "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/drafts/{draftId}/publish: post: summary: Publish a draft x-fern-sdk-group-name: agent_versioning_drafts x-fern-sdk-method-name: publish_draft description: Publish a draft as a new versioned release. Optionally activate it immediately. tags: - Agent Versioning - Drafts security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - $ref: "#/components/parameters/DraftId" requestBody: required: false content: application/json: schema: $ref: "#/components/schemas/PublishDraftRequest" responses: "201": description: Draft published as a new version content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/AgentVersion" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent or draft not found "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/drafts/{draftId}/test-call: post: summary: Test call with draft config description: Initiate a test call using the draft's resolved configuration. tags: - Agent Versioning - Drafts security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - $ref: "#/components/parameters/DraftId" requestBody: required: false content: application/json: schema: $ref: "#/components/schemas/TestCallRequest" responses: "200": description: Test call initiated content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object description: Test call result details properties: callId: type: string description: The call ID of the initiated test call. Use with GET /conversation/{id} to fetch the call log. "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent or draft not found "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/drafts/{draftId}/config: patch: summary: Edit draft config (prompt, tools, post-call metrics, voice, etc.) x-fern-sdk-group-name: agent_versioning_drafts x-fern-sdk-method-name: update_draft_config description: | Update the configuration of a draft. This single endpoint is how every agent-level config field is changed: prompt, tools, voice, language, **post-call analytics (disposition metrics)**, and more. There is no standalone post-call-analytics endpoint — it lives here as the `postCallAnalyticsConfig` body field. ## Post-Call Analytics Pass a `postCallAnalyticsConfig` object to configure disposition metrics (STRING, BOOLEAN, INTEGER, ENUM, DATETIME) that are automatically extracted from each completed call, along with the `useInternalAnalyticsModel` and `useReasoningModel` flags. See the [Post-Call Metrics guide](/atoms/atoms-platform/features/post-call-metrics) for a full Python walkthrough and disposition metric schema reference. ## Full payload Accepts the full agent-shaped config payload (language, synthesizer, slmModel, defaultVariables, preCallAPI, etc.) plus two draft-specific fields: - `singlePromptConfig` — prompt and tools (end_call, transfer_call, api_call, extract_dynamic_variables, knowledge_base_search). - `postCallAnalyticsConfig` — disposition metrics + analytics/ reasoning model flags. Each PATCH increments the draft's revision counter. Config is not live until the draft is published and activated (see `/drafts/{draftId}/publish` and `/versions/{versionId}/activate`). tags: - Agent Versioning - Drafts - Post-Call Analytics security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - $ref: "#/components/parameters/DraftId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/DraftConfigRequest" responses: "200": description: Draft config updated successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/AgentVersion" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/ForbiddenError" "404": description: Agent or draft not found "500": $ref: "#/components/responses/InternalServerErrorResponse" # ── Agent Versioning: Published Versions ─────────────────────────────── /agent/{id}/versions: get: summary: List published versions description: | List published versions for an agent with pagination and optional pin filter. The `total` value currently represents the total number of published versions for the agent, not necessarily the filtered count when `isPinned` is used. tags: - Agent Versioning - Versions security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - name: limit in: query required: false description: Number of versions to return (1-100, default 20) schema: type: integer minimum: 1 maximum: 100 default: 20 - name: skip in: query required: false description: Number of versions to skip (default 0) schema: type: integer minimum: 0 default: 0 - name: isPinned in: query required: false description: Filter by pinned status schema: type: boolean responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: versions: type: array items: allOf: - $ref: "#/components/schemas/AgentVersion" - type: object properties: publishedByName: type: string nullable: true description: Display name of the user who published activatedByName: type: string nullable: true description: Display name of the user who activated the version total: type: integer description: Total published versions for the agent. When `isPinned` is used, this may not equal the filtered result count. "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/WorkflowGraphAgentAccessForbiddenError" "404": description: Agent not found content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/versions/diff: get: summary: Diff two versions description: Compare two version or draft revision records side-by-side by their IDs. The implementation tries published versions first and can fall back to the latest draft revision. tags: - Agent Versioning - Versions security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - name: versionA in: query required: true description: ID of the first version schema: type: string pattern: "^[a-f\\d]{24}$" - name: versionB in: query required: true description: ID of the second version schema: type: string pattern: "^[a-f\\d]{24}$" responses: "200": description: Diff returned successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/AgentVersionDiff" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/WorkflowGraphAgentAccessForbiddenError" "404": description: Agent or version not found content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/versions/compare-metrics: get: summary: Compare metrics between two versions x-fern-sdk-group-name: agent_versioning_versions x-fern-sdk-method-name: compare_version_metrics description: Compare analytics/call metrics between two published versions over an optional date range. tags: - Agent Versioning - Versions security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - name: versionA in: query required: true description: ID of the first version schema: type: string pattern: "^[a-f\\d]{24}$" - name: versionB in: query required: true description: ID of the second version schema: type: string pattern: "^[a-f\\d]{24}$" - name: dateFrom in: query required: false description: Start date for the comparison range in YYYY-MM-DD format. schema: type: string format: date example: "2026-05-01" - name: dateTo in: query required: false description: End date for the comparison range in YYYY-MM-DD format. schema: type: string format: date example: "2026-05-31" responses: "200": description: Metrics comparison returned content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/AgentVersionMetricsComparison" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/WorkflowGraphAgentAccessForbiddenError" "404": description: Agent or version not found content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/versions/{versionId}: get: summary: Get version detail description: | Returns the full detail of a specific published version (read-only). Published versions are config-immutable — to modify config, create a draft from this version and publish it as a new version. tags: - Agent Versioning - Versions security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - $ref: "#/components/parameters/VersionId" responses: "200": description: Successful response content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: version: $ref: "#/components/schemas/AgentVersion" resolvedConfig: type: object description: Resolved agent configuration keyed by config section. additionalProperties: true "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/WorkflowGraphAgentAccessForbiddenError" "404": description: Agent or version not found content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" patch: summary: Update version metadata (label, description, pin only) x-fern-sdk-group-name: agent_versioning_versions x-fern-sdk-method-name: update_version_metadata description: | Update a published version's label, description, or pinned status. At least one field is required. Published versions (both active and inactive) are config-immutable — their agent configuration cannot be changed. To modify config, create a new draft from the version, edit the draft, and publish it as a new version. tags: - Agent Versioning - Versions security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - $ref: "#/components/parameters/VersionId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateVersionMetaRequest" responses: "200": description: Version metadata updated content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/AgentVersion" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/WorkflowGraphAgentAccessForbiddenError" "404": description: Agent or version not found content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/versions/{versionId}/activate: patch: summary: Activate a version x-fern-sdk-group-name: agent_versioning_versions x-fern-sdk-method-name: activate_version description: | Set a published version as the active version for the agent. The previously active version is deactivated. This does not modify the version's config — it only changes which version serves live traffic. Activation is idempotent: if the version is already active, the endpoint returns that version without changing config. tags: - Agent Versioning - Versions security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - $ref: "#/components/parameters/VersionId" responses: "200": description: Version activated successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/AgentVersion" "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/WorkflowGraphAgentAccessForbiddenError" "404": description: Agent or version not found content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/versions/{versionId}/test-call: post: summary: Test call with version config description: | Initiate a test call using a specific published version's configuration. The response always includes `conversationId` and `callId`. For `webcall` and `chat`, it also includes `token`, `roomName`, and `host`. Those fields are omitted for `telephony`. tags: - Agent Versioning - Versions security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - $ref: "#/components/parameters/VersionId" requestBody: required: false content: application/json: schema: $ref: "#/components/schemas/TestCallRequest" responses: "200": description: Test call initiated content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object required: - conversationId - callId properties: conversationId: type: string description: Conversation ID created for the test call callId: type: string description: Call ID created for the test call token: type: string description: Returned for webcall and chat modes only roomName: type: string description: Returned for webcall and chat modes only host: type: string description: Returned for webcall and chat modes only "400": $ref: "#/components/responses/BadRequestError" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": $ref: "#/components/responses/WorkflowGraphAgentAccessForbiddenError" "404": description: Agent or version not found content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" # ── GET /agent/{id}/resolved-config — REMOVED ────────────────────────── # Unused by UI. Resolved config is served via GET /agent/{id}?draftId=X # which merges _resolvedConfig into the agent DTO. Marked for backend # removal in tasks/09-backend-misc-cleanup.md. /prompt-scoring/score: post: summary: Score a prompt description: | Scores an agent's prompt across 11 quality dimensions using Gemini-based analysis. Requires the prompt to have changed since the last scoring. **Input:** Provide exactly one of `versionId` (published agent version) or `draftId` (agent draft). Providing both or neither returns a 400. **Credit usage:** 1 credit is deducted per successful call. **Idempotency:** Re-submitting the same prompt without changes returns a 400 — retrieve the cached score via the GET agent endpoint instead. **Supported agent types:** Only `single_prompt` agents are supported. Workflow-graph agents return a 400. **Scoring model:** Two sequential Gemini calls — a Platform Analyst pass followed by a Rubric Judge pass. ### Scored Dimensions | Tier | Dimension | Notes | |------|-----------|-------| | 1 | Role & Objective | | | 1 | Personality & Voice | | | 1 | Conversation Structure | | | 1 | Tool Integration | | | 1 | Constraints & Safety | | | 2 | Conversational Naturalness | | | 2 | Failure-Mode Coverage | | | 3 | Information Integrity | Gating — if Weak/Missing, score capped at 70 | | 3 | Variable & Tool Hygiene | Gating — if Weak/Missing, score capped at 50 | | 3 | Internal Consistency | | | 3 | Density | Computed from token analysis | tags: - Prompt Scoring security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object description: Exactly one of `versionId` or `draftId` must be provided. oneOf: - required: [versionId] properties: versionId: type: string description: Published agent version ID (MongoDB ObjectId). example: "6a1589b75e048394eb37bc47" - required: [draftId] properties: draftId: type: string description: Agent draft ID (MongoDB ObjectId). example: "6a1589b75e048394eb37bc48" responses: "200": description: Prompt scored successfully content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: overall_score: type: integer description: 0–100 quality score. example: 82 overall_grade: type: string description: Human-readable grade. enum: ["Excellent", "Good", "Needs Work", "Poor"] example: "Good" band: type: string description: | Token density band based on prompt length: - `lean` — fewer than 4K tokens - `normal` — 4K–9.9K tokens - `heavy` — 10K–14.9K tokens - `overweight` — 15K or more tokens enum: ["lean", "normal", "heavy", "overweight"] example: "normal" estimated_ttft_overhead_ms: type: number description: Estimated first-token latency overhead in milliseconds introduced by the prompt length. example: 420 dimensions: type: array description: Per-dimension scoring results across 11 quality dimensions. items: type: object properties: tier: type: integer description: "Priority tier: 1 (highest), 2, or 3." enum: [1, 2, 3] example: 1 level: type: string description: Quality level for this dimension. enum: ["Strong", "Adequate", "Weak", "Missing", "Not Applicable"] example: "Strong" evidence_span: type: string description: Quote from the prompt supporting the assessment. Empty string if no relevant content was found. example: "You are a helpful support agent..." title: type: string description: Short dimension name. example: "Role & Objective" description: type: string description: Explanation of the score for this dimension. example: "Prompt clearly defines the agent's role and primary objective." example: status: true data: overall_score: 56 overall_grade: "Needs Work" band: "lean" estimated_ttft_overhead_ms: 12.9 dimensions: - tier: 1 level: "Adequate" evidence_span: "You are a friendly and helpful weather assistant. Your role is to provide accurate, real-time weather information to users." title: "Clear but basic role definition" description: "The role is clearly defined but lacks specific success criteria or scope boundaries." - tier: 1 level: "Weak" evidence_span: "Use the get_weather function to fetch real-time data" title: "Undeclared tool reference" description: "The 'get_weather' tool is referenced but not defined, and failure paths are missing." - tier: 2 level: "Missing" evidence_span: "no relevant content found" title: "No failure mode coverage" description: "The prompt contains no instructions for handling errors, tool failures, or unclear user input." "400": description: | Bad request. Possible reasons: - Neither or both of `versionId`/`draftId` provided - Organization has no credits available - Agent is a conversational/workflow-graph type (not supported) - Prompt unchanged since last scoring — retrieve the existing score via GET agent - No prompt found on the version or draft content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Prompt has not changed since last scoring — retrieve the existing score via GET agent"] "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "403": description: Not a member of the organization or insufficient role (minimum Member required). content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["You are not a member of this organization"] "404": description: Version or draft not found. content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Version not found"] "429": description: Rate limit exceeded. content: application/json: schema: type: object properties: message: type: string example: "Rate limit exceeded" rateLimit: type: object properties: routeClass: type: string example: "prompt-scoring" limit: type: integer example: 10 retryAfterSec: type: integer description: Seconds to wait before retrying. example: 60 "500": description: Gemini scoring failed after retries. content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Prompt scoring failed"] # --------------------------------------------------------------------------- # 5.1.0 additive endpoints — customer-facing, verifyToken auth # See SDK_5.1.0_COMPLETENESS_SPEC.md for the audit + backend handler refs. # --------------------------------------------------------------------------- /agent/with-ai: post: summary: Create agent with AI brief x-fern-sdk-group-name: agents x-fern-sdk-method-name: create_with_ai description: | Create a new single-prompt agent from a natural-language brief or structured question/answer pairs. Atoms generates the system prompt for you. Provide either `description` (free-form brief) or a non-empty `questions` array, but not both. The `emotiveToggle`, `voiceId`, and `voiceModel` fields must be supplied as a 3-tuple or omitted entirely. tags: - Agents security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: name: type: string minLength: 1 maxLength: 50 description: Agent name (trimmed). Auto-generated when omitted. description: type: string minLength: 1 maxLength: 15000 description: | Free-form natural-language description of what the agent should do. Atoms turns this into the system prompt. Use this OR `questions`, not both. questions: type: array minItems: 1 items: type: object required: [question, answer] properties: question: type: string minLength: 1 maxLength: 2000 answer: type: string minLength: 50 maxLength: 15000 description: | Structured question/answer pairs. Atoms uses these to compose the system prompt. Use this OR `description`, not both. type: type: string enum: [single_prompt] default: single_prompt description: Currently the only supported agent type. emotiveToggle: type: boolean description: Enable emotive synthesis. Must be paired with `voiceId` + `voiceModel`. voiceId: type: string description: Voice ID for synthesis. Must be paired with `emotiveToggle` + `voiceModel`. voiceModel: type: string enum: - waves - waves_lightning_large - waves_lightning_large_voice_clone - waves_lightning_v2 - waves_lightning_v3 - waves_lightning_v3_1 - gpt-realtime - gpt-realtime-mini - other description: Synthesizer to use. Must be paired with `emotiveToggle` + `voiceId`. knowledgeBaseId: type: string description: Optional knowledge-base ID to attach to the new agent. responses: "201": description: Agent created. `data` is the new agent's `_id` (string). content: application/json: schema: type: object properties: status: type: boolean example: true data: type: string description: Newly created agent ID. example: "60d0fe4f5311236168a109ca" "400": $ref: "#/components/responses/BadRequestErrorResponse" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/call-logs: get: summary: Get conversation logs for an agent x-fern-sdk-group-name: agents x-fern-sdk-method-name: list_call_logs description: | Returns paginated conversation logs (calls) for a specific agent in the caller's organization. Use `GET /conversation` for cross-agent log listing; use this when you already have an agent ID. tags: - Agents security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" - name: page in: query required: false schema: type: string default: "1" description: Page number (string-encoded positive integer). - name: offset in: query required: false schema: type: string default: "10" description: Page size (string-encoded positive integer). responses: "200": description: Paginated list of conversation logs for the agent. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: callLogs: type: array items: type: object properties: _id: type: string createdAt: type: string format: date-time callId: type: string callDuration: type: number recordingUrl: type: string nullable: true callStatus: type: string callType: type: string callCost: type: number nullable: true statusDetails: type: array items: type: string fromNumber: type: string nullable: true toNumber: type: string nullable: true plivoData: type: object nullable: true pagination: type: object properties: currentPage: type: integer totalPages: type: integer totalCount: type: integer offset: type: integer "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": $ref: "#/components/responses/NotFoundErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/{id}/widget-config: get: summary: Get widget configuration for an agent x-fern-sdk-group-name: agents x-fern-sdk-method-name: get_widget_config description: | Returns the embeddable web widget configuration for the agent (theme, copy, consent prompts, branding, voice/chat mode, allowlist). The response merges the stored config with `assistantId: ` injected. tags: - Agents security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" responses: "200": description: Widget configuration for the agent. content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/WidgetConfig" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": $ref: "#/components/responses/NotFoundErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" patch: summary: Update widget configuration for an agent x-fern-sdk-group-name: agents x-fern-sdk-method-name: update_widget_config description: | Merge updates into the agent's embeddable widget config. Only the fields in the request body are overwritten; everything else is preserved. Returns the full widget config after merge. tags: - Agents security: - BearerAuth: [] parameters: - $ref: "#/components/parameters/AgentId" requestBody: required: true content: application/json: schema: type: object required: [widgetConfig] properties: widgetConfig: $ref: "#/components/schemas/WidgetConfig" responses: "200": description: Merged widget configuration. content: application/json: schema: type: object properties: status: type: boolean example: true data: $ref: "#/components/schemas/WidgetConfig" "400": $ref: "#/components/responses/BadRequestErrorResponse" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": $ref: "#/components/responses/NotFoundErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /agent/prompt-config: get: summary: Get prompt-config metadata (question definitions + labels) x-fern-sdk-group-name: agents x-fern-sdk-method-name: get_prompt_config description: | Returns the canonical question definitions, option choices, and example labels used by the agent-builder UI when collecting input for `POST /agent/with-ai`. Use this to programmatically discover what questions to ask end-users when building agent-creation UIs. tags: - Agents security: - BearerAuth: [] responses: "200": description: Prompt-config catalogue. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: questions: type: array items: type: object properties: text: type: string type: type: string enum: [textarea, select, multiselect] options: type: array items: type: object properties: value: type: string label: type: string examples: type: object additionalProperties: type: string description: Map of `` → answer text. Always includes a `default` key. exampleLabels: type: array items: type: string defaultLabel: type: string "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /dnc: get: summary: List DNC entries for the organization x-fern-sdk-group-name: dnc x-fern-sdk-method-name: list description: | Lists Do-Not-Call entries for the caller's organization with pagination, search, and sort. Optionally scope to a single agent via `agentId`. Each entry records a phone number that was flagged (via call outcome or manual upload) as not-to-be-called for either the org or a specific agent. tags: - DNC security: - BearerAuth: [] parameters: - name: agentId in: query required: false schema: type: string description: | Optional 24-character hex agent ID. When present, restricts results to entries for this agent. Returns 400/404 if the ID isn't valid or doesn't belong to the caller's org. - name: search in: query required: false schema: type: string description: Free-text search across phone numbers. - name: sortField in: query required: false schema: type: string enum: [createdAt, phoneNumber] default: createdAt - name: sortOrder in: query required: false schema: type: string enum: [asc, desc] default: desc - name: page in: query required: false schema: type: string default: "1" description: Page number (string-encoded positive integer, ≥ 1). - name: offset in: query required: false schema: type: string default: "50" description: Page size (string-encoded; server clamps to 1–500). responses: "200": description: Paginated DNC entries. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: entries: type: array items: type: object properties: id: type: string agentId: type: string orgId: type: string phoneNumber: type: string source: type: string detectedInCallId: type: string nullable: true createdAt: type: string format: date-time updatedAt: type: string format: date-time pagination: type: object properties: page: type: integer offset: type: integer total: type: integer totalPages: type: integer hasMore: type: boolean "400": $ref: "#/components/responses/BadRequestErrorResponse" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": $ref: "#/components/responses/NotFoundErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /account/get-account-details: get: summary: Get authenticated user + organizations x-fern-sdk-group-name: organization x-fern-sdk-method-name: get_account_details description: | Returns the authenticated user's profile and the organizations they belong to. **Response envelope is non-standard** — this endpoint returns the account object directly (no `{status, data}` wrapper). tags: - Organization security: - BearerAuth: [] responses: "200": description: Authenticated user + organizations. Raw object, no envelope. content: application/json: schema: type: object properties: email: type: string phone: type: string nullable: true firstName: type: string lastName: type: string userId: type: string picture: type: string organizations: type: array items: type: object properties: orgId: type: string roleId: type: string name: type: string ownerEmail: type: string onPremEnabled: type: boolean hasOnboarded: type: boolean "401": description: User not authenticated. content: application/json: schema: type: object properties: message: type: string example: User not authenticated "500": description: Internal Server Error (non-standard envelope — `{message}`). content: application/json: schema: type: object properties: message: type: string example: Internal Server Error /account/update-org-name: put: summary: Update organization display name x-fern-sdk-group-name: organization x-fern-sdk-method-name: update_name description: | Update the display name of the caller's current organization. Requires admin role. **Response envelope is non-standard** — returns `{success: true, name}` instead of the usual `{status, data}` wrapper. tags: - Organization security: - BearerAuth: [] requestBody: required: true content: application/json: schema: type: object required: [name] properties: name: type: string minLength: 1 maxLength: 50 description: New organization name (trimmed). responses: "200": description: Organization renamed. content: application/json: schema: type: object properties: success: type: boolean example: true name: type: string "400": description: Validation error (missing or too-long name). content: application/json: schema: type: object properties: success: type: boolean example: false message: type: string example: Organization name is required "401": description: Unauthorized. content: application/json: schema: type: object properties: success: type: boolean example: false message: type: string example: Unauthorized "500": description: Internal Server Error. content: application/json: schema: type: object properties: success: type: boolean example: false message: type: string example: Internal server error /user/subscription: get: summary: Get caller's subscription + plan limits + feature flags x-fern-sdk-group-name: user x-fern-sdk-method-name: get_subscription description: | Returns the caller's subscription details (plan ID + plan-tier limits) and feature-flag map. Useful for client-side gating of paid features. **`limits` is omitted** for the `ENTERPRISE` plan (and for unknown plan IDs) — only `features` is returned in those cases. tags: - User security: - BearerAuth: [] responses: "200": description: Subscription details + limits + features. content: application/json: schema: type: object properties: status: type: boolean example: true data: type: object properties: planId: type: string limits: type: object description: | Per-plan caps. Omitted for ENTERPRISE. properties: agents: type: integer campaigns: type: integer numbers: type: integer dailyCalls: type: integer concurrentCalls: type: integer knowledgeBaseItemLimit: type: integer knowledgeBaseLimits: type: object features: type: object description: Feature-flag map. All keys are boolean. properties: chat: type: boolean telephony: type: boolean campaign: type: boolean webcall: type: boolean knowledge_base: type: boolean integrations: type: boolean webhooks: type: boolean telephony_inbound: type: boolean telephony_outbound: type: boolean waves_lightning: type: boolean waves_lightning_large: type: boolean waves_lightning_large_voice_clone: type: boolean openai_gpt_4o: type: boolean electron: type: boolean workflow_editor: type: boolean "400": $ref: "#/components/responses/BadRequestErrorResponse" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" /campaign/{id}/logs/export: get: summary: Export campaign call logs as a JSON file x-fern-sdk-group-name: campaigns x-fern-sdk-method-name: export_logs description: | Streams a JSON file containing every call log for a campaign. Response is a **file download** (`Content-Disposition: attachment`), not the standard `{status, data}` envelope. Body is a raw JSON array of log objects. When the relay-service is configured and reachable, each row also includes an `events` array; otherwise the field is omitted. tags: - Campaigns security: - BearerAuth: [] parameters: - name: id in: path required: true description: Campaign ID. schema: type: string responses: "200": description: | Campaign-logs JSON file. `Content-Disposition: attachment; filename=campaign-logs--.json`. headers: Content-Disposition: schema: type: string example: "attachment; filename=campaign-logs-MyCampaign-2026-06-19T11:30:00.000Z.json" content: application/json: schema: type: array items: type: object properties: _id: type: string callId: type: string status: type: string duration: type: number recordingUrl: type: string nullable: true from: type: string nullable: true to: type: string nullable: true agentId: type: string statusDetails: type: array items: type: string events: type: array description: Relay-service event stream. Omitted when relay isn't configured. items: type: object "400": $ref: "#/components/responses/BadRequestErrorResponse" "401": $ref: "#/components/responses/UnauthorizedErrorResponse" "404": $ref: "#/components/responses/NotFoundErrorResponse" "500": $ref: "#/components/responses/InternalServerErrorResponse" components: securitySchemes: BearerAuth: type: http scheme: bearer description: API key from the console ApiKey collection, sent as Bearer token. Also accepts session cookies for browser-based auth. parameters: AgentId: name: id in: path required: true description: The agent ID schema: type: string example: "60d0fe4f5311236168a109ca" DraftId: name: draftId in: path required: true description: The draft ID schema: type: string VersionId: name: versionId in: path required: true description: The published version ID schema: type: string pattern: "^[a-f\\d]{24}$" schemas: ApiResponse: type: object properties: status: type: boolean data: type: object WidgetConfig: type: object description: | Configuration for the embeddable web widget. Used by `GET /agent/{id}/widget-config` (returned with `assistantId` injected) and `PATCH /agent/{id}/widget-config` (merge-patched). Every field is optional — only the fields present in a PATCH request body are written, so partial updates are safe. properties: position: type: string enum: [bottom-right, bottom-left, top-right, top-left] size: type: string enum: [tiny, compact, full] borderRadius: type: number minimum: 0 maximum: 50 mode: type: string enum: [chat, voice] theme: type: string enum: [light, dark] baseColor: type: string accentColor: type: string agentBubbleColor: type: string textOnAccentColor: type: string secondaryTextColor: type: string primaryTextColor: type: string title: type: string startButtonText: type: string minLength: 1 endButtonText: type: string minLength: 1 ctaTitle: type: string nullable: true ctaSubtitle: type: string nullable: true ctaName: type: string nullable: true widgetName: type: string nullable: true avatarUrl: type: string nullable: true description: | Must start with the CDN distribution domain prefix configured for the organization. Submit a non-CDN URL and the server returns 400. voiceEmptyMessage: type: string nullable: true voiceActiveEmptyMessage: type: string nullable: true chatEmptyMessage: type: string nullable: true chatFirstMessage: type: string nullable: true chatPlaceholder: type: string minLength: 1 voiceShowTranscript: type: boolean consentRequired: type: boolean consentTitle: type: string minLength: 1 consentContent: type: string minLength: 1 consentStorageKey: type: string nullable: true publicKey: type: string assistantId: type: string description: Injected by `GET /agent/{id}/widget-config` (equals the agent ID). allowlist: type: array items: type: string description: List of origins (domains) authorized to embed this widget. Product: type: object description: 'A phone-number product owned by the organization — either a platform-rented number (`productType: telephony`) or a SIP-imported number (`productType: custom-telephony`).' properties: _id: type: string description: 24-char MongoDB ObjectId. Use this as `productId` when releasing, or assign to an agent via `PATCH /agent/{agentId}`. example: "6969109c84c74bed175f02a7" productType: type: string enum: [telephony, custom-telephony] description: | - `telephony` — number rented via the Atoms platform (Plivo/Twilio). - `custom-telephony` — number imported via `POST /product/import-phone-number` with the customer's own SIP trunk. example: "telephony" isActive: type: boolean description: Whether the number is currently billable / serving traffic. example: true attributes: type: object description: Provider-specific number metadata. properties: provider: type: string enum: [plivo, twilio] phoneNumber: type: string description: E.164 format including `+`. example: "+912268093636" agentId: type: string nullable: true description: 24-char MongoDB ObjectId of the agent this number is assigned to, if any. `null` when unassigned. example: "69edad34780a67ce987d3f42" createdAt: type: string format: date-time updatedAt: type: string format: date-time UnauthorizedErrorResponse: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Unauthorized: User not found"] InternalServerErrorResponse: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Internal server error"] BadRequestErrorResponse: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Invalid input"] CreateAgentFromTemplateRequest: type: object required: - agentName - templateId properties: agentName: type: string description: Name of the agent agentDescription: type: string description: Description of the agent templateId: type: string description: ID of the template to use. You can get the list of templates with their description and id from the /agent/template endpoint. CreateAgentRequest: type: object required: - name properties: name: type: string description: type: string backgroundSound: type: string enum: ["", "office", "cafe", "call_center", "static"] default: "" description: "Ambient background sound during calls. Options: '' (none), 'office', 'cafe', 'call_center', 'static'. Note: this value is currently overridden by the server default on creation; update via PATCH after creation." # visibleToEveryone: # type: boolean # default: false language: type: object description: | Language configuration for the agent. Cross-field rule: `default` must be one of the values in `supported`. Tamil (`ta`) cannot be combined with other languages in `supported`. properties: default: type: string enum: [en, hi, mr, gu, ta, es, north_indic, bn, or] description: "The default language of the agent. Note: `ta` cannot be combined with other languages in `supported`." default: en supported: type: array description: | Languages the agent understands. `default` must be one of these values. Tamil (`ta`) cannot be combined with other languages. items: type: string enum: [en, hi, mr, gu, ta, es, north_indic, bn, or] switching: type: object description: Language switching configuration for the agent. If enabled, the agent will be able to switch between languages based on the user's language. properties: isEnabled: type: boolean description: Whether to enable language switching for the agent default: false minWordsForDetection: type: number minimum: 1 maximum: 10 description: Minimum number of words required for language detection default: 2 strongSignalThreshold: type: number minimum: 0.1 maximum: 0.9 description: Threshold for strong language signal detection (0.1 to 0.9) default: 0.7 weakSignalThreshold: type: number minimum: 0.1 maximum: 0.9 description: Threshold for weak language signal detection (0.1 to 0.9) default: 0.3 minConsecutiveForWeakThresholdSwitch: type: number minimum: 1 maximum: 5 description: Minimum consecutive detections required for weak threshold language switch default: 2 synthesizer: type: object description: | Synthesizer (TTS) configuration for the agent. Models `waves`, `waves_lightning_large`, `waves_lightning_v2`, and `waves_lightning_v3_1` validate `voiceId` against the Waves API. All other models accept any voiceId. Cloned voices are regular voiceIds — use them with any compatible Waves model. properties: voiceConfig: type: object description: Voice configuration for the synthesizer. properties: model: type: string enum: - waves_lightning_v3_1 - gpt-realtime - gpt-realtime-mini - waves - waves_lightning_large - waves_lightning_v2 - waves_lightning_v3 default: waves_lightning_v3_1 description: | The TTS model to use. Use `waves_lightning_v3_1` for the recommended Waves voice path (default), or `gpt-realtime` / `gpt-realtime-mini` for OpenAI realtime models (require `workflowType: single_prompt`). The other tokens (`waves`, `waves_lightning_large`, `waves_lightning_v2`, `waves_lightning_v3`) are kept for backwards compatibility with existing agents and should not be used for new agents. voiceId: type: string default: nyah description: The voice ID to use. For cloned voices, pass the voiceId from the Waves platform with a compatible model. gender: type: string enum: - male - female default: female description: The gender of the voice. default: model: waves_lightning_large voiceId: nyah speed: type: number minimum: 0 maximum: 2 default: 1.2 consistency: type: number minimum: 0 maximum: 1 default: 0.5 similarity: type: number minimum: 0 maximum: 1 default: 0 enhancement: type: number enum: [0, 1, 2] default: 1 sampleRate: type: number enum: [8000, 16000, 24000, 44100] default: 16000 description: Output audio sample rate in Hz. globalKnowledgeBaseId: type: string description: The global knowledge base ID of the agent. You can create a global knowledge base by using the /knowledgebase endpoint and assign it to the agent. The agent will use this knowledge base for its responses. slmModel: type: string enum: - electron - electron-kogta - electron-kogta-v2 - gpt-4o - gpt-4.1 - gpt-5.2 - gpt-realtime - gpt-realtime-mini default: electron description: | The LLM model to use for the agent. Note: `gpt-5.2`, `electron-kogta`, and `electron-kogta-v2` require org-level access and return 403 if not enabled. `workflowType` must be `single_prompt` to use `gpt-realtime` or `gpt-realtime-mini`. defaultVariables: type: object description: The default variables to use for the agent. These variables will be used if no variables are provided when initiating a conversation with the agent. preCallAPI: type: object description: Configuration for an API call to be made before the call starts. The response variables can be injected into the agent's prompt. properties: isEnabled: type: boolean default: false description: Whether the pre-call API is enabled. url: type: string format: uri description: The URL of the API endpoint to call. method: type: string enum: ["GET", "POST", "PUT", "DELETE", "PATCH"] description: The HTTP method to use for the API call. headers: type: object additionalProperties: type: string description: Optional HTTP headers to include in the request. body: type: object description: Optional request body for POST/PUT/PATCH requests. timeout: type: integer minimum: 1 maximum: 30 default: 5 description: Timeout in seconds for the API call. queryParams: type: object description: Optional query parameters to include in the request URL. responseVariables: type: array description: List of variables to extract from the API response using JSON path expressions. items: type: object required: - variableName - jsonPath properties: variableName: type: string description: The name of the variable to inject into the agent prompt. jsonPath: type: string description: JSON path expression to extract the value from the API response. required: - url - method globalPrompt: type: string maxLength: 4000 description: | Set global instructions for your agent's personality, role, and behavior throughout conversations. Note: Only used for workflow_graph agents. Maximum 4000 characters. telephonyProductId: type: array items: type: string description: IDs of telephony products (phone numbers) to associate with the agent for inbound/outbound calls. workflowType: $ref: "#/components/schemas/WorkflowType" default: single_prompt description: The type of workflow to create for the agent. Defaults to `single_prompt` if not specified. Using `workflow_graph` requires conversational agent access (403 if not enabled). firstMessage: type: string maxLength: 500 description: The first message the agent sends when a conversation starts. muteUserUntilFirstBotResponse: type: boolean description: When true, the user's audio is muted until the agent has finished its first response. allowInterruptions: type: boolean description: Whether the user can interrupt the agent while it is speaking. waitForUserToSpeakFirst: type: boolean description: When true, the agent waits for the user to speak before sending the first message. interruptionBackoffTimer: type: number minimum: 0 maximum: 10 description: Seconds the agent waits after being interrupted before resuming speech. smartTurnConfig: type: object description: Smart turn-detection configuration. When enabled, the agent uses an additional model to decide whether the user has finished a turn. properties: isEnabled: type: boolean waitTimeInSecs: type: number minimum: 0 maximum: 10 description: How long to wait after the user stops speaking before responding. voiceDetectionConfig: type: object description: Voice activity detection (VAD) configuration. Controls how the agent decides when speech is present. properties: confidence: type: number minimum: 0 maximum: 1 description: Minimum VAD confidence threshold to register speech. minVolume: type: number minimum: 0 maximum: 1 description: Minimum input volume threshold to register speech. triggerTimeInSecs: type: number minimum: 0 maximum: 10 description: How long sustained speech must be detected before turning the VAD on. releaseTimeInSecs: type: number minimum: 0 maximum: 10 description: How long after silence before the VAD turns off. voiceMailDetectionConfig: type: object description: Voicemail-detection configuration. When the call hits a voicemail tone, the agent plays `endText` and ends the call. properties: enabled: type: boolean endText: type: string maxLength: 200 description: Message played before hanging up when voicemail is detected. denoisingConfig: type: object description: Background-noise denoising configuration for the agent's input audio. properties: isEnabled: type: boolean redactionConfig: type: object description: PII redaction configuration. When enabled, personally identifiable information is redacted from transcripts before storage. properties: isEnabled: type: boolean pronunciationDicts: type: array description: Pronunciation overrides — words the TTS engine should pronounce differently from its default. items: type: object required: - word - pronunciation properties: word: type: string description: The word to override. pronunciation: type: string description: How the word should be pronounced (phonetic spelling). llmIdleTimeoutConfig: type: object description: Timeout configuration for the LLM stage of a conversation. Triggers a retry or call termination when the LLM does not respond within the configured window. properties: chatTimeoutTimeInSecs: type: number minimum: 1 maximum: 300 description: LLM idle timeout for chat conversations, in seconds. webcallTimeoutTimeInSecs: type: number minimum: 1 maximum: 300 description: LLM idle timeout for web calls, in seconds. telephonyTimeoutTimeInSecs: type: number minimum: 1 maximum: 300 description: LLM idle timeout for telephony calls, in seconds. maxRetries: type: number description: Maximum number of LLM-idle retries before terminating the call. System-defined min/max. sessionTimeoutConfig: type: object description: Maximum duration of a conversation session. The call ends after this elapsed time even if active. properties: timeoutTimeInSecs: type: number maximum: 3600 default: 1800 description: Maximum session duration in seconds (max 1 hour). Defaults to 1800 (30 minutes). timezone: type: object description: Timezone applied to scheduled actions and timestamps the agent reports to the user. properties: label: type: string description: IANA timezone label (e.g. `America/New_York`). offset: type: number description: UTC offset in minutes (e.g. -300 for EST). callDispositionConfig: type: string description: Configuration string for call disposition tracking. allowInboundCall: type: boolean default: true description: Whether the agent accepts inbound calls. enableStyleGuide: type: boolean default: true description: Whether style guide enforcement is applied to agent responses. speechFormatting: type: boolean description: Whether speech formatting is applied to the agent's responses. UpdateAgentRequest: type: object description: | Agent update payload. Behavior depends on whether the agent has versioning enabled: **Versioned agents**: only the metadata fields below are accepted. Config-level fields (language, synthesizer, slmModel, etc.) return 400. **Non-versioned agents**: all configuration fields are accepted — the same full set as `POST /agent` (see `CreateAgentRequest`). properties: name: type: string description: Name of the agent. description: type: string description: Description of the agent. avatarUrl: type: string description: URL of the agent's avatar image. telephonyProductId: type: array items: type: string description: IDs of telephony products (phone numbers) to associate with the agent. allowInboundCall: type: boolean description: Whether the agent accepts inbound calls. visibleToEveryone: type: boolean description: Whether the agent is visible to all members of the organization. DraftConfigRequest: type: object description: | Config payload for editing a draft via `PATCH /agent/{id}/drafts/{draftId}/config`. All fields are optional — only the fields provided are updated. A subset of config fields from `CreateAgentRequest` is accepted, plus two versioning-era fields. **Fields NOT accepted here** (use `PATCH /agent/{id}` instead): - `name` — agent metadata, not a config field; sending it alone returns 400 "No recognized config fields" - `telephonyProductId` — agent metadata, not a config field properties: singlePromptConfig: $ref: "#/components/schemas/SinglePromptConfig" postCallAnalyticsConfig: $ref: "#/components/schemas/PostCallAnalyticsConfig" language: type: object description: Language configuration. See CreateAgentRequest for full shape. synthesizer: type: object description: Synthesizer (TTS) configuration. See CreateAgentRequest for full shape. slmModel: type: string enum: - electron - electron-kogta - electron-kogta-v2 - gpt-4o - gpt-4.1 - gpt-5.2 - gpt-realtime - gpt-realtime-mini description: LLM model for this draft transcriberType: type: string description: STT engine to use for this draft customLLMWebSocketUrl: type: string description: Custom LLM WebSocket URL (overrides slmModel) widgetConfig: type: object description: Widget configuration for chat-mode agents defaultVariables: type: object description: Default prompt variables preCallAPI: type: object description: Pre-call API configuration. See CreateAgentRequest for full shape. globalPrompt: type: string maxLength: 4000 description: Global prompt for workflow_graph agents (max 4000 characters) globalKnowledgeBaseId: type: string description: Knowledge base ID to attach to this draft firstMessage: type: string description: Opening message for this draft allowInterruptions: type: boolean waitForUserToSpeakFirst: type: boolean muteUserUntilFirstBotResponse: type: boolean interruptionBackoffTimer: type: number minimum: 0 maximum: 10 backgroundSound: type: string enum: ["", "office", "cafe", "call_center", "static"] smartTurnConfig: type: object voiceDetectionConfig: type: object voiceMailDetectionConfig: type: object denoisingConfig: type: object redactionConfig: type: object pronunciationDicts: type: array items: type: object llmIdleTimeoutConfig: type: object sessionTimeoutConfig: type: object workflowType: $ref: "#/components/schemas/WorkflowType" timezone: type: object callDispositionConfig: type: string enableStyleGuide: type: boolean speechFormatting: type: boolean AgentDTO: type: object properties: _id: type: string description: The ID of the agent name: type: string description: The name of the agent description: type: string description: The description of the agent backgroundSound: type: string enum: ["", "office", "cafe", "call_center", "static"] description: "Ambient background sound during calls. Options: '' (none), 'office', 'cafe', 'call_center', 'static'." organization: type: string description: The organization ID of the agent workflowId: type: string description: The workflow ID of the agent workflowType: $ref: "#/components/schemas/WorkflowType" default: workflow_graph description: The type of workflow used by the agent createdBy: type: string description: The user ID of the user who created the agent globalKnowledgeBaseId: type: string description: The global knowledge base ID of the agent language: type: object description: The language configuration of the agent properties: default: type: string description: The default language of the agent enum: [en, hi, mr, gu, ta, es, north_indic, bn, or] switching: type: object description: Language switching configuration for the agent properties: isEnabled: type: boolean description: Whether language switching is enabled for the agent minWordsForDetection: type: number description: Minimum number of words required for language detection strongSignalThreshold: type: number description: Threshold for strong language signal detection weakSignalThreshold: type: number description: Threshold for weak language signal detection minConsecutiveForWeakThresholdSwitch: type: number description: Minimum consecutive detections required for weak threshold language switch supported: type: array items: type: string description: The supported languages of the agent synthesizer: type: object description: The synthesizer (TTS) configuration of the agent properties: voiceConfig: type: object description: The voice configuration of the synthesizer properties: model: type: string description: | The TTS model of the synthesizer. Use `waves_lightning_v3_1` for the recommended Waves voice path (default), or `gpt-realtime` / `gpt-realtime-mini` for OpenAI realtime models. The other tokens (`waves`, `waves_lightning_large`, `waves_lightning_large_voice_clone`, `waves_lightning_v2`, `waves_lightning_v3`) are kept for backwards compatibility with existing agents and should not be used for new agents. enum: - waves_lightning_v3_1 - gpt-realtime - gpt-realtime-mini - waves - waves_lightning_large - waves_lightning_large_voice_clone - waves_lightning_v2 - waves_lightning_v3 default: waves_lightning_v3_1 voiceId: type: string description: The voice ID of the synthesizer. default: nyah gender: type: string enum: - male - female default: female speed: type: number default: 1.2 description: The speed of the synthesizer consistency: type: number default: 0.5 description: The consistency of the synthesizer similarity: type: number default: 0 description: The similarity of the synthesizer enhancement: type: number default: 1 description: The enhancement of the synthesizer sampleRate: type: number description: The audio sample rate used by the synthesizer slmModel: type: string enum: - electron - electron-kogta - electron-kogta-v2 - gpt-4o - gpt-4.1 - gpt-5.2 - gpt-realtime - gpt-realtime-mini description: The LLM model to use for the agent. LLM model will be used to generate the response and take decisions based on the user's query. defaultVariables: type: object description: The default variables to use for the agent. These variables will be used if no variables are provided when initiating a conversation with the agent. preCallAPI: type: object description: Configuration for an API call to be made before the call starts. The response variables can be injected into the agent's prompt. properties: isEnabled: type: boolean default: false description: Whether the pre-call API is enabled. url: type: string format: uri description: The URL of the API endpoint to call. method: type: string enum: ["GET", "POST", "PUT", "DELETE", "PATCH"] description: The HTTP method to use for the API call. headers: type: object additionalProperties: type: string description: Optional HTTP headers to include in the request. body: type: object description: Optional request body for POST/PUT/PATCH requests. timeout: type: integer minimum: 1 maximum: 30 default: 5 description: Timeout in seconds for the API call. queryParams: type: object description: Optional query parameters to include in the request URL. responseVariables: type: array description: List of variables to extract from the API response using JSON path expressions. items: type: object required: - variableName - jsonPath properties: variableName: type: string description: The name of the variable to inject into the agent prompt. jsonPath: type: string description: JSON path expression to extract the value from the API response. required: - url - method createdAt: type: string format: date-time description: The date and time when the agent was created updatedAt: type: string format: date-time description: The date and time when the agent was last updated avatarUrl: type: string description: URL of the agent's avatar image firstMessage: type: string description: The opening message spoken by the agent at the start of a call allowInterruptions: type: boolean description: Whether the agent can be interrupted mid-speech by the caller waitForUserToSpeakFirst: type: boolean description: When true, the agent waits for the caller to speak before responding totalCalls: type: number description: Total number of calls made with this agent transcriberType: type: string description: The speech-to-text engine used for transcription globalPrompt: type: string description: A global system prompt prepended to all agent interactions archived: type: boolean description: Whether the agent has been archived. Archived agents are excluded from default listings. archivedAt: type: string format: date-time description: The date and time when the agent was archived isLocked: type: boolean description: Whether the agent is locked and cannot be edited activeVersionId: type: string description: ID of the currently-active published version. Matches `versionId`. versionId: type: string description: Alias for `activeVersionId`. allowInboundCall: type: boolean default: true description: Whether the agent accepts inbound calls. phoneNumber: type: array items: type: string description: | Phone numbers attached to this agent (E.164 strings). Only present when the agent has been linked to one or more telephony products. visibleToEveryone: type: boolean default: false description: Whether the agent is visible to all members of the organization (vs. only the creator). speechFormatting: type: boolean description: | Apply LLM-side speech formatting (e.g. expanding "$100" to "one hundred dollars") before passing text to the synthesizer. Boolean; no default — when unset the platform applies the per-organization default. muteUserUntilFirstBotResponse: type: boolean default: false description: When true, the user microphone is muted until the agent has spoken its first response. interruptionBackoffTimer: type: number description: Seconds to wait after an interruption before the agent resumes speaking. enableStyleGuide: type: boolean default: true description: Whether to apply the platform's style-guide post-processing on agent responses. callDispositionConfig: type: string default: "" description: Free-form prompt used for call disposition classification (separate from `postCallAnalyticsConfig.dispositionMetrics`). voiceMailDetectionConfig: type: object description: Voicemail detection settings. properties: enabled: type: boolean default: false endText: type: string default: "Terminating call, you can call us back anytime. Thank you for calling." description: Text spoken before the call is terminated when voicemail is detected. smartTurnConfig: type: object description: Smart end-of-turn detection settings. properties: isEnabled: type: boolean waitTimeInSecs: type: number minimum: 0 maximum: 10 voiceDetectionConfig: type: object description: VAD (voice activity detection) tuning. properties: confidence: type: number minimum: 0 maximum: 1 minVolume: type: number minimum: 0 maximum: 1 triggerTimeInSecs: type: number minimum: 0 maximum: 10 releaseTimeInSecs: type: number minimum: 0 maximum: 10 denoisingConfig: type: object description: Audio denoising settings. properties: isEnabled: type: boolean redactionConfig: type: object description: PII/PCI redaction settings applied to transcripts. properties: isEnabled: type: boolean pronunciationDicts: type: array description: Custom pronunciation dictionary applied before synthesis. items: type: object required: [word, pronunciation] properties: word: type: string pronunciation: type: string llmIdleTimeoutConfig: type: object description: | Per-channel idle timeouts (seconds) after which the LLM is nudged when the user stops speaking. `maxRetries` bounds how many nudges before the call ends. properties: chatTimeoutTimeInSecs: type: number webcallTimeoutTimeInSecs: type: number telephonyTimeoutTimeInSecs: type: number maxRetries: type: number sessionTimeoutConfig: type: object description: Maximum session duration before the call is automatically ended. properties: timeoutTimeInSecs: type: number timezone: type: object description: Agent timezone — used for time-of-day-sensitive prompts and analytics bucketing. properties: label: type: string default: "(GMT+0:00) UTC" offset: type: number default: 0 postCallAnalyticsConfig: $ref: "#/components/schemas/PostCallAnalyticsConfig" widgetConfig: type: object description: | Chat-widget rendering configuration (theme, copy, consent prompt). Only relevant when the agent is exposed via the embeddable widget; ignored by voice-only agents. properties: position: type: string enum: [bottom-right, bottom-left, top-right, top-left] default: bottom-right size: type: string enum: [tiny, compact, full] default: full mode: type: string enum: [chat, voice] default: chat theme: type: string enum: [light, dark] default: light baseColor: type: string default: "#ffffff" accentColor: type: string default: "#2d9d9f" agentBubbleColor: type: string default: "#f3f4f6" textOnAccentColor: type: string default: "#FFFFFF" secondaryTextColor: type: string default: "#6b7280" primaryTextColor: type: string default: "#111827" startButtonText: type: string default: Start endButtonText: type: string default: End ctaName: type: string default: Talk to Atoms widgetName: type: string default: Atoms avatarUrl: type: string nullable: true chatPlaceholder: type: string default: "Type your message..." consentRequired: type: boolean default: false consentTitle: type: string default: "Privacy Agreement" consentContent: type: string description: Long-form consent body shown before the user can interact. assistantId: type: string nullable: true allowlist: type: array items: type: string description: Allowed origin hostnames for widget embedding. _resolvedConfig: type: object additionalProperties: true description: | The resolved config of the target version, merged into a flat shape. Not returned in list responses (`GET /agent`). Only populated in single-agent responses (`GET /agent/{id}`) when the agent has a published, activated version. Can contain up to ~30 fields depending on which config sections are set. properties: prompt: type: string description: Active version's single-prompt text. tools: type: array items: $ref: "#/components/schemas/Tool" description: Active version's configured tools. postCallAnalyticsConfig: $ref: "#/components/schemas/PostCallAnalyticsConfig" callDispositionConfig: type: string modelName: type: string description: LLM model name on the resolved version. transcriberType: type: string description: STT engine in use on the resolved version. defaultLanguage: type: string enum: [en, hi, mr, gu, ta, es, north_indic, bn, or] description: Default language set on the resolved version. supportedLanguages: type: array items: type: string description: Supported languages on the resolved version. languageSwitching: type: object description: Language-switching configuration on the resolved version. firstMessage: type: string description: Opening message on the resolved version. globalPrompt: type: string description: Global prompt on the resolved version (workflow_graph agents only). preCallAPI: type: object description: Pre-call API configuration on the resolved version. workflowGraph: type: object description: Full node graph for workflow_graph agents. Null for single_prompt agents. muteUserUntilFirstBotResponse: type: boolean allowInterruptions: type: boolean voiceDetectionConfig: type: object smartTurnConfig: type: object backgroundSound: type: string denoisingConfig: type: object redactionConfig: type: object llmIdleTimeoutConfig: type: object sessionTimeoutConfig: type: object _configSource: type: string enum: - active - draft - version description: | Only present when `?draftId` or `?versionId` query params are used. Indicates which config source was resolved into `_resolvedConfig`. _versionedWorkflow: type: object description: | **Deprecated — internal use only.** Legacy field present whenever `_resolvedConfig` is populated. Mirrors a subset of `_resolvedConfig` (`prompt`, `tools`, `workflowGraph`). Kept for backward compatibility with existing frontend code. Ignore in new integrations. properties: prompt: type: string tools: type: array items: $ref: "#/components/schemas/Tool" workflowGraph: type: object # ── Agent Versioning Schemas ────────────────────────────────────────── AgentVersion: type: object description: Represents either a draft revision or a published version of an agent's configuration. properties: _id: type: string description: Unique identifier agent: type: string description: The agent this version belongs to status: type: string enum: [published, draft, archived] description: Current status of the version record versionNumber: type: integer nullable: true description: Auto-incremented version number (published versions only) label: type: string nullable: true description: Human-readable label for the version maxLength: 200 description: type: string nullable: true description: Description of what changed in this version maxLength: 2000 isPinned: type: boolean default: false description: Whether the version is pinned for quick access publishedBy: type: string nullable: true description: User ID of who published this version publishedAt: type: string format: date-time nullable: true description: When this version was published activatedBy: type: string nullable: true description: User ID of who activated this version activatedAt: type: string format: date-time nullable: true description: When this version was activated draftId: type: string nullable: true description: Unique draft identifier (drafts only) draftName: type: string nullable: true description: Human-readable draft name maxLength: 100 draftRevision: type: integer nullable: true description: Revision number within the draft (drafts only) sourceVersionId: type: string nullable: true description: The published version this draft was branched from blocks: type: object description: References to the 13 config section blocks properties: workflow_prompt: type: string workflow_tools: type: string workflow_graph: type: string llm: type: string voice: type: string language: type: string call_handling: type: string detection: type: string analytics: type: string timeouts: type: string audio: type: string privacy: type: string widget: type: string workflowType: $ref: "#/components/schemas/WorkflowType" parentVersion: type: string nullable: true description: The version this was derived from isActive: type: boolean description: Whether this is the currently active version for the agent createdBy: type: string description: User ID of who created this record createdAt: type: string format: date-time updatedAt: type: string format: date-time AgentVersionDiff: type: object description: Section-by-section diff between two version or draft revision records. properties: unchangedSections: type: array description: Config sections that did not change. items: type: string diffs: type: array description: Config sections with one or more changes. items: type: object properties: section: type: string description: Config section name. changes: type: array items: type: object properties: path: type: string description: Path to the changed value within the section. oldValue: nullable: true description: Previous value. Can be any JSON value or null. oneOf: - type: string - type: number - type: boolean - type: object additionalProperties: true - type: array items: {} newValue: nullable: true description: New value. Can be any JSON value or null. oneOf: - type: string - type: number - type: boolean - type: object additionalProperties: true - type: array items: {} AgentVersionMetrics: type: object properties: orgId: type: string agentId: type: string versionId: type: string totalCalls: type: number answeredCalls: type: number avgDurationMs: type: number completionRate: type: number totalCost: type: number hangupSourceDistribution: type: object additionalProperties: type: number period: type: object description: Date range used for the metric aggregation. additionalProperties: true AgentVersionMetricsComparison: type: object properties: configDiff: $ref: "#/components/schemas/AgentVersionDiff" metrics: type: object properties: versionA: $ref: "#/components/schemas/AgentVersionMetrics" versionB: $ref: "#/components/schemas/AgentVersionMetrics" deltas: type: object properties: totalCalls: type: number answeredCalls: type: number avgDurationMs: type: number completionRate: type: number totalCost: type: number DraftEditHistoryEntry: type: object properties: revision: type: integer description: Draft revision number changedSections: type: array items: type: string description: List of config sections that changed in this revision editorName: type: string nullable: true description: Display name of the editor editorId: type: string nullable: true description: User ID of the editor timestamp: type: string format: date-time description: When the edit was made CreateDraftRequest: type: object properties: sourceVersionId: type: string pattern: "^[a-f\\d]{24}$" description: | ID of a published version to branch from. Must be a valid MongoDB ObjectId (24-char hex). Sending a non-ObjectId format returns 400. sourceDraftId: type: string description: ID of an existing draft to branch from draftName: type: string minLength: 1 maxLength: 100 description: Optional name for the draft (1–100 characters) PublishDraftRequest: type: object properties: label: type: string nullable: true maxLength: 200 description: Label for the published version description: type: string nullable: true maxLength: 2000 description: Description of the published version activate: type: boolean description: Whether to immediately activate the version after publishing default: false UpdateVersionMetaRequest: type: object description: At least one of label, description, or isPinned must be provided. properties: label: type: string nullable: true maxLength: 200 description: Version label description: type: string nullable: true maxLength: 2000 description: Version description isPinned: type: boolean description: Pin or unpin the version TestCallRequest: type: object properties: mode: type: string enum: [webcall, chat, telephony] default: webcall description: Test call mode. Defaults to `webcall` when omitted. toPhone: type: string description: | Phone number to call. Required only when `mode` is `telephony`. Omit for `webcall` and `chat`. WebhookAgent: type: object properties: _id: type: string description: The ID of the agent name: type: string description: The name of the agent description: type: string description: The description of the agent WebhookSubscriptionPopulated: type: object properties: _id: type: string description: The unique identifier for the subscription webhookId: type: string description: The ID of the webhook agentId: $ref: "#/components/schemas/WebhookAgent" nullable: true description: The populated agent details, or null if not assigned eventType: type: string enum: [pre-conversation, post-conversation, analytics-completed] description: The type of event subscribed to createdAt: type: string format: date-time description: The date and time when the subscription was created updatedAt: type: string format: date-time description: The date and time when the subscription was last updated Webhook: type: object properties: _id: type: string description: The unique identifier for the webhook url: type: string description: The webhook endpoint URL description: type: string description: The description of the webhook status: type: string enum: [enabled, disabled] description: The status of the webhook organizationId: type: string description: The organization ID createdBy: type: string description: The user ID who created the webhook subscriptions: type: array items: $ref: "#/components/schemas/WebhookSubscriptionPopulated" description: A list of subscriptions for the webhook with populated agent details. decryptedSecretKey: type: string description: The decrypted signing secret for the webhook. This is only returned when fetching a single webhook by ID. createdAt: type: string format: date-time description: The date and time when the webhook was created updatedAt: type: string format: date-time description: The date and time when the webhook was last updated WebhookSubscription: type: object properties: _id: type: string description: The unique identifier for the subscription webhookId: type: string description: The ID of the webhook agentId: type: string description: The ID of the agent eventType: type: string enum: [pre-conversation, post-conversation, analytics-completed] description: The type of event subscribed to createdAt: type: string format: date-time description: The date and time when the subscription was created updatedAt: type: string format: date-time description: The date and time when the subscription was last updated WebhookEventEnvelope: type: object description: | Common envelope shared by every webhook event Atoms delivers to your endpoint. The `metadata` field's shape varies by event type — see the per-event schemas (`WebhookEventPreConversation`, `WebhookEventPostConversation`, `WebhookEventAnalyticsCompleted`). properties: url: type: string description: The webhook URL endpoint that received the event. example: "https://example.com/webhook" description: type: string description: Human-readable label configured on the webhook (e.g. "Debt Collection Agent's Endpoint"). event: type: string description: "Event identifier in the form `{agentId}.{eventType}`." example: "69fc7dd072a0c1d28d948ace.post-conversation" id: type: string description: Unique webhook delivery ID (separate from `metadata.callId`). example: "69fd96118fd277fc807e4c23" required: - url - description - event - id WebhookEventPreConversation: type: object description: | Fired **before** the agent begins speaking. Use this to enrich CRM data, log call attempts, or gate outbound calls. Does **not** contain `callData`, `transcript`, `variables`, `analytics`, or `recordingUrl`. `callData` is on `post-conversation` and `analytics-completed`; `transcript`, `variables`, and `recordingUrl` are only on `post-conversation`; `analytics` is only on `analytics-completed`. allOf: - $ref: "#/components/schemas/WebhookEventEnvelope" - type: object required: [metadata] properties: metadata: type: object required: [agentId, eventType, conversationType, toPhone, fromPhone, callId] properties: agentId: type: string description: The Atoms agent ID that handled the call. example: "69fc7dd072a0c1d28d948ace" eventType: type: string enum: [pre-conversation] example: "pre-conversation" conversationType: type: string description: "Channel type. Known values: `telephonyOutbound`, `telephonyInbound`." example: "telephonyOutbound" toPhone: type: string description: Destination phone number in E.164 format. example: "+916296641821" fromPhone: type: string description: Originating phone number in E.164 format. example: "+918035317096" callId: type: string description: Unique call identifier. example: "CALL-1778226705739-7e4c17" WebhookEventTranscriptTurn: type: object description: One speaking turn in a `post-conversation` transcript. properties: role: type: string enum: [agent, user] description: Speaker role. content: type: string description: The spoken text for this turn. timestamp: type: string format: date-time description: ISO 8601 timestamp of when this turn began (UTC). required: [role, content, timestamp] WebhookEventCallData: type: object description: | Call-level metadata shared by `post-conversation` and `analytics-completed` events. In `analytics-completed`, the `callDirection` field may be absent. properties: fromNumber: type: string description: Originating phone number in E.164 format. example: "+918035317096" toNumber: type: string description: Destination phone number in E.164 format. example: "+916296641821" callDuration: type: number format: float description: Total call duration in **seconds** (float). example: 49.350622 callStatus: type: string enum: [completed, no_answer, failed, cancelled] description: Terminal status. callDirection: type: string enum: [telephony_outbound, telephony_inbound] description: | Call direction. Present on `post-conversation`; may be absent on `analytics-completed`. answerTime: type: string format: date-time description: ISO 8601 timestamp when the call was answered (UTC). endTime: type: string format: date-time description: ISO 8601 timestamp when the call ended (UTC). required: [fromNumber, toNumber, callDuration, callStatus, answerTime, endTime] WebhookEventPostConversation: type: object description: | Fired **after** the call ends. Contains the full transcript, call metadata, recording URL, and all agent variables that were in scope during the conversation. allOf: - $ref: "#/components/schemas/WebhookEventEnvelope" - type: object required: [metadata] properties: metadata: type: object required: [agentId, eventType, conversationType, callId, recordingUrl, callData, transcript, variables] properties: agentId: type: string example: "69fc7dd072a0c1d28d948ace" eventType: type: string enum: [post-conversation] example: "post-conversation" conversationType: type: string example: "telephonyOutbound" callId: type: string example: "CALL-1778226705739-7e4c17" recordingUrl: type: string format: uri description: URL to the composite call recording (`.wav`). callData: $ref: "#/components/schemas/WebhookEventCallData" transcript: type: array description: Ordered list of transcript turns. items: $ref: "#/components/schemas/WebhookEventTranscriptTurn" variables: type: object additionalProperties: true description: | Flat key-value map of all agent variables in scope during the call. **This object is fully dynamic.** Keys and values are entirely determined by the agent's configuration; they are not fixed by the platform. New keys can appear at any time. Store as JSON and iterate keys — do not hard-code column mappings. Common platform keys include `agent_name`, `customer_name`, `current_date`, `default_language`; domain-specific keys (e.g. `due_amount`, `bank_name`) come from your agent's prompt configuration. example: agent_name: "Nisha" customer_name: "Rahul Sharma" due_amount: "29000" WebhookEventAnalyticsMetric: type: object description: | A single disposition or success metric computed by the `analytics-completed` event. The set of metrics is configured per-agent and can vary. properties: identifier: type: string description: "Machine-readable metric name (e.g. `turn_taking_balance`, `escalation_needed`)." example: "turn_taking_balance" value: description: | The evaluated result. Type depends on `dispositionMetricType`. oneOf: - type: integer - type: string - type: boolean confidence: type: number format: float minimum: 0 maximum: 1 description: Confidence score (0–1). example: 1 reasoning: type: string description: LLM-generated explanation for the assigned value. dispositionMetricPrompt: type: string description: The prompt/question that was used to evaluate this metric. dispositionMetricType: type: string enum: [STRING, BOOLEAN, INTEGER, ENUM, DATETIME] description: Data type of `value`. required: [identifier, value, confidence, reasoning, dispositionMetricPrompt, dispositionMetricType] WebhookEventAnalyticsCompleted: type: object description: | Fired **after** Atoms finishes running the configured disposition and success metrics on the transcript. Arrives some time after `post-conversation`. allOf: - $ref: "#/components/schemas/WebhookEventEnvelope" - type: object required: [metadata] properties: metadata: type: object required: [agentId, eventType, conversationType, callId, analytics, callData] properties: agentId: type: string eventType: type: string enum: [analytics-completed] example: "analytics-completed" conversationType: type: string callId: type: string analytics: type: object required: [summary, dispositionMetrics, successMetrics] properties: summary: type: string description: LLM-generated plain-text summary of the call. dispositionMetrics: type: array items: $ref: "#/components/schemas/WebhookEventAnalyticsMetric" successMetrics: type: array description: Same schema as `dispositionMetrics`. May be empty. items: $ref: "#/components/schemas/WebhookEventAnalyticsMetric" callData: $ref: "#/components/schemas/WebhookEventCallData" KnowledgeBase: type: object properties: _id: type: string description: The unique identifier for the knowledge base name: type: string description: The name of the knowledge base description: type: string description: The description of the knowledge base organization: type: string description: The organization ID createdBy: type: string description: The user ID who created the knowledge base processingStatus: type: string enum: [pending, processing, completed, failed] description: The current processing status of the knowledge base createdAt: type: string format: date-time description: The date and time when the knowledge base was created updatedAt: type: string format: date-time description: The date and time when the knowledge base was last updated required: - _id - name - organization - createdBy KnowledgeBaseItem: type: object properties: _id: type: string description: The unique identifier for the knowledge base item itemType: type: string enum: [file, text] description: The type of the knowledge base item metadata: type: object description: Additional metadata for the item knowledgeBaseId: type: string description: The ID of the knowledge base this item belongs to processingStatus: type: string enum: [pending, processing, completed, failed] description: The processing status of the item fileName: type: string description: The name of the file (for file type items) contentType: type: string description: The MIME type of the content size: type: number description: The size of the file in bytes key: type: string description: The storage key for the file title: type: string description: The title of the item content: type: string description: The content of the item (for text type items) createdAt: type: string format: date-time description: The date and time when the item was created updatedAt: type: string format: date-time description: The date and time when the item was last updated required: - _id - itemType - knowledgeBaseId - processingStatus - createdAt - updatedAt WebhookEvent: type: object properties: _id: type: string description: The unique identifier for the event webhookId: type: string description: The ID of the webhook eventType: type: string description: The type of event payload: type: object description: The event payload status: type: string description: The status of the event createdAt: type: string format: date-time description: The date and time when the event was created WorkflowType: type: string enum: [workflow_graph, single_prompt] description: The type of workflow configuration. workflow_graph uses a node-based visual workflow, single_prompt uses a simple prompt-based configuration. WorkflowGraphData: type: object description: Workflow configuration using a node-based graph structure properties: nodes: type: array description: Array of workflow nodes items: type: object properties: id: type: string description: Unique identifier for the node type: type: string description: Type of the node (e.g., default_node, end_call, pre_call_api) position: type: object properties: x: type: number y: type: number data: type: object description: Node-specific data and configuration edges: type: array description: Array of workflow edges connecting nodes items: type: object properties: id: type: string description: Unique identifier for the edge source: type: string description: ID of the source node target: type: string description: ID of the target node type: type: string description: Type of the edge SinglePromptData: type: object description: Workflow configuration using a simple prompt-based approach properties: prompt: type: string description: The main prompt that defines the agent's behavior and responses tools: type: array description: Array of tools/functions available to the agent items: type: object description: Tool configuration object SinglePromptConfig: type: object description: Configuration for single prompt workflow type properties: prompt: type: string description: The main prompt that defines the agent's behavior and responses example: "You are a helpful AI assistant that can help users with various tasks." tools: type: array description: | Array of tools/functions available to the agent during conversations. Five tool types are supported: `end_call`, `transfer_call`, `api_call`, `extract_dynamic_variables`, and `knowledge_base_search`. Each type has its own required fields — see `Tool` schema. items: $ref: "#/components/schemas/Tool" default: [] required: [prompt] Tool: type: object description: | Tool (function) available to the agent. The `type` field determines which additional fields are required. Backend validation enforces per-type schemas. required: [type, name, description] properties: type: type: string enum: [end_call, transfer_call, api_call, extract_dynamic_variables, knowledge_base_search] description: The type of function/tool name: type: string description: Unique name for the function (no spaces) example: "end_call" description: type: string description: Description of what the function does example: "End the conversation when the user is satisfied" enabled: type: boolean default: true description: Whether the tool is enabled # ── Transfer Call specific fields ── transferNumber: type: string description: "Required for transfer_call type. Phone number to transfer the call to (E.164 format)" example: "+1234567890" transferOption: type: object description: "Required for transfer_call type. Controls cold vs warm transfer behavior." properties: type: type: string enum: [cold_transfer, warm_transfer] default: cold_transfer description: Transfer mode. `cold_transfer` hands off immediately; `warm_transfer` briefs the receiving party first. privateHandoffOption: type: object nullable: true description: Private briefing delivered to the transfer target before the caller is connected. Only used when `type = warm_transfer`. properties: type: type: string enum: [prompt, static] description: "`prompt` generates briefing from the LLM; `static` plays fixed text." prompt: type: string description: The prompt or static text for the private handoff. publicHandoffOption: type: object nullable: true description: Message played to the caller while the transfer is being set up. Only used when `type = warm_transfer`. properties: type: type: string enum: [prompt, static] prompt: type: string onHoldMusic: type: string enum: [ringtone, relaxing_sound, uplifting_beats, none] default: ringtone description: "Optional for transfer_call type. Audio played to the caller while the transfer is in progress." transferOnlyIfHuman: type: boolean default: true description: "Optional for transfer_call type. If true, the call is only transferred when a human is detected on the receiving end (voicemail/IVR skipped)." detectionTimeout: type: integer minimum: 5 maximum: 60 default: 30 description: "Optional for transfer_call type. Seconds to wait for human detection before giving up (5–60)." # ── API Call specific fields ── url: type: string format: uri description: "Required for api_call type. The URL to make the HTTP request to." example: "https://api.example.com/orders" method: type: string enum: [GET, POST, PUT, DELETE, PATCH] description: "Required for api_call type. HTTP method to use." example: "GET" timeout: type: integer minimum: 1000 maximum: 30000 default: 5000 description: "Optional for api_call type. Request timeout in milliseconds (1000–30000)." headers: type: object additionalProperties: type: string description: "Optional for api_call type. Static HTTP headers as a key/value map." example: Authorization: "Bearer TOKEN" Content-Type: "application/json" headersArray: type: array description: "Optional for api_call type. Headers as an array of key/value objects (alternative to `headers` map)." items: type: object required: [key, value] properties: key: type: string example: "Authorization" value: type: string example: "Bearer TOKEN" queryParams: type: array description: "Optional for api_call type. Query parameters to include in the request URL. Values support variable templating like `{{order_id}}`." items: type: object required: [key, value] properties: key: type: string example: "id" value: type: string example: "{{order_id}}" requestBody: type: string description: "Optional for api_call type. Raw request body as a JSON string. Supports variable templating." example: '{"customer_id": "{{customer_id}}"}' llmParameters: type: array description: "Optional for api_call type. Parameters the LLM can supply dynamically at runtime." items: type: object required: [name, description, type] properties: name: type: string description: Parameter name description: type: string description: What the parameter represents type: type: string enum: [text, number, boolean, enum] values: type: array items: type: string description: "Required when type is `enum`. Allowed values." required: type: boolean default: false responseVariables: type: array description: "Optional for api_call type. Variables to extract from the API response into the agent's variable store." items: type: object required: [variableName, jsonPath] properties: variableName: type: string description: Name to store the extracted value under example: "orderStatus" jsonPath: type: string description: JSON path to extract the value from the response example: "$.data.status" default: [] # ── Dynamic Variable Extraction specific fields ── variablesExtractionSchema: type: array description: "Required for extract_dynamic_variables type. Schema defining variables to extract from the conversation." items: type: object required: [name, description, type] properties: name: type: string description: Name of the variable to extract example: "customer_name" description: type: string description: What this variable represents example: "The customer's full name" type: type: string enum: [text, number, boolean, enum] values: type: array items: type: string description: "Required when type is `enum`. List of possible values." example: ["satisfied", "unsatisfied", "neutral"] minItems: 1 # ── Knowledge Base Search specific fields ── knowledgeBaseId: type: string description: "Required for knowledge_base_search type. ID of the knowledge base to search." example: "60d0fe4f5311236168a109ca" fillerPhrases: type: array description: "Optional for knowledge_base_search type. Phrases spoken while searching." items: type: string default: [] example: ["Let me check that for you", "One moment please"] DispositionMetric: type: object description: | A single disposition metric captured after each call. The metric prompt is evaluated against the call transcript post-call, and the result is returned in the call log under `postCallAnalytics.dispositionMetrics`. required: [identifier, dispositionMetricPrompt, dispositionMetricType] properties: identifier: type: string pattern: "^[a-z0-9_]+$" description: Stable machine identifier. Lowercase letters, digits, and underscores only. example: "call_resolved" dispositionMetricPrompt: type: string description: Natural-language question evaluated against the transcript after the call ends. example: "Was the customer issue resolved by the end of the call?" dispositionMetricType: type: string enum: [STRING, BOOLEAN, INTEGER, ENUM, DATETIME] description: Data type returned by the metric. example: "STRING" choices: type: array description: "Required when `dispositionMetricType = ENUM`. Allowed values." items: type: string example: ["resolved", "escalated", "callback_scheduled", "no_action"] PostCallAnalyticsConfig: type: object description: | Per-agent post-call analytics configuration. Evaluated after each call ends and surfaced in call logs under the `postCallAnalytics` field. properties: dispositionMetrics: type: array description: Structured metrics extracted from each completed call. items: $ref: "#/components/schemas/DispositionMetric" default: [] successMetrics: type: array deprecated: true description: | **Deprecated** — will be removed in a future version. Use `dispositionMetrics` instead. Kept here because the backend still accepts it on writes and returns it on reads. items: type: object required: [identifier, successMetricPrompt, successMetricType] properties: identifier: type: string pattern: "^[a-z0-9_]+$" successMetricPrompt: type: string successMetricType: type: string enum: [NUMERIC_SCALE, PERCENTAGE_SCALE, PASS_FAIL, DESCRIPTIVE_SCALE] default: [] summaryPrompt: type: string deprecated: true description: | **Deprecated** — no longer used in post-call analysis and will be removed in a future version. Kept here because the backend still accepts it on writes and returns it on reads. default: "" useInternalAnalyticsModel: type: boolean default: true description: Use the internal analytics model. When false, falls back to the agent's own LLM. useReasoningModel: type: boolean default: false description: Route analytics evaluation through the reasoning model for higher-quality results at a latency/cost tradeoff. ComplianceApplication: type: object description: A compliance application for a specific country, number type, and user type properties: _id: type: string description: Unique identifier example: "663f1a2b4c5d6e7f8a9b0c1d" organizationId: type: string description: The organization this application belongs to plivoComplianceId: type: string description: Plivo's compliance application identifier alias: type: string description: Auto-generated alias (orgId-countryIso-env) example: "663f1a2b-IN-production" status: type: string enum: [draft, submitted, accepted, rejected, suspended, expired] description: Current status of the compliance application example: "submitted" countryIso: type: string description: ISO 3166-1 alpha-2 country code example: "IN" numberType: type: string enum: [local, mobile, tollfree] example: "local" userType: type: string enum: [individual, business] example: "business" endUserName: type: string description: Legal business or individual name example: "Acme Corp" endUserLastName: type: string nullable: true endUserEmail: type: string nullable: true endUserCountry: type: string nullable: true example: "IN" documentFileNames: type: array items: type: string description: Names of uploaded document files example: ["certificate_of_incorporation.pdf"] rejectionReason: type: string nullable: true description: Reason for rejection, if applicable createdBy: type: string description: User ID of the person who created this application createdAt: type: string format: date-time updatedAt: type: string format: date-time ComplianceRequirement: type: object description: Compliance requirements for a country/numberType/userType combination properties: requirementId: type: string description: Plivo's requirement identifier countryIso: type: string example: "IN" numberType: type: string example: "local" userType: type: string example: "business" documentTypes: type: array description: Required document types. Empty array means no compliance is needed. items: $ref: "#/components/schemas/RequiredDocumentType" RequiredDocumentType: type: object description: A document type required for compliance properties: documentTypeId: type: string description: Identifier to use when submitting this document type example: "dt_certificate_of_incorporation" name: type: string description: Human-readable name example: "Certificate of Incorporation" description: type: string description: Description of what this document should contain example: "A government-issued certificate proving business registration" proofRequired: type: boolean description: Whether a file upload is required for this document type example: true requiredFields: type: array description: Data fields that must be provided alongside the document items: type: object properties: fieldName: type: string example: "business_name" friendlyName: type: string example: "Business Name" helpText: type: string example: "Exact name as on the certificate" fieldType: type: string example: "string" required: type: boolean example: true responses: UnauthorizedError: description: Access token is missing or invalid content: application/json: schema: $ref: "#/components/schemas/ApiResponse" BadRequestError: description: Invalid input content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" ForbiddenError: description: Forbidden access content: application/json: schema: $ref: "#/components/schemas/ApiResponse" WorkflowGraphAgentAccessForbiddenError: description: Forbidden. Returned for workflow_graph agents when the organization lacks conversational agents access. content: application/json: schema: $ref: "#/components/schemas/ApiResponse" UnauthorizedErrorResponse: description: Unauthorized access content: application/json: schema: $ref: "#/components/schemas/UnauthorizedErrorResponse" InternalServerErrorResponse: description: Internal server error content: application/json: schema: $ref: "#/components/schemas/InternalServerErrorResponse" BadRequestErrorResponse: description: Bad request — validation failed or required field missing. content: application/json: schema: $ref: "#/components/schemas/BadRequestErrorResponse" NotFoundErrorResponse: description: Resource not found — the referenced ID does not exist or does not belong to the caller's organization. content: application/json: schema: type: object properties: status: type: boolean example: false errors: type: array items: type: string example: ["Resource not found"] tags: - name: Prompt Scoring description: Score and analyse agent prompts across quality dimensions - name: Agent Templates description: Operations related to agent templates - name: Agents description: Operations related to agents # - name: Workflows # DEPRECATED — workflow agents are being sunset - name: Logs description: Operations related to conversation logs, call history, and recordings. Supports filtering by agents, campaigns, call IDs, status, duration, and more. - name: Calls description: Operations related to initiating and managing calls - name: Live Transcripts description: Real-time streaming of call transcript events via Server-Sent Events (SSE). Subscribe to an active call to receive user speech, agent speech, and lifecycle events in real time. - name: Phone Numbers description: Operations related to phone numbers - name: Compliance description: | Regulatory compliance for phone number rentals. Some countries require identity verification and document submission before numbers can be rented. Use these endpoints to check requirements, submit compliance applications, and track approval status. - name: Webhooks description: Operations related to webhooks and webhook subscriptions - name: Audience description: Operations related to audience management and CSV uploads - name: Agent Versioning - Drafts description: Operations for creating, editing, diffing, and publishing agent configuration drafts - name: Agent Versioning - Versions description: Operations for listing, comparing, activating, and testing published agent versions. Published versions (active or inactive) are config-immutable — only metadata (label, description, isPinned) can be updated. To change config, create a draft and publish a new version. - name: Post-Call Analytics description: | Configure disposition metrics that are automatically extracted from each completed call (call resolved, satisfaction score, call outcome, summary, etc.). Post-call analytics is not a standalone endpoint — it is configured through the versioning system by setting the `postCallAnalyticsConfig` field in the body of `PATCH /agent/{id}/drafts/{draftId}/config`, then publishing and activating the draft. See the [Post-Call Metrics guide](/atoms/atoms-platform/features/post-call-metrics) for the full walkthrough. servers: - url: https://api.smallest.ai/atoms/v1 description: Production server