{
	"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
			}
		}
	}
}
