{ "openapi": "3.0.3", "info": { "title": "Samora AI API", "description": "The Samora AI API lets you trigger immediate outbound calls and manage outbound campaigns through the Samora AI system. Use it to start calls with your AI agents, pass per-call context, create campaigns, add recipients, and manage campaign lifecycle from your server.\n\n**Authentication:** Every request must include your organization API key in the `X-API-Key` header. These APIs are intended for server-to-server integrations; do not expose your organization API key in browser or mobile clients.\n\n**Phone number format:** Destination numbers must be in E.164 format (e.g. `+919876543210`) and include the country code. The pattern is: `+` followed by 10-15 digits.\n\n**Call statuses:** When you fetch call details, `status` can be: `PENDING`, `TRIGGERED`, `ONGOING`, `CALL_FINISHED`, `UNANSWERED`, `REJECTED`.\n\n**Campaign statuses:** Campaign `status` can be: `DRAFT`, `SCHEDULED`, `IN_PROGRESS`, `PAUSED`, `FINISHED`, `FAILED`, `CANCELLED`.\n\n**Campaign lifecycle:** Recipients can be added only while a campaign is `DRAFT` or `PAUSED`. Campaigns can be started only from `DRAFT` or `PAUSED`, stopped only from `IN_PROGRESS`, and cancelled unless they are already `FINISHED`, `FAILED`, or `CANCELLED`.\n\n**Campaign API limits:** Request bodies are limited to 2 MiB. Campaign names can be up to 120 characters. List requests support `page_size` up to 100. Add recipients accepts up to 5000 phone numbers per request, and each recipient's `call_variables` can be up to 4 KiB.\n\n**Transcripts and recordings:** For finished calls, presigned URLs for transcript and recording are valid for 60 minutes.\n", "version": "1.0.0", "license": { "name": "Proprietary" } }, "servers": [ { "url": "https://api.samora.ai", "description": "Production server" } ], "security": [ { "ApiKeyAuth": [] } ], "paths": { "/v1/call/trigger": { "post": { "description": "Triggers an immediate outbound call using the specified AI agent. The call is queued and processed asynchronously.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TriggerCallRequest" } } } }, "responses": { "202": { "description": "Call request accepted and queued", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TriggerCallResponse" }, "examples": { "success": { "value": { "message": "Call request accepted", "status": "accepted", "call_id": "550e8400-e29b-41d4-a716-446655440000" } } } } } }, "400": { "description": "Bad request - invalid request body or phone number format", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "examples": { "invalidPhoneNumber": { "value": { "message": "Invalid phone number format. Please use E.164 format (e.g., +919876543210)" } } } } } }, "404": { "description": "Agent not found or does not belong to your company", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "examples": { "agentNotFound": { "value": { "message": "Agent not found or does not belong to your company" } } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/v1/call/{call_id}": { "get": { "description": "Retrieves detailed information about a specific call by its ID. The call must belong to an agent that belongs to your company. Transcript and recording URLs are presigned and valid for 60 minutes.", "parameters": [ { "name": "call_id", "in": "path", "required": true, "description": "The UUID of the call to retrieve. Returned as `call_id` from the Trigger call endpoint.", "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Call details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetCallDetailsResponse" }, "examples": { "finishedCall": { "value": { "message": "Call details fetched successfully", "data": { "agent_id": "123e4567-e89b-12d3-a456-426614174000", "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:35:00Z", "started_at": "2024-01-15T10:30:05Z", "ended_at": "2024-01-15T10:35:30Z", "transcript_url": "https://s3.amazonaws.com/bucket/transcript.pdf?X-Amz-Algorithm=...", "recording_url": "https://s3.amazonaws.com/bucket/recording.mp3?X-Amz-Algorithm=...", "status": "CALL_FINISHED", "call_variables": { "name": "John Doe", "email": "john.doe@example.com", "customer_id": "CUST-001" }, "call_dispositions": [ { "id": "b1h2a3r4-t5i6-7890-1234-567890abcdef", "name": "Final Outcome", "type": "mcq", "answer": "Voicemail Left", "_source": "consensus", "choices": ["Callback Scheduled", "Not Interested", "Voicemail Left", "Hung Up", "Abusive/DNC"], "question": "What was the final outcome of the call?" }, { "id": "f5n6o7t8-e9s0-1234-5678-90abcdef1234", "name": "Call Summary", "type": "subjective", "answer": "The call went to voicemail, and the assistant attempted to engage but received no response.", "_source": "primary", "question": "Briefly summarize the call." } ] } } } } } } }, "400": { "description": "Bad request - invalid call ID format", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Call not found or does not belong to your company", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "examples": { "callNotFound": { "value": { "message": "Call not found or does not belong to your company" } } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } }, "/v1/external/campaigns/{agent_id}": { "post": { "description": "Creates a draft outbound campaign for the specified agent. The agent must belong to your organization.", "parameters": [ { "$ref": "#/components/parameters/AgentId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCampaignRequest" } } } }, "responses": { "201": { "description": "Campaign created successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCampaignResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" }, "500": { "$ref": "#/components/responses/InternalServerError" } } }, "get": { "description": "Lists outbound campaigns for the specified agent.", "parameters": [ { "$ref": "#/components/parameters/AgentId" }, { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1, "minimum": 1 } }, { "name": "page_size", "in": "query", "schema": { "type": "integer", "default": 10, "minimum": 1, "maximum": 100 } }, { "name": "search", "in": "query", "description": "Search by campaign name.", "schema": { "type": "string" } }, { "name": "status", "in": "query", "description": "Filter by campaign status. Repeat the query parameter for multiple statuses.", "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CampaignStatus" } }, "style": "form", "explode": true }, { "name": "sort_by", "in": "query", "schema": { "type": "string", "default": "created_at" } }, { "name": "sort_dir", "in": "query", "schema": { "type": "string", "enum": ["asc", "desc"], "default": "desc" } } ], "responses": { "200": { "description": "Campaigns fetched successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListCampaignsResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" }, "500": { "$ref": "#/components/responses/InternalServerError" } } } }, "/v1/external/campaigns/{agent_id}/{campaign_id}": { "get": { "description": "Retrieves campaign details and aggregate call statistics.", "parameters": [ { "$ref": "#/components/parameters/AgentId" }, { "$ref": "#/components/parameters/CampaignId" } ], "responses": { "200": { "description": "Campaign fetched successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetCampaignResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" }, "500": { "$ref": "#/components/responses/InternalServerError" } } }, "put": { "description": "Updates retry settings for a draft campaign.", "parameters": [ { "$ref": "#/components/parameters/AgentId" }, { "$ref": "#/components/parameters/CampaignId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCampaignSettingsRequest" } } } }, "responses": { "200": { "description": "Campaign settings updated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CampaignEnvelopeResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" }, "500": { "$ref": "#/components/responses/InternalServerError" } } } }, "/v1/external/campaigns/{agent_id}/{campaign_id}/scheduled-calls": { "post": { "description": "Adds recipients to a campaign by creating scheduled outbound call records. Recipients can be added only when campaign status is DRAFT or PAUSED.", "parameters": [ { "$ref": "#/components/parameters/AgentId" }, { "$ref": "#/components/parameters/CampaignId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddCampaignRecipientsRequest" }, "examples": { "recipients": { "value": { "phone_numbers": [ { "to_number": "+919876543210", "call_variables": { "name": "Aarav Sharma", "customer_id": "CUST-001", "city": "Mumbai" } }, { "to_number": "+919812345678", "call_variables": { "name": "Priya Mehta", "customer_id": "CUST-002", "city": "Delhi" } } ] } } } } } }, "responses": { "201": { "description": "Campaign calls scheduled successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddCampaignRecipientsResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" }, "500": { "$ref": "#/components/responses/InternalServerError" } } } }, "/v1/external/campaigns/{agent_id}/{campaign_id}/calls": { "get": { "description": "Lists calls/recipients created for a campaign. Use this lightweight response to track call statuses. Use Get call details for the full call record.", "parameters": [ { "$ref": "#/components/parameters/AgentId" }, { "$ref": "#/components/parameters/CampaignId" }, { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1, "minimum": 1 } }, { "name": "page_size", "in": "query", "schema": { "type": "integer", "default": 10, "minimum": 1, "maximum": 100 } }, { "name": "search", "in": "query", "description": "Search by recipient phone number.", "schema": { "type": "string" } }, { "name": "status", "in": "query", "description": "Filter by call status.", "schema": { "type": "string" } }, { "name": "duration_min", "in": "query", "description": "Minimum call duration in seconds.", "schema": { "type": "integer", "minimum": 0 } }, { "name": "duration_max", "in": "query", "description": "Maximum call duration in seconds.", "schema": { "type": "integer", "minimum": 0 } }, { "name": "sort_by", "in": "query", "schema": { "type": "string", "enum": ["participant_id", "status", "created_at", "updated_at", "started_at", "ended_at", "duration"], "default": "created_at" } }, { "name": "sort_dir", "in": "query", "schema": { "type": "string", "enum": ["asc", "desc"], "default": "desc" } } ], "responses": { "200": { "description": "Campaign calls fetched successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListCampaignCallsResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" }, "500": { "$ref": "#/components/responses/InternalServerError" } } } }, "/v1/external/campaigns/{agent_id}/{campaign_id}/start": { "post": { "description": "Starts a campaign. Campaign status must be DRAFT or PAUSED.", "parameters": [ { "$ref": "#/components/parameters/AgentId" }, { "$ref": "#/components/parameters/CampaignId" } ], "responses": { "200": { "description": "Campaign started successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CampaignEnvelopeResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" }, "500": { "$ref": "#/components/responses/InternalServerError" } } } }, "/v1/external/campaigns/{agent_id}/{campaign_id}/stop": { "post": { "description": "Stops an active campaign and marks it as PAUSED. Campaign status must be IN_PROGRESS.", "parameters": [ { "$ref": "#/components/parameters/AgentId" }, { "$ref": "#/components/parameters/CampaignId" } ], "responses": { "200": { "description": "Campaign stopped successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CampaignEnvelopeResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" }, "500": { "$ref": "#/components/responses/InternalServerError" } } } }, "/v1/external/campaigns/{agent_id}/{campaign_id}/cancel": { "post": { "description": "Cancels a campaign and cancels pending outbound calls for it. Campaign status must not be FINISHED, FAILED, or CANCELLED.", "parameters": [ { "$ref": "#/components/parameters/AgentId" }, { "$ref": "#/components/parameters/CampaignId" } ], "responses": { "200": { "description": "Campaign cancelled successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CampaignEnvelopeResponse" } } } }, "400": { "$ref": "#/components/responses/BadRequest" }, "404": { "$ref": "#/components/responses/NotFound" }, "500": { "$ref": "#/components/responses/InternalServerError" } } } }, "/v2/webhooks": { "post": { "description": "Creates a new webhook to receive call event notifications.\n\nThe webhook secret is returned only once during creation and should be saved securely.\n", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWebhookRequest" }, "examples": { "basic": { "value": { "agent_id": "123e4567-e89b-12d3-a456-426614174000", "name": "CRM Integration", "url": "https://your-server.com/webhooks/samora", "events": ["CALL_FINISHED", "CALL_FAILED"] } }, "withOptions": { "value": { "agent_id": "123e4567-e89b-12d3-a456-426614174000", "name": "Full Data Webhook", "url": "https://your-server.com/webhooks/samora", "events": ["CALL_FINISHED"], "data_options": { "include_transcript": true, "include_recording_url": true }, "custom_headers": { "X-Custom-Header": "my-value" } } } } } } }, "responses": { "201": { "description": "Webhook created successfully", "content": { "application/json": { "schema": { "type": "object", "required": ["message", "data"], "properties": { "message": { "type": "string" }, "data": { "$ref": "#/components/schemas/WebhookResponse" } }, "additionalProperties": false }, "examples": { "created": { "value": { "message": "Webhook created successfully. Save the secret - it will not be shown again.", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "agent_id": "123e4567-e89b-12d3-a456-426614174000", "name": "CRM Integration", "url": "https://your-server.com/webhooks/samora", "secret": "whsec_abc123def456ghi789...", "events": ["CALL_FINISHED", "CALL_FAILED"], "data_options": { "include_transcript": false, "include_recording_url": false }, "custom_headers": {}, "is_active": true, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z" } } } } } } }, "400": { "description": "Invalid request body", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "examples": { "invalidRequest": { "value": { "message": "Invalid request body" } } } } } }, "403": { "description": "Agent does not belong to your company", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "examples": { "forbidden": { "value": { "message": "Agent does not belong to your company" } } } } } } } }, "get": { "description": "Lists all webhooks for your company. Optionally filter by agent_id.", "parameters": [ { "name": "agent_id", "in": "query", "required": false, "description": "Filter webhooks by agent ID", "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Webhooks retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "required": ["data"], "properties": { "data": { "$ref": "#/components/schemas/WebhookListResponse" } }, "additionalProperties": false }, "examples": { "success": { "value": { "data": { "webhooks": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "agent_id": "123e4567-e89b-12d3-a456-426614174000", "name": "CRM Integration", "url": "https://your-server.com/webhooks/samora", "events": ["CALL_FINISHED", "CALL_FAILED"], "data_options": { "include_transcript": true, "include_recording_url": false }, "custom_headers": {}, "is_active": true, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z" } ], "total_count": 1 } } } } } } } } } }, "/v2/webhooks/events": { "get": { "description": "Returns the catalog of available webhook event types and their descriptions.", "responses": { "200": { "description": "Events catalog retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "required": ["data"], "properties": { "data": { "$ref": "#/components/schemas/EventsCatalogResponse" } }, "additionalProperties": false }, "examples": { "success": { "value": { "data": { "events": [ { "event_type": "CALL_STARTED", "display_name": "Call Started", "description": "Triggered when a call begins (inbound or outbound). Basic call info available.", "available_data_options": [] }, { "event_type": "CALL_FINISHED", "display_name": "Call Finished", "description": "Triggered when a call ends with transcript and recording available.", "available_data_options": [ "include_transcript", "include_recording_url" ] }, { "event_type": "CALL_FAILED", "display_name": "Call Failed", "description": "Triggered when a call fails, is rejected, or goes unanswered.", "available_data_options": [] } ] } } } } } } } } } }, "/v2/webhooks/{webhook_id}": { "get": { "description": "Retrieves details of a specific webhook by ID.", "parameters": [ { "name": "webhook_id", "in": "path", "required": true, "description": "The UUID of the webhook", "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Webhook retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "required": ["data"], "properties": { "data": { "$ref": "#/components/schemas/WebhookResponse" } }, "additionalProperties": false } } } }, "403": { "description": "Webhook does not belong to your company", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "examples": { "forbidden": { "value": { "message": "Webhook does not belong to your company" } } } } } }, "404": { "description": "Webhook not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "examples": { "notFound": { "value": { "message": "Webhook not found" } } } } } } } }, "put": { "description": "Updates an existing webhook configuration. All fields are optional.", "parameters": [ { "name": "webhook_id", "in": "path", "required": true, "description": "The UUID of the webhook to update", "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateWebhookRequest" }, "examples": { "updateUrl": { "value": { "url": "https://new-server.com/webhooks/samora" } }, "disableWebhook": { "value": { "is_active": false } }, "updateEvents": { "value": { "events": ["CALL_FINISHED"], "data_options": { "include_transcript": true, "include_recording_url": true } } } } } } }, "responses": { "200": { "description": "Webhook updated successfully", "content": { "application/json": { "schema": { "type": "object", "required": ["message", "data"], "properties": { "message": { "type": "string" }, "data": { "$ref": "#/components/schemas/WebhookResponse" } }, "additionalProperties": false } } } }, "400": { "description": "Invalid request body", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Webhook not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } }, "delete": { "description": "Deletes a webhook. This action cannot be undone.", "parameters": [ { "name": "webhook_id", "in": "path", "required": true, "description": "The UUID of the webhook to delete", "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Webhook deleted successfully", "content": { "application/json": { "schema": { "type": "object", "required": ["message"], "properties": { "message": { "type": "string" } }, "additionalProperties": false }, "examples": { "deleted": { "value": { "message": "Webhook deleted successfully" } } } } } }, "404": { "description": "Webhook not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } } }, "components": { "securitySchemes": { "ApiKeyAuth": { "type": "apiKey", "in": "header", "name": "X-API-Key", "description": "Your unique organization API key. Required on all requests." } }, "parameters": { "AgentId": { "name": "agent_id", "in": "path", "required": true, "description": "The UUID of the AI agent that owns the campaign.", "schema": { "type": "string", "format": "uuid" } }, "CampaignId": { "name": "campaign_id", "in": "path", "required": true, "description": "The UUID of the campaign.", "schema": { "type": "string", "format": "uuid" } } }, "responses": { "BadRequest": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "NotFound": { "description": "Resource not found or does not belong to your organization", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "InternalServerError": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "schemas": { "TriggerCallRequest": { "type": "object", "required": ["agent_id", "to_number"], "properties": { "agent_id": { "type": "string", "format": "uuid", "description": "The UUID of the AI agent to conduct the call." }, "to_number": { "type": "string", "description": "The destination phone number in E.164 format (e.g. +919876543210). Must include country code. Pattern: + followed by 10-15 digits.", "pattern": "^\\+[0-9]{10,15}$" }, "metadata": { "type": "object", "additionalProperties": true, "description": "Optional. Additional metadata to pass context to the agent (e.g. customer information, call objectives). Arbitrary key-value pairs." } }, "additionalProperties": false }, "TriggerCallResponse": { "type": "object", "required": ["message", "status", "call_id"], "properties": { "message": { "type": "string", "description": "Human-readable status message." }, "status": { "type": "string", "description": "Status value, e.g. accepted.", "example": "accepted" }, "call_id": { "type": "string", "format": "uuid", "description": "The unique identifier for the call (UUID). Use this to fetch call details later." } }, "additionalProperties": false }, "GetCallDetailsResponse": { "type": "object", "required": ["message", "data"], "properties": { "message": { "type": "string", "description": "Human-readable status message." }, "data": { "$ref": "#/components/schemas/CallDetails" } }, "additionalProperties": false }, "CallDetails": { "type": "object", "required": ["agent_id", "created_at", "updated_at", "status"], "properties": { "agent_id": { "type": "string", "format": "uuid", "description": "The UUID of the AI agent that conducted the call." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the call record was created (ISO 8601)." }, "updated_at": { "type": "string", "format": "date-time", "description": "Timestamp when the call record was last updated (ISO 8601)." }, "started_at": { "type": "string", "nullable": true, "format": "date-time", "description": "Timestamp when the call started (ISO 8601). Null if not yet started." }, "ended_at": { "type": "string", "nullable": true, "format": "date-time", "description": "Timestamp when the call ended (ISO 8601). Null if not yet ended." }, "transcript_url": { "type": "string", "nullable": true, "format": "uri", "description": "Presigned URL to access the call transcript (valid for 60 minutes). Null if not available." }, "recording_url": { "type": "string", "nullable": true, "format": "uri", "description": "Presigned URL to access the call recording (valid for 60 minutes). Null if not available." }, "status": { "type": "string", "enum": [ "PENDING", "TRIGGERED", "ONGOING", "CALL_FINISHED", "UNANSWERED", "REJECTED" ], "description": "Current status of the call." }, "call_variables": { "type": "object", "nullable": true, "additionalProperties": true, "description": "Additional variables associated with the call (e.g. metadata passed at trigger time). Null if none." }, "call_dispositions": { "type": "array", "nullable": true, "description": "Call disposition evaluation answers generated for the call when available.", "items": { "$ref": "#/components/schemas/OutcomeEvaluationItem" } } }, "additionalProperties": false }, "OutcomeEvaluationItem": { "type": "object", "required": ["id", "name", "type", "answer", "_source", "question"], "properties": { "id": { "type": "string", "description": "Evaluation question identifier." }, "name": { "type": "string", "description": "Human-readable evaluation field name." }, "type": { "type": "string", "enum": ["mcq", "subjective"], "description": "Evaluation answer type." }, "answer": { "type": "string", "description": "Evaluation answer." }, "_source": { "type": "string", "description": "Source used to derive the answer, for example primary or consensus." }, "choices": { "type": "array", "description": "Possible options for MCQ evaluations.", "items": { "type": "string" } }, "question": { "type": "string", "description": "Evaluation question text." } }, "additionalProperties": true }, "CampaignStatus": { "type": "string", "enum": [ "DRAFT", "SCHEDULED", "IN_PROGRESS", "PAUSED", "FINISHED", "FAILED", "CANCELLED" ] }, "RetryConfig": { "type": "object", "description": "Optional retry behavior for campaign calls. Retries are attempted when a call ends with one of the statuses listed in `retry_on`.", "properties": { "max_retries": { "type": "integer", "minimum": 1, "maximum": 5, "description": "Maximum retry attempts per recipient call. Must be between 1 and 5 when retry_config is provided." }, "retry_delay_minutes": { "type": "integer", "minimum": 1, "maximum": 1440, "description": "Delay in minutes before each retry attempt. Must be between 1 and 1440." }, "retry_on": { "type": "array", "description": "Call statuses that should trigger a retry.", "minItems": 1, "maxItems": 4, "uniqueItems": true, "items": { "type": "string", "enum": ["UNANSWERED", "REJECTED", "VOICEMAIL", "FAILED"] } } }, "additionalProperties": false, "example": { "max_retries": 2, "retry_delay_minutes": 30, "retry_on": ["UNANSWERED", "REJECTED", "VOICEMAIL"] } }, "CreateCampaignRequest": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string", "maxLength": 120, "description": "Campaign name. Maximum 120 characters." }, "retry_config": { "$ref": "#/components/schemas/RetryConfig" } }, "additionalProperties": false }, "CreateCampaignResponse": { "type": "object", "required": ["message", "data"], "properties": { "message": { "type": "string" }, "data": { "type": "object", "required": ["campaign_id"], "properties": { "campaign_id": { "type": "string", "format": "uuid" } }, "additionalProperties": false } }, "additionalProperties": false }, "UpdateCampaignSettingsRequest": { "type": "object", "properties": { "retry_config": { "$ref": "#/components/schemas/RetryConfig" } }, "additionalProperties": false }, "Campaign": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "agent_id": { "type": "string", "format": "uuid" }, "agent_name": { "type": "string", "description": "Agent name, included on responses that join campaign and agent details." }, "status": { "$ref": "#/components/schemas/CampaignStatus" }, "retry_config": { "$ref": "#/components/schemas/RetryConfig" }, "call_stats": { "$ref": "#/components/schemas/CampaignCallStats" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } }, "additionalProperties": false }, "CampaignCallStats": { "type": "object", "properties": { "total": { "type": "integer" }, "finished": { "type": "integer" }, "pending": { "type": "integer" }, "unanswered": { "type": "integer" }, "failed": { "type": "integer" }, "total_duration": { "type": "string", "description": "Human-readable total call duration." } }, "additionalProperties": false }, "CampaignCall": { "type": "object", "required": ["id", "to_number", "status", "duration", "created_at", "updated_at", "started_at", "ended_at"], "properties": { "id": { "type": "string", "format": "uuid" }, "to_number": { "type": "string", "description": "Recipient phone number.", "pattern": "^\\+[0-9]{10,15}$" }, "status": { "type": "string", "description": "Current call status." }, "duration": { "type": "integer", "description": "Call duration in seconds." }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" }, "started_at": { "type": "string", "format": "date-time", "nullable": true }, "ended_at": { "type": "string", "format": "date-time", "nullable": true } }, "additionalProperties": false }, "ListCampaignCallsResponse": { "type": "object", "required": ["message", "data"], "properties": { "message": { "type": "string" }, "data": { "type": "object", "required": ["calls", "page", "page_size", "total"], "properties": { "calls": { "type": "array", "items": { "$ref": "#/components/schemas/CampaignCall" } }, "page": { "type": "integer" }, "page_size": { "type": "integer" }, "total": { "type": "integer" } }, "additionalProperties": false } }, "additionalProperties": false }, "ListCampaignsResponse": { "type": "object", "required": ["message", "data"], "properties": { "message": { "type": "string" }, "data": { "type": "object", "required": ["campaigns", "page", "page_size", "total"], "properties": { "campaigns": { "type": "array", "items": { "$ref": "#/components/schemas/Campaign" } }, "page": { "type": "integer" }, "page_size": { "type": "integer" }, "total": { "type": "integer" } }, "additionalProperties": false } }, "additionalProperties": false }, "GetCampaignResponse": { "type": "object", "required": ["message", "data"], "properties": { "message": { "type": "string" }, "data": { "type": "object", "required": ["campaign", "stats"], "properties": { "campaign": { "$ref": "#/components/schemas/Campaign" }, "stats": { "$ref": "#/components/schemas/CampaignCallStats" } }, "additionalProperties": false } }, "additionalProperties": false }, "CampaignEnvelopeResponse": { "type": "object", "required": ["message", "data"], "properties": { "message": { "type": "string" }, "data": { "$ref": "#/components/schemas/Campaign" } }, "additionalProperties": false }, "CampaignRecipient": { "type": "object", "required": ["to_number"], "properties": { "to_number": { "type": "string", "description": "Destination phone number in E.164 format.", "pattern": "^\\+[0-9]{10,15}$" }, "call_variables": { "type": "object", "description": "Variables passed to the agent for this recipient. Maximum serialized size is 4 KiB.", "additionalProperties": true } }, "additionalProperties": false }, "AddCampaignRecipientsRequest": { "type": "object", "required": ["phone_numbers"], "properties": { "phone_numbers": { "type": "array", "minItems": 1, "maxItems": 5000, "items": { "$ref": "#/components/schemas/CampaignRecipient" } } }, "additionalProperties": false }, "AddCampaignRecipientsResponse": { "type": "object", "required": ["message", "data"], "properties": { "message": { "type": "string" }, "data": { "type": "object", "required": ["scheduled_call_ids"], "properties": { "scheduled_call_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } } }, "additionalProperties": false } }, "additionalProperties": false }, "DataOptions": { "type": "object", "properties": { "include_transcript": { "type": "boolean", "default": false, "description": "Include the full call transcript in webhook payload." }, "include_recording_url": { "type": "boolean", "default": false, "description": "Include the call recording URL in webhook payload." } }, "additionalProperties": false }, "CustomHeaders": { "type": "object", "description": "Custom HTTP headers to send with webhook requests.", "additionalProperties": { "type": "string" } }, "CreateWebhookRequest": { "type": "object", "required": ["agent_id", "name", "url", "events"], "properties": { "agent_id": { "type": "string", "format": "uuid", "description": "The UUID of the agent this webhook is associated with." }, "name": { "type": "string", "minLength": 1, "maxLength": 255, "description": "A friendly name for this webhook." }, "url": { "type": "string", "format": "uri", "description": "The HTTPS URL where webhook payloads will be sent." }, "events": { "type": "array", "minItems": 1, "description": "List of event types to subscribe to.", "items": { "type": "string", "enum": ["CALL_STARTED", "CALL_FINISHED", "CALL_FAILED"] } }, "data_options": { "$ref": "#/components/schemas/DataOptions" }, "custom_headers": { "$ref": "#/components/schemas/CustomHeaders" } }, "additionalProperties": false }, "UpdateWebhookRequest": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 255, "description": "A friendly name for this webhook." }, "url": { "type": "string", "format": "uri", "description": "The HTTPS URL where webhook payloads will be sent." }, "events": { "type": "array", "minItems": 1, "description": "List of event types to subscribe to.", "items": { "type": "string", "enum": ["CALL_STARTED", "CALL_FINISHED", "CALL_FAILED"] } }, "data_options": { "$ref": "#/components/schemas/DataOptions" }, "custom_headers": { "$ref": "#/components/schemas/CustomHeaders" }, "is_active": { "type": "boolean", "description": "Enable or disable the webhook." } }, "additionalProperties": false }, "WebhookResponse": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid", "description": "Unique identifier for the webhook." }, "agent_id": { "type": "string", "format": "uuid", "description": "The agent this webhook is associated with." }, "name": { "type": "string", "description": "The webhook name." }, "url": { "type": "string", "format": "uri", "description": "The webhook URL." }, "secret": { "type": "string", "description": "The webhook signing secret. Returned only on creation." }, "events": { "type": "array", "items": { "type": "string" }, "description": "Subscribed event types." }, "data_options": { "$ref": "#/components/schemas/DataOptions" }, "custom_headers": { "$ref": "#/components/schemas/CustomHeaders" }, "is_active": { "type": "boolean", "description": "Whether the webhook is active." }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } }, "additionalProperties": false }, "WebhookListResponse": { "type": "object", "required": ["webhooks", "total_count"], "properties": { "webhooks": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookResponse" } }, "total_count": { "type": "integer" } }, "additionalProperties": false }, "EventCatalog": { "type": "object", "required": [ "event_type", "display_name", "description", "available_data_options" ], "properties": { "event_type": { "type": "string", "description": "The event type identifier." }, "display_name": { "type": "string", "description": "Human-readable name." }, "description": { "type": "string", "description": "Description of when this event fires." }, "available_data_options": { "type": "array", "items": { "type": "string" }, "description": "Data options available for this event type." } }, "additionalProperties": false }, "EventsCatalogResponse": { "type": "object", "required": ["events"], "properties": { "events": { "type": "array", "items": { "$ref": "#/components/schemas/EventCatalog" } } }, "additionalProperties": false }, "Error": { "type": "object", "required": ["message"], "properties": { "message": { "type": "string", "description": "Error message." } }, "additionalProperties": false } } } }