diff --git a/README.md b/README.md index be5f83b1..549f814a 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,17 @@ An honest comparison on the axes that matter most to teams evaluating voice AI p curl -o docker-compose.yaml https://raw.githubusercontent.com/dograh-hq/dograh/main/docker-compose.yaml && curl -o start_docker.sh https://raw.githubusercontent.com/dograh-hq/dograh/main/scripts/start_docker.sh && chmod +x start_docker.sh && ./start_docker.sh ``` +> **⚡ Prefer an AI agent to set it up for you?** +> If you use **Claude Code** or **Codex**, install the official [Dograh setup skill](https://github.com/dograh-hq/dograh-plugins) and let your agent handle installation, configuration, and troubleshooting — it detects your OS, picks the right deploy path, runs Dograh's own setup scripts, and verifies the result. +> +> ```text +> # In Claude Code +> /plugin marketplace add dograh-hq/dograh-plugins +> /plugin install dograh@dograh +> ``` +> +> Then start a new session and ask it to _"set up Dograh"_ (or run `/dograh-setup`). Codex is supported too — see the [plugin repo](https://github.com/dograh-hq/dograh-plugins#install). + > **Note** > First startup may take 2-3 minutes to download all images. Once running, open http://localhost:3010 to create your first AI voice assistant! > For common issues and solutions, see 🔧 **[Troubleshooting](docs/troubleshooting.md)**. diff --git a/README.zh-CN.md b/README.zh-CN.md index 3b2af0d3..a6cf3a07 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -84,6 +84,17 @@ curl -o docker-compose.yaml https://raw.githubusercontent.com/dograh-hq/dograh/main/docker-compose.yaml && REGISTRY=ghcr.io/dograh-hq ENABLE_TELEMETRY=true docker compose up --pull always ``` +> **⚡ 想让 AI 智能体帮你完成部署?** +> 如果你使用 **Claude Code** 或 **Codex**,可以安装官方的 [Dograh 部署技能(skill)](https://github.com/dograh-hq/dograh-plugins),让智能体替你完成安装、配置与排障——它会识别你的操作系统、选择合适的部署方式、运行 Dograh 自带的部署脚本并验证结果。 +> +> ```text +> # 在 Claude Code 中 +> /plugin marketplace add dograh-hq/dograh-plugins +> /plugin install dograh@dograh +> ``` +> +> 然后开启一个新会话,让它 _"set up Dograh"_(或运行 `/dograh-setup`)。Codex 同样支持——详见[插件仓库](https://github.com/dograh-hq/dograh-plugins#install)。 + > **提示** > 首次启动需要 2-3 分钟拉取所有镜像。启动完成后,打开 http://localhost:3010 即可创建你的第一个 AI 语音助手! > 常见问题及解决方案请参见 🔧 **[故障排查](docs/troubleshooting.md)**。 diff --git a/api/alembic/versions/91cc6ba3e1c7_add_key_to_user_configurations.py b/api/alembic/versions/91cc6ba3e1c7_add_key_to_user_configurations.py index b532c4f1..6bdc8b4e 100644 --- a/api/alembic/versions/91cc6ba3e1c7_add_key_to_user_configurations.py +++ b/api/alembic/versions/91cc6ba3e1c7_add_key_to_user_configurations.py @@ -5,7 +5,7 @@ organization_configurations. Existing rows (the legacy v1 AI model configuration blob) are backfilled with key MODEL_CONFIGURATION. Revision ID: 91cc6ba3e1c7 -Revises: 384be6596b36 +Revises: efe356f488f9 Create Date: 2026-06-12 21:04:25.561529 """ @@ -17,7 +17,7 @@ from alembic import op # revision identifiers, used by Alembic. revision: str = "91cc6ba3e1c7" -down_revision: Union[str, None] = "384be6596b36" +down_revision: Union[str, None] = "efe356f488f9" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None diff --git a/api/alembic/versions/efe356f488f9_add_extra_column_in_workflow_runs.py b/api/alembic/versions/efe356f488f9_add_extra_column_in_workflow_runs.py new file mode 100644 index 00000000..fd64cfdb --- /dev/null +++ b/api/alembic/versions/efe356f488f9_add_extra_column_in_workflow_runs.py @@ -0,0 +1,34 @@ +"""add extra column in workflow runs + +Revision ID: efe356f488f9 +Revises: 384be6596b36 +Create Date: 2026-06-16 12:24:30.081058 + +""" + +from typing import Sequence, Union + +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "efe356f488f9" +down_revision: Union[str, None] = "384be6596b36" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + op.add_column( + "workflow_runs", + sa.Column( + "extra", + sa.JSON(), + server_default=sa.text("'{}'::json"), + nullable=False, + ), + ) + + +def downgrade() -> None: + op.drop_column("workflow_runs", "extra") diff --git a/api/db/campaign_client.py b/api/db/campaign_client.py index 7729a2ea..2c988afd 100644 --- a/api/db/campaign_client.py +++ b/api/db/campaign_client.py @@ -10,6 +10,7 @@ from api.db.filters import apply_workflow_run_filters, get_workflow_run_order_cl from api.db.models import CampaignModel, QueuedRunModel, WorkflowRunModel from api.schemas.workflow import WorkflowRunResponseSchema from api.services.workflow.run_usage_response import format_public_cost_info +from api.utils.recording_artifacts import get_recording_storage_key class CampaignClient(BaseDBClient): @@ -45,9 +46,11 @@ class CampaignClient(BaseDBClient): source_id=source_id, created_by=user_id, organization_id=organization_id, - retry_config=retry_config - if retry_config - else CampaignModel.retry_config.default.arg, + retry_config=( + retry_config + if retry_config + else CampaignModel.retry_config.default.arg + ), orchestrator_metadata=orchestrator_metadata, telephony_configuration_id=telephony_configuration_id, ) @@ -216,6 +219,12 @@ class CampaignClient(BaseDBClient): "is_completed": run.is_completed, "recording_url": run.recording_url, "transcript_url": run.transcript_url, + "user_recording_url": get_recording_storage_key( + run.extra, "user" + ), + "bot_recording_url": get_recording_storage_key( + run.extra, "bot" + ), "cost_info": format_public_cost_info( run.cost_info, run.usage_info ), @@ -270,9 +279,11 @@ class CampaignClient(BaseDBClient): source_id=parent_campaign.source_id, created_by=parent_campaign.created_by, organization_id=parent_campaign.organization_id, - retry_config=retry_config - if retry_config - else CampaignModel.retry_config.default.arg, + retry_config=( + retry_config + if retry_config + else CampaignModel.retry_config.default.arg + ), orchestrator_metadata=child_meta, rate_limit_per_second=parent_campaign.rate_limit_per_second, total_rows=len(queued_runs_data), @@ -338,8 +349,7 @@ class CampaignClient(BaseDBClient): # Retries create new queued_runs with suffixed source_uuids linked via # parent_queued_run_id, so group by the ROOT queued_run using a # recursive walk and pick the latest workflow_run across the tree. - sql = text( - f""" + sql = text(f""" WITH RECURSIVE run_tree AS ( SELECT id AS root_id, id AS run_id FROM queued_runs @@ -366,8 +376,7 @@ class CampaignClient(BaseDBClient): JOIN latest_run_per_root lr ON lr.root_id = q0.id WHERE q0.campaign_id = :cid AND ({tag_filter}) - """ - ) + """) async with self.async_session() as session: result = await session.execute(sql, {"cid": campaign_id}) diff --git a/api/db/models.py b/api/db/models.py index 6039d142..d2cfc42f 100644 --- a/api/db/models.py +++ b/api/db/models.py @@ -544,6 +544,9 @@ class WorkflowRunModel(Base): is_completed = Column(Boolean, default=False) recording_url = Column(String, nullable=True) transcript_url = Column(String, nullable=True) + extra = Column( + JSON, nullable=False, default=dict, server_default=text("'{}'::json") + ) # Store storage backend as string enum (s3, minio) storage_backend = Column( Enum("s3", "minio", name="storage_backend"), diff --git a/api/db/organization_usage_client.py b/api/db/organization_usage_client.py index 8691dd4c..d1a52e7c 100644 --- a/api/db/organization_usage_client.py +++ b/api/db/organization_usage_client.py @@ -20,6 +20,7 @@ from api.db.models import ( ) from api.enums import OrganizationConfigurationKey, UserConfigurationKey from api.schemas.ai_model_configuration import EffectiveAIModelConfiguration +from api.utils.recording_artifacts import get_recording_storage_key class OrganizationUsageClient(BaseDBClient): @@ -226,6 +227,9 @@ class OrganizationUsageClient(BaseDBClient): "call_duration_seconds": int(round(call_duration)), "recording_url": run.recording_url, "transcript_url": run.transcript_url, + "user_recording_url": get_recording_storage_key(run.extra, "user"), + "bot_recording_url": get_recording_storage_key(run.extra, "bot"), + "extra": run.extra, "public_access_token": run.public_access_token, "phone_number": phone_number, "caller_number": caller_number, diff --git a/api/db/workflow_run_client.py b/api/db/workflow_run_client.py index 497230ad..0389a891 100644 --- a/api/db/workflow_run_client.py +++ b/api/db/workflow_run_client.py @@ -17,6 +17,7 @@ from api.db.models import ( from api.enums import CallType, StorageBackend from api.schemas.workflow import WorkflowRunResponseSchema from api.services.workflow.run_usage_response import format_public_cost_info +from api.utils.recording_artifacts import get_recording_storage_key class WorkflowRunClient(BaseDBClient): @@ -188,13 +189,19 @@ class WorkflowRunClient(BaseDBClient): "workflow_name": run.workflow.name if run.workflow else None, "user_id": run.workflow.user_id if run.workflow else None, "organization_id": organization.id if organization else None, - "organization_name": organization.provider_id - if organization - else None, + "organization_name": ( + organization.provider_id if organization else None + ), "mode": run.mode, "is_completed": run.is_completed, "recording_url": run.recording_url, "transcript_url": run.transcript_url, + "user_recording_url": get_recording_storage_key( + run.extra, "user" + ), + "bot_recording_url": get_recording_storage_key( + run.extra, "bot" + ), "usage_info": run.usage_info, "cost_info": run.cost_info, "initial_context": run.initial_context, @@ -313,6 +320,12 @@ class WorkflowRunClient(BaseDBClient): "is_completed": run.is_completed, "recording_url": run.recording_url, "transcript_url": run.transcript_url, + "user_recording_url": get_recording_storage_key( + run.extra, "user" + ), + "bot_recording_url": get_recording_storage_key( + run.extra, "bot" + ), "cost_info": format_public_cost_info( run.cost_info, run.usage_info ), @@ -340,6 +353,7 @@ class WorkflowRunClient(BaseDBClient): logs: dict | None = None, state: str | None = None, annotations: dict | None = None, + extra: dict | None = None, ) -> WorkflowRunModel: async with self.async_session() as session: # Use SELECT FOR UPDATE to lock the row during the update @@ -374,6 +388,8 @@ class WorkflowRunClient(BaseDBClient): run.logs = {**run.logs, **logs} if annotations: run.annotations = {**run.annotations, **annotations} + if extra: + run.extra = {**run.extra, **extra} if is_completed: run.is_completed = is_completed if state: diff --git a/api/routes/organization.py b/api/routes/organization.py index 8f8e4cbe..f64d3cfd 100644 --- a/api/routes/organization.py +++ b/api/routes/organization.py @@ -56,6 +56,7 @@ from api.services.configuration.masking import is_mask_of, mask_key, mask_user_c from api.services.configuration.registry import ( DOGRAH_STT_LANGUAGES, REGISTRY, + DograhTTSService, ServiceProviders, ServiceType, ) @@ -210,6 +211,13 @@ async def get_telephony_config_warnings(user: UserModel = Depends(get_user)): # --------------------------------------------------------------------------- +def _dograh_allows_custom_voice() -> bool: + extra = DograhTTSService.model_fields["voice"].json_schema_extra + if isinstance(extra, dict): + return bool(extra.get("allow_custom_input", False)) + return False + + def _byok_provider_schemas(service_type: ServiceType) -> dict[str, dict]: return { provider: model_cls.model_json_schema() @@ -251,6 +259,7 @@ async def get_model_configuration_v2_defaults( return { "dograh": { "voices": [DOGRAH_DEFAULT_VOICE], + "allow_custom_input": _dograh_allows_custom_voice(), "speeds": list(DOGRAH_SPEED_OPTIONS), "languages": DOGRAH_STT_LANGUAGES, "defaults": { diff --git a/api/routes/organization_usage.py b/api/routes/organization_usage.py index 3912745b..2575a7b0 100644 --- a/api/routes/organization_usage.py +++ b/api/routes/organization_usage.py @@ -14,6 +14,7 @@ from api.services.auth.depends import get_user, get_user_with_selected_organizat from api.services.mps_service_key_client import mps_service_key_client from api.services.reports import generate_usage_runs_report_csv from api.utils.artifacts import artifact_url +from api.utils.recording_artifacts import has_recording_track router = APIRouter(prefix="/organizations") @@ -99,8 +100,12 @@ class WorkflowRunUsageResponse(BaseModel): call_duration_seconds: int recording_url: Optional[str] = None transcript_url: Optional[str] = None + user_recording_url: Optional[str] = None + bot_recording_url: Optional[str] = None recording_public_url: Optional[str] = None transcript_public_url: Optional[str] = None + user_recording_public_url: Optional[str] = None + bot_recording_public_url: Optional[str] = None public_access_token: Optional[str] = None phone_number: Optional[str] = Field( default=None, @@ -308,14 +313,18 @@ async def get_billing_credits( aggregation_key=entry.get("aggregation_key"), usage_event_id=_optional_int(entry.get("usage_event_id")), workflow_run_id=_optional_int(entry.get("workflow_run_id")), - workflow_id=workflow_ids_by_run_id.get( - _optional_int(entry.get("workflow_run_id")) - ) - if entry.get("workflow_run_id") is not None - else None, - billable_quantity=float(entry["billable_quantity"]) - if entry.get("billable_quantity") is not None - else None, + workflow_id=( + workflow_ids_by_run_id.get( + _optional_int(entry.get("workflow_run_id")) + ) + if entry.get("workflow_run_id") is not None + else None + ), + billable_quantity=( + float(entry["billable_quantity"]) + if entry.get("billable_quantity") is not None + else None + ), quantity_unit=entry.get("quantity_unit"), metadata=entry.get("metadata") or {}, created_at=str(entry["created_at"]), @@ -478,6 +487,17 @@ async def get_usage_history( public_access_token, "transcript" ) run["recording_public_url"] = artifact_url(public_access_token, "recording") + run["user_recording_public_url"] = ( + artifact_url(public_access_token, "user_recording") + if has_recording_track(run.get("extra"), "user") + else None + ) + run["bot_recording_public_url"] = ( + artifact_url(public_access_token, "bot_recording") + if has_recording_track(run.get("extra"), "bot") + else None + ) + run.pop("extra", None) return { "runs": runs, diff --git a/api/routes/public_download.py b/api/routes/public_download.py index c84cc244..c2d70455 100644 --- a/api/routes/public_download.py +++ b/api/routes/public_download.py @@ -6,14 +6,16 @@ post-call processing for runs that execute integrations, QA, or campaign reporting. """ -from typing import Literal - from fastapi import APIRouter, HTTPException, Query from fastapi.responses import RedirectResponse from loguru import logger from api.db import db_client from api.services.storage import get_storage_for_backend +from api.utils.recording_artifacts import ( + get_recording_storage_backend, + get_recording_storage_key, +) router = APIRouter(prefix="/public/download") @@ -21,7 +23,7 @@ router = APIRouter(prefix="/public/download") @router.get("/workflow/{token}/{artifact_type}") async def download_workflow_artifact( token: str, - artifact_type: Literal["recording", "transcript"], + artifact_type: str, inline: bool = Query( default=False, description="Display inline in browser instead of download" ), @@ -36,13 +38,15 @@ async def download_workflow_artifact( Args: token: The public access token (UUID format) - artifact_type: Type of artifact - "recording" or "transcript" + artifact_type: Type of artifact - "recording", "transcript", + "user_recording", or "bot_recording" inline: If true, sets Content-Disposition to inline for browser preview Returns: RedirectResponse to the signed URL (302 redirect) Raises: + HTTPException 400: If artifact type is unsupported HTTPException 404: If token is invalid or artifact not found """ # 1. Lookup workflow run by token @@ -52,10 +56,26 @@ async def download_workflow_artifact( raise HTTPException(status_code=404, detail="Invalid or expired token") # 2. Get file path based on artifact type + artifact_storage_backend = None if artifact_type == "recording": file_path = workflow_run.recording_url - else: # transcript + elif artifact_type == "transcript": file_path = workflow_run.transcript_url + elif artifact_type == "user_recording": + file_path = get_recording_storage_key(workflow_run.extra, "user") + artifact_storage_backend = get_recording_storage_backend( + workflow_run.extra, "user" + ) + elif artifact_type == "bot_recording": + file_path = get_recording_storage_key(workflow_run.extra, "bot") + artifact_storage_backend = get_recording_storage_backend( + workflow_run.extra, "bot" + ) + else: + logger.warning( + f"Unsupported artifact type: type={artifact_type}, workflow_run_id={workflow_run.id}" + ) + raise HTTPException(status_code=400, detail="Unsupported artifact type") if not file_path: logger.warning( @@ -68,7 +88,9 @@ async def download_workflow_artifact( # 3. Get storage backend for this workflow run try: - storage = get_storage_for_backend(workflow_run.storage_backend) + storage = get_storage_for_backend( + artifact_storage_backend or workflow_run.storage_backend + ) except ValueError as e: logger.error(f"Invalid storage backend: {workflow_run.storage_backend}") raise HTTPException(status_code=500, detail="Storage configuration error") diff --git a/api/routes/s3_signed_url.py b/api/routes/s3_signed_url.py index f0008ae4..b749f98c 100644 --- a/api/routes/s3_signed_url.py +++ b/api/routes/s3_signed_url.py @@ -40,14 +40,22 @@ class PresignedUploadUrlResponse(BaseModel): router = APIRouter(prefix="/s3", tags=["s3"]) +ORG_SCOPED_STORAGE_PREFIXES = ("campaigns", "knowledge_base") + + def _extract_org_id_from_key(key: str) -> Optional[int]: """Try to extract an organization ID from a storage key. - Matches keys of the form ``{prefix}/{org_id}/...`` where *org_id* is a - positive integer. Returns ``None`` when the pattern does not match. + Matches known org-scoped keys of the form ``{prefix}/{org_id}/...`` where + *org_id* is a positive integer. Returns ``None`` when the pattern does not + match. """ parts = key.split("/") - if len(parts) >= 3 and parts[1].isdigit(): + if ( + len(parts) >= 3 + and parts[0] in ORG_SCOPED_STORAGE_PREFIXES + and parts[1].isdigit() + ): return int(parts[1]) return None @@ -58,15 +66,20 @@ def _extract_legacy_workflow_run_id(key: str) -> Optional[int]: Supports: - ``transcripts/{run_id}.txt`` - ``recordings/{run_id}.wav`` + - ``recordings/{run_id}/user.wav`` + - ``recordings/{run_id}/bot.wav`` Returns ``None`` when the key does not match a legacy pattern. """ if key.startswith("transcripts/") and key.endswith(".txt"): run_id_str = key[len("transcripts/") : -4] - elif key.startswith("recordings/") and key.endswith(".wav"): - run_id_str = key[len("recordings/") : -4] else: - return None + recording_match = re.fullmatch( + r"recordings/(\d+)(?:\.wav|/(?:user|bot)\.wav)", key + ) + if not recording_match: + return None + run_id_str = recording_match.group(1) return int(run_id_str) if run_id_str.isdigit() else None @@ -89,8 +102,13 @@ async def _validate_and_extract_workflow_run_id( """ if key.startswith("transcripts/") and key.endswith(".txt"): run_id_str = key[len("transcripts/") : -4] # strip prefix & suffix - elif key.startswith("recordings/") and key.endswith(".wav"): - run_id_str = key[len("recordings/") : -4] + elif key.startswith("recordings/"): + run_id = _extract_legacy_workflow_run_id(key) + if run_id is None: + raise HTTPException( + status_code=400, detail="Invalid workflow_run_id in key" + ) + return run_id elif allow_special_paths and key.startswith("voicemail_detections/"): return None # Skip validation for these paths else: @@ -159,9 +177,9 @@ async def get_signed_url( """Return a short-lived signed URL for a file stored on S3 / MinIO. Access Control: - * Keys that embed an organization ID (``{prefix}/{org_id}/...``) are - authorized by matching the org_id against the requesting user's - organization. + * Known org-scoped keys (for example ``campaigns/{org_id}/...`` and + ``knowledge_base/{org_id}/...``) are authorized by matching the org_id + against the requesting user's organization. * Legacy keys (``recordings/{run_id}.wav``, ``transcripts/{run_id}.txt``) are authorized via the workflow run they belong to. * Superusers can request any key. diff --git a/api/routes/webrtc_signaling.py b/api/routes/webrtc_signaling.py index ca8d3038..75ed0482 100644 --- a/api/routes/webrtc_signaling.py +++ b/api/routes/webrtc_signaling.py @@ -19,7 +19,7 @@ import ipaddress import os from datetime import UTC, datetime from enum import Enum -from typing import Dict, List, Optional +from typing import Dict, List, Optional, Set from aiortc import RTCIceServer from aiortc.sdp import candidate_from_sdp @@ -246,6 +246,74 @@ class SignalingManager: def __init__(self): self._connections: Dict[str, WebSocket] = {} self._peer_connections: Dict[str, SmallWebRTCConnection] = {} + self._connection_peer_ids: Dict[str, Set[str]] = {} + self._peer_connection_owners: Dict[str, str] = {} + + def _track_peer_connection( + self, connection_id: str, pc_id: str, pc: SmallWebRTCConnection + ) -> None: + self._peer_connections[pc_id] = pc + self._peer_connection_owners[pc_id] = connection_id + self._connection_peer_ids.setdefault(connection_id, set()).add(pc_id) + + def _forget_peer_connection(self, pc_id: str) -> Optional[str]: + connection_id = self._peer_connection_owners.pop(pc_id, None) + self._peer_connections.pop(pc_id, None) + + if connection_id: + peer_ids = self._connection_peer_ids.get(connection_id) + if peer_ids is not None: + peer_ids.discard(pc_id) + if not peer_ids: + self._connection_peer_ids.pop(connection_id, None) + + return connection_id + + async def _send_json_if_connected( + self, websocket: WebSocket, message: dict + ) -> bool: + if websocket.application_state != WebSocketState.CONNECTED: + return False + + try: + await websocket.send_json(message) + return True + except Exception as e: + logger.debug(f"Failed to send signaling WebSocket message: {e}") + return False + + async def _close_websocket_if_connected( + self, websocket: WebSocket, code: int = 1000, reason: str = "" + ) -> None: + if websocket.application_state != WebSocketState.CONNECTED: + return + + try: + await websocket.close(code=code, reason=reason) + except Exception as e: + logger.debug(f"Failed to close signaling WebSocket: {e}") + + async def _notify_call_ended_and_close_websocket( + self, + websocket: WebSocket, + workflow_run_id: int, + pc_id: str, + reason: str, + ) -> None: + await self._send_json_if_connected( + websocket, + { + "type": "call-ended", + "payload": { + "workflow_run_id": workflow_run_id, + "pc_id": pc_id, + "reason": reason, + }, + }, + ) + await self._close_websocket_if_connected( + websocket, code=1000, reason="call ended" + ) async def handle_websocket( self, @@ -257,35 +325,51 @@ class SignalingManager: """Handle WebSocket connection for signaling.""" await websocket.accept() connection_id = f"{workflow_id}:{workflow_run_id}:{user.id}" - self._connections[connection_id] = websocket + connection_key = f"{connection_id}:{id(websocket)}" + self._connections[connection_key] = websocket try: while True: message = await websocket.receive_json() await self._handle_message( - websocket, message, workflow_id, workflow_run_id, user + websocket, + message, + workflow_id, + workflow_run_id, + user, + connection_key, ) except WebSocketDisconnect: logger.info(f"WebSocket disconnected for {connection_id}") except Exception as e: - logger.error(f"WebSocket error for {connection_id}: {e}") + if websocket.application_state == WebSocketState.DISCONNECTED: + logger.info(f"WebSocket disconnected for {connection_id}") + else: + logger.error(f"WebSocket error for {connection_id}: {e}") finally: # Cleanup - self._connections.pop(connection_id, None) + self._connections.pop(connection_key, None) + peer_ids = list(self._connection_peer_ids.pop(connection_key, set())) # Unregister WebSocket sender for real-time feedback unregister_ws_sender(workflow_run_id) - # Clean up all peer connections for this workflow run + # Clean up peer connections owned by this WebSocket. # Note: In a WebSocket-based signaling approach (vs HTTP PATCH), # we maintain our own connection map instead of relying on # SmallWebRTCRequestHandler's _pcs_map. This is suitable for # multi-worker FastAPI deployments where state cannot be shared. - for pc_id in list(self._peer_connections.keys()): + for pc_id in peer_ids: + self._peer_connection_owners.pop(pc_id, None) pc = self._peer_connections.pop(pc_id, None) if pc: - await pc.disconnect() - logger.debug(f"Disconnected peer connection: {pc_id}") + try: + await pc.disconnect() + logger.debug(f"Disconnected peer connection: {pc_id}") + except Exception as e: + logger.debug( + f"Failed to disconnect peer connection {pc_id}: {e}" + ) async def _handle_message( self, @@ -294,17 +378,20 @@ class SignalingManager: workflow_id: int, workflow_run_id: int, user: UserModel, + connection_key: str, ): """Handle incoming WebSocket messages.""" msg_type = message.get("type") payload = message.get("payload", {}) if msg_type == "offer": - await self._handle_offer(ws, payload, workflow_id, workflow_run_id, user) + await self._handle_offer( + ws, payload, workflow_id, workflow_run_id, user, connection_key + ) elif msg_type == "ice-candidate": - await self._handle_ice_candidate(ws, payload, workflow_run_id) + await self._handle_ice_candidate(payload, connection_key) elif msg_type == "renegotiate": - await self._handle_renegotiation(ws, payload, workflow_id, workflow_run_id) + await self._handle_renegotiation(ws, payload, connection_key) async def _handle_offer( self, @@ -313,6 +400,7 @@ class SignalingManager: workflow_id: int, workflow_run_id: int, user: UserModel, + connection_key: str, ): """Handle offer message and create answer with ICE trickling.""" pc_id = payload.get("pc_id") @@ -320,6 +408,15 @@ class SignalingManager: type_ = payload.get("type") call_context_vars = payload.get("call_context_vars", {}) + if not pc_id or not sdp or not type_: + await ws.send_json( + { + "type": "error", + "payload": {"message": "Missing offer fields"}, + } + ) + return + # Set run context for logging and tracing. org_id must be set before # pc.initialize() so that aiortc's internal tasks inherit it. set_current_run_id(workflow_run_id) @@ -347,7 +444,16 @@ class SignalingManager: ) return - if pc_id and pc_id in self._peer_connections: + if pc_id in self._peer_connections: + if self._peer_connection_owners.get(pc_id) != connection_key: + await ws.send_json( + { + "type": "error", + "payload": {"message": "Peer connection already owned"}, + } + ) + return + # Reuse existing connection logger.info(f"Reusing existing connection for pc_id: {pc_id}") pc = self._peer_connections[pc_id] @@ -379,7 +485,7 @@ class SignalingManager: await pc.initialize(sdp=sdp, type=type_) # Store peer connection using client's pc_id - self._peer_connections[pc_id] = pc + self._track_peer_connection(connection_key, pc_id, pc) # Register WebSocket sender for real-time feedback async def ws_sender(message: dict): @@ -392,7 +498,16 @@ class SignalingManager: @pc.event_handler("closed") async def handle_disconnected(webrtc_connection: SmallWebRTCConnection): logger.info(f"PeerConnection closed: {webrtc_connection.pc_id}") - self._peer_connections.pop(webrtc_connection.pc_id, None) + owner_connection_id = self._forget_peer_connection( + webrtc_connection.pc_id + ) + if owner_connection_id == connection_key: + await self._notify_call_ended_and_close_websocket( + ws, + workflow_run_id, + webrtc_connection.pc_id, + reason="peer_connection_closed", + ) # Start pipeline in background asyncio.create_task( @@ -421,9 +536,7 @@ class SignalingManager: } ) - async def _handle_ice_candidate( - self, ws: WebSocket, payload: dict, workflow_run_id: int - ): + async def _handle_ice_candidate(self, payload: dict, connection_key: str): """Handle incoming ICE candidate from client. Uses SmallWebRTC's native ICE trickling support via add_ice_candidate(). @@ -442,6 +555,9 @@ class SignalingManager: if not pc: logger.warning(f"No peer connection found for pc_id: {pc_id}") return + if self._peer_connection_owners.get(pc_id) != connection_key: + logger.warning(f"Ignoring ICE candidate for unowned pc_id: {pc_id}") + return if candidate_data: candidate_str = candidate_data.get("candidate", "") @@ -466,7 +582,7 @@ class SignalingManager: logger.debug(f"End of ICE candidates for pc_id: {pc_id}") async def _handle_renegotiation( - self, ws: WebSocket, payload: dict, workflow_id: int, workflow_run_id: int + self, ws: WebSocket, payload: dict, connection_key: str ): """Handle renegotiation request.""" pc_id = payload.get("pc_id") @@ -479,6 +595,11 @@ class SignalingManager: {"type": "error", "payload": {"message": "Peer connection not found"}} ) return + if self._peer_connection_owners.get(pc_id) != connection_key: + await ws.send_json( + {"type": "error", "payload": {"message": "Peer connection not found"}} + ) + return pc = self._peer_connections[pc_id] await pc.renegotiate(sdp=sdp, type=type_, restart_pc=restart_pc) diff --git a/api/routes/workflow.py b/api/routes/workflow.py index 06e5fdf9..15541674 100644 --- a/api/routes/workflow.py +++ b/api/routes/workflow.py @@ -60,6 +60,10 @@ from api.services.workflow.trigger_paths import ( ) from api.services.workflow.workflow_graph import WorkflowGraph from api.utils.artifacts import artifact_url +from api.utils.recording_artifacts import ( + get_recording_storage_key, + has_recording_track, +) router = APIRouter(prefix="/workflow") @@ -1255,7 +1259,16 @@ async def get_workflow_run( raise HTTPException(status_code=404, detail="Workflow run not found") public_access_token = run.public_access_token - if (run.transcript_url or run.recording_url) and not public_access_token: + user_recording_url = get_recording_storage_key(run.extra, "user") + bot_recording_url = get_recording_storage_key(run.extra, "bot") + has_user_recording = has_recording_track(run.extra, "user") + has_bot_recording = has_recording_track(run.extra, "bot") + if ( + run.transcript_url + or run.recording_url + or has_user_recording + or has_bot_recording + ) and not public_access_token: public_access_token = await db_client.ensure_public_access_token(run.id) return { @@ -1266,8 +1279,20 @@ async def get_workflow_run( "is_completed": run.is_completed, "transcript_url": run.transcript_url, "recording_url": run.recording_url, + "user_recording_url": user_recording_url, + "bot_recording_url": bot_recording_url, "transcript_public_url": artifact_url(public_access_token, "transcript"), "recording_public_url": artifact_url(public_access_token, "recording"), + "user_recording_public_url": ( + artifact_url(public_access_token, "user_recording") + if has_user_recording + else None + ), + "bot_recording_public_url": ( + artifact_url(public_access_token, "bot_recording") + if has_bot_recording + else None + ), "public_access_token": public_access_token, "cost_info": format_public_cost_info(run.cost_info, run.usage_info), "usage_info": format_public_usage_info(run.usage_info), diff --git a/api/schemas/workflow.py b/api/schemas/workflow.py index ae0a2659..2291e11f 100644 --- a/api/schemas/workflow.py +++ b/api/schemas/workflow.py @@ -15,8 +15,12 @@ class WorkflowRunResponseSchema(BaseModel): is_completed: bool transcript_url: str | None recording_url: str | None + user_recording_url: str | None = None + bot_recording_url: str | None = None transcript_public_url: str | None = None recording_public_url: str | None = None + user_recording_public_url: str | None = None + bot_recording_public_url: str | None = None public_access_token: str | None = None cost_info: Dict[str, Any] | None usage_info: Dict[str, Any] | None = None diff --git a/api/services/configuration/check_validity.py b/api/services/configuration/check_validity.py index b1996879..7bd36752 100644 --- a/api/services/configuration/check_validity.py +++ b/api/services/configuration/check_validity.py @@ -49,6 +49,7 @@ class UserConfigurationValidator: ServiceProviders.CAMB.value: self._check_camb_api_key, ServiceProviders.AWS_BEDROCK.value: self._check_aws_bedrock_api_key, ServiceProviders.SPEACHES.value: self._check_speaches_api_key, + ServiceProviders.HUGGINGFACE.value: self._check_huggingface_api_key, ServiceProviders.GOOGLE_VERTEX.value: self._check_google_vertex_llm_api_key, ServiceProviders.OPENAI_REALTIME.value: self._check_openai_api_key, ServiceProviders.GROK_REALTIME.value: self._check_grok_realtime_api_key, @@ -60,6 +61,7 @@ class UserConfigurationValidator: ServiceProviders.GLADIA.value: self._check_gladia_api_key, ServiceProviders.RIME.value: self._check_rime_api_key, ServiceProviders.MINIMAX.value: self._check_minimax_api_key, + ServiceProviders.SMALLEST.value: self._check_smallest_api_key, } async def validate( @@ -360,6 +362,14 @@ class UserConfigurationValidator: raise ValueError("base_url is required for Speaches services") return True + def _check_huggingface_api_key(self, model: str, api_key: str) -> bool: + if not api_key.startswith("hf_"): + raise ValueError( + "Invalid Hugging Face API token format. Use a token that starts with " + "'hf_' and has Inference Providers permission." + ) + return True + def _check_google_vertex_realtime_api_key(self, model: str, service_config) -> bool: if not getattr(service_config, "project_id", None): raise ValueError("project_id is required for Google Vertex Realtime") @@ -389,6 +399,7 @@ class UserConfigurationValidator: return True def _check_minimax_api_key(self, model: str, api_key: str) -> bool: - # MiniMax doesn't publish a cheap key-validation endpoint; trust the key - # at save time and surface auth errors at first call (same as Rime/Sarvam). + return True + + def _check_smallest_api_key(self, model: str, api_key: str) -> bool: return True diff --git a/api/services/configuration/registry.py b/api/services/configuration/registry.py index a0a74546..9ac9b7d2 100644 --- a/api/services/configuration/registry.py +++ b/api/services/configuration/registry.py @@ -68,6 +68,7 @@ class ServiceProviders(str, Enum): CAMB = "camb" AWS_BEDROCK = "aws_bedrock" SPEACHES = "speaches" + HUGGINGFACE = "huggingface" ASSEMBLYAI = "assemblyai" GLADIA = "gladia" RIME = "rime" @@ -79,6 +80,7 @@ class ServiceProviders(str, Enum): GOOGLE_REALTIME = "google_realtime" GOOGLE_VERTEX_REALTIME = "google_vertex_realtime" AZURE_REALTIME = "azure_realtime" + SMALLEST = "smallest" class BaseServiceConfiguration(BaseModel): @@ -94,6 +96,7 @@ class BaseServiceConfiguration(BaseModel): ServiceProviders.DOGRAH, ServiceProviders.AWS_BEDROCK, ServiceProviders.SPEACHES, + ServiceProviders.HUGGINGFACE, ServiceProviders.ASSEMBLYAI, ServiceProviders.GLADIA, ServiceProviders.RIME, @@ -106,6 +109,7 @@ class BaseServiceConfiguration(BaseModel): ServiceProviders.GOOGLE_VERTEX_REALTIME, ServiceProviders.AZURE_REALTIME, ServiceProviders.SARVAM, + ServiceProviders.SMALLEST, ] api_key: str | list[str] @@ -255,6 +259,11 @@ SPEACHES_PROVIDER_MODEL_CONFIG = provider_model_config( ), provider_docs_url="https://github.com/speaches-ai/speaches", ) +HUGGINGFACE_PROVIDER_MODEL_CONFIG = provider_model_config( + "Hugging Face", + description="Hosted Hugging Face Inference Providers API for usage-based inference.", + provider_docs_url="https://huggingface.co/docs/inference-providers/en/index", +) AZURE_SPEECH_PROVIDER_MODEL_CONFIG = provider_model_config( "Azure Speech Services", description="Azure Cognitive Services Speech — TTS and STT via the Azure Speech SDK.", @@ -471,6 +480,35 @@ class SpeachesLLMConfiguration(BaseLLMConfiguration): ) +HUGGINGFACE_LLM_MODELS = [ + "openai/gpt-oss-120b:cerebras", + "deepseek-ai/DeepSeek-R1:fastest", + "Qwen/Qwen3-Coder-480B-A35B-Instruct:fastest", +] + + +@register_llm +class HuggingFaceLLMConfiguration(BaseLLMConfiguration): + model_config = HUGGINGFACE_PROVIDER_MODEL_CONFIG + provider: Literal[ServiceProviders.HUGGINGFACE] = ServiceProviders.HUGGINGFACE + model: str = Field( + default="openai/gpt-oss-120b:cerebras", + description="Hugging Face chat-completion model identifier, optionally with provider suffix.", + json_schema_extra={ + "examples": HUGGINGFACE_LLM_MODELS, + "allow_custom_input": True, + }, + ) + base_url: str = Field( + default="https://router.huggingface.co/v1", + description="Hugging Face OpenAI-compatible chat-completions router base URL.", + ) + bill_to: str | None = Field( + default=None, + description="Optional Hugging Face organization or user to bill using X-HF-Bill-To.", + ) + + MINIMAX_MODELS = [ "MiniMax-M2.7", "MiniMax-M2.7-highspeed", @@ -741,6 +779,7 @@ LLMConfig = Annotated[ DograhLLMService, AWSBedrockLLMConfiguration, SpeachesLLMConfiguration, + HuggingFaceLLMConfiguration, MiniMaxLLMConfiguration, SarvamLLMConfiguration, ], @@ -907,6 +946,7 @@ class DograhTTSService(BaseTTSConfiguration): voice: str = Field( default="default", description="Voice preset.", + json_schema_extra={"allow_custom_input": True}, ) speed: float = Field(default=1.0, ge=0.5, le=2.0, description="Speed of the voice.") @@ -961,6 +1001,12 @@ class SarvamTTSConfiguration(BaseTTSConfiguration): description="BCP-47 Indian-language code (e.g. hi-IN, en-IN).", json_schema_extra={"examples": SARVAM_LANGUAGES}, ) + speed: float = Field( + default=1.0, + ge=0.5, + le=2.0, + description="Speech speed multiplier.", + ) CAMB_TTS_MODELS = ["mars-flash", "mars-pro", "mars-instruct"] @@ -1120,6 +1166,80 @@ class AzureSpeechTTSConfiguration(BaseTTSConfiguration): ) +SMALLEST_PROVIDER_MODEL_CONFIG = provider_model_config( + "Smallest AI", + description="Smallest AI ultralow-latency TTS (Waves) and STT (Pulse) APIs.", + provider_docs_url="https://smallest.ai/docs", +) + +SMALLEST_TTS_MODELS = ["lightning_v3.1", "lightning_v3.1_pro"] +SMALLEST_TTS_VOICES = [ + "sophia", + "avery", + "liam", + "lucas", + "olivia", + "ryan", + "freya", + "william", + "devansh", + "arjun", + "niharika", + "maya", + "dhruv", + "mia", + "maithili", +] +SMALLEST_TTS_LANGUAGES = [ + "en", + "hi", + "fr", + "de", + "es", + "it", + "nl", + "pl", + "ru", + "ar", + "bn", + "gu", + "he", + "kn", + "mr", + "ta", +] + + +@register_tts +class SmallestAITTSConfiguration(BaseTTSConfiguration): + model_config = SMALLEST_PROVIDER_MODEL_CONFIG + provider: Literal[ServiceProviders.SMALLEST] = ServiceProviders.SMALLEST + model: str = Field( + default="lightning_v3.1", + description="Smallest AI TTS model. lightning_v3.1_pro is the premium pool (American, British, Indian accents); lightning_v3.1 is the standard pool with 217 voices across 12 languages.", + json_schema_extra={"examples": SMALLEST_TTS_MODELS}, + ) + voice: str = Field( + default="sophia", + description="Smallest AI voice ID.", + json_schema_extra={"examples": SMALLEST_TTS_VOICES, "allow_custom_input": True}, + ) + language: str = Field( + default="en", + description="ISO 639-1 language code for synthesis.", + json_schema_extra={ + "examples": SMALLEST_TTS_LANGUAGES, + "allow_custom_input": True, + }, + ) + speed: float = Field( + default=1.0, + ge=0.5, + le=2.0, + description="Speech speed multiplier (0.5 to 2.0).", + ) + + TTSConfig = Annotated[ Union[ DeepgramTTSConfiguration, @@ -1134,6 +1254,7 @@ TTSConfig = Annotated[ SpeachesTTSConfiguration, MiniMaxTTSConfiguration, AzureSpeechTTSConfiguration, + SmallestAITTSConfiguration, ], Field(discriminator="provider"), ] @@ -1334,6 +1455,38 @@ class SpeachesSTTConfiguration(BaseSTTConfiguration): ) +HUGGINGFACE_STT_MODELS = [ + "openai/whisper-large-v3-turbo", + "openai/whisper-large-v3", +] + + +@register_stt +class HuggingFaceSTTConfiguration(BaseSTTConfiguration): + model_config = HUGGINGFACE_PROVIDER_MODEL_CONFIG + provider: Literal[ServiceProviders.HUGGINGFACE] = ServiceProviders.HUGGINGFACE + model: str = Field( + default="openai/whisper-large-v3-turbo", + description="Hugging Face ASR model identifier served through Inference Providers.", + json_schema_extra={ + "examples": HUGGINGFACE_STT_MODELS, + "allow_custom_input": True, + }, + ) + base_url: str = Field( + default="https://router.huggingface.co/hf-inference", + description="Hugging Face Inference Providers router base URL.", + ) + bill_to: str | None = Field( + default=None, + description="Optional Hugging Face organization or user to bill using X-HF-Bill-To.", + ) + return_timestamps: bool = Field( + default=False, + description="Request timestamp chunks when supported by the selected provider/model.", + ) + + ASSEMBLYAI_STT_MODELS = ["u3-rt-pro"] ASSEMBLYAI_STT_LANGUAGES = ["en", "es", "de", "fr", "pt", "it"] @@ -1396,6 +1549,62 @@ class AzureSpeechSTTConfiguration(BaseSTTConfiguration): ) +SMALLEST_STT_MODELS = ["pulse"] +SMALLEST_STT_LANGUAGES = [ + "en", + "hi", + "fr", + "de", + "es", + "it", + "nl", + "pl", + "ru", + "pt", + "bn", + "gu", + "kn", + "ml", + "mr", + "ta", + "te", + "pa", + "or", + "bg", + "cs", + "da", + "et", + "fi", + "hu", + "lt", + "lv", + "mt", + "ro", + "sk", + "sv", + "uk", +] + + +@register_stt +class SmallestAISTTConfiguration(BaseSTTConfiguration): + model_config = SMALLEST_PROVIDER_MODEL_CONFIG + provider: Literal[ServiceProviders.SMALLEST] = ServiceProviders.SMALLEST + model: str = Field( + default="pulse", + description="Smallest AI STT model. Supports 38 languages with real-time streaming.", + json_schema_extra={"examples": SMALLEST_STT_MODELS}, + ) + language: str = Field( + default="en", + description="ISO 639-1 language code for transcription.", + json_schema_extra={ + "examples": SMALLEST_STT_LANGUAGES, + "allow_custom_input": True, + }, + ) + + STTConfig = Annotated[ Union[ DeepgramSTTConfiguration, @@ -1406,9 +1615,11 @@ STTConfig = Annotated[ SpeechmaticsSTTConfiguration, SarvamSTTConfiguration, SpeachesSTTConfiguration, + HuggingFaceSTTConfiguration, AssemblyAISTTConfiguration, GladiaSTTConfiguration, AzureSpeechSTTConfiguration, + SmallestAISTTConfiguration, ], Field(discriminator="provider"), ] diff --git a/api/services/pipecat/event_handlers.py b/api/services/pipecat/event_handlers.py index 5ce82a9d..bb66d19f 100644 --- a/api/services/pipecat/event_handlers.py +++ b/api/services/pipecat/event_handlers.py @@ -9,8 +9,8 @@ from api.services.integrations import IntegrationRuntimeSession from api.services.pipecat.audio_config import AudioConfig from api.services.pipecat.audio_playback import play_audio_loop from api.services.pipecat.in_memory_buffers import ( - InMemoryAudioBuffer, InMemoryLogsBuffer, + InMemoryRecordingBuffers, ) from api.services.pipecat.pipeline_metrics_aggregator import PipelineMetricsAggregator from api.services.pipecat.tracing_config import get_trace_url @@ -40,11 +40,11 @@ async def _capture_call_event( "workflow_run_id": workflow_run_id, "workflow_id": workflow_run.workflow_id if workflow_run else None, "call_type": workflow_run.mode if workflow_run else None, - "call_direction": (workflow_run.initial_context or {}).get( - "direction", "outbound" - ) - if workflow_run - else None, + "call_direction": ( + (workflow_run.initial_context or {}).get("direction", "outbound") + if workflow_run + else None + ), } if extra_properties: properties.update(extra_properties) @@ -73,7 +73,7 @@ def register_event_handlers( """Register all event handlers for transport and task events. Returns: - in_memory_audio_buffer for use by other handlers. + In-memory recording buffers for use by other handlers. """ # Initialize in-memory buffers with proper audio configuration sample_rate = audio_config.pipeline_sample_rate if audio_config else 16000 @@ -84,7 +84,7 @@ def register_event_handlers( f"with sample_rate={sample_rate}Hz, channels={num_channels}" ) - in_memory_audio_buffer = InMemoryAudioBuffer( + in_memory_audio_buffers = InMemoryRecordingBuffers( workflow_run_id=workflow_run_id, sample_rate=sample_rate, num_channels=num_channels, @@ -363,14 +363,32 @@ def register_event_handlers( # Write buffers to temp files and enqueue combined processing task audio_temp_path = None + user_audio_temp_path = None + bot_audio_temp_path = None transcript_temp_path = None try: - if not in_memory_audio_buffer.is_empty: - audio_temp_path = await in_memory_audio_buffer.write_to_temp_file() + if not in_memory_audio_buffers.mixed.is_empty: + audio_temp_path = ( + await in_memory_audio_buffers.mixed.write_to_temp_file() + ) else: logger.debug("Audio buffer is empty, skipping upload") + if not in_memory_audio_buffers.user.is_empty: + user_audio_temp_path = ( + await in_memory_audio_buffers.user.write_to_temp_file() + ) + else: + logger.debug("User audio buffer is empty, skipping upload") + + if not in_memory_audio_buffers.bot.is_empty: + bot_audio_temp_path = ( + await in_memory_audio_buffers.bot.write_to_temp_file() + ) + else: + logger.debug("Bot audio buffer is empty, skipping upload") + transcript_temp_path = in_memory_logs_buffer.write_transcript_to_temp_file() if not transcript_temp_path: logger.debug("No transcript events in logs buffer, skipping upload") @@ -385,16 +403,18 @@ def register_event_handlers( workflow_run_id, audio_temp_path, transcript_temp_path, + user_audio_temp_path, + bot_audio_temp_path, ) # Return the buffer so it can be passed to other handlers - return in_memory_audio_buffer + return in_memory_audio_buffers def register_audio_data_handler( audio_buffer: AudioBufferProcessor, workflow_run_id, - in_memory_buffer: InMemoryAudioBuffer, + in_memory_buffers: InMemoryRecordingBuffers, ): """Register event handler for audio data""" logger.info(f"Registering audio data handler for workflow run {workflow_run_id}") @@ -404,9 +424,19 @@ def register_audio_data_handler( if not audio: return - # Use in-memory buffer try: - await in_memory_buffer.append(audio) + await in_memory_buffers.mixed.append(audio) except MemoryError as e: - logger.error(f"Memory buffer full: {e}") - # Could implement overflow to disk here if needed + logger.error(f"Mixed audio buffer full: {e}") + + @audio_buffer.event_handler("on_track_audio_data") + async def on_track_audio_data( + buffer, user_audio, bot_audio, sample_rate, num_channels + ): + try: + if user_audio: + await in_memory_buffers.user.append(user_audio) + if bot_audio: + await in_memory_buffers.bot.append(bot_audio) + except MemoryError as e: + logger.error(f"Track audio buffer full: {e}") diff --git a/api/services/pipecat/in_memory_buffers.py b/api/services/pipecat/in_memory_buffers.py index 3cf22d55..5c7f3030 100644 --- a/api/services/pipecat/in_memory_buffers.py +++ b/api/services/pipecat/in_memory_buffers.py @@ -75,6 +75,27 @@ class InMemoryAudioBuffer: return self._total_size +class InMemoryRecordingBuffers: + """Holds the mixed recording plus aligned user and bot mono tracks.""" + + def __init__(self, workflow_run_id: int, sample_rate: int, num_channels: int = 1): + self.mixed = InMemoryAudioBuffer( + workflow_run_id=workflow_run_id, + sample_rate=sample_rate, + num_channels=num_channels, + ) + self.user = InMemoryAudioBuffer( + workflow_run_id=workflow_run_id, + sample_rate=sample_rate, + num_channels=1, + ) + self.bot = InMemoryAudioBuffer( + workflow_run_id=workflow_run_id, + sample_rate=sample_rate, + num_channels=1, + ) + + class InMemoryLogsBuffer: """Buffer real-time feedback events in memory during a call, then save to workflow run logs.""" diff --git a/api/services/pipecat/service_factory.py b/api/services/pipecat/service_factory.py index ec5e9911..68f7c303 100644 --- a/api/services/pipecat/service_factory.py +++ b/api/services/pipecat/service_factory.py @@ -39,8 +39,17 @@ from pipecat.services.google.vertex.llm import ( GoogleVertexLLMSettings, ) from pipecat.services.groq.llm import GroqLLMService, GroqLLMSettings +from pipecat.services.huggingface.llm import ( + HuggingFaceLLMService, + HuggingFaceLLMSettings, +) +from pipecat.services.huggingface.stt import ( + HuggingFaceSTTService, + HuggingFaceSTTSettings, +) from pipecat.services.minimax.llm import MiniMaxLLMService from pipecat.services.minimax.tts import MiniMaxTTSSettings +from pipecat.services.openai._constants import OPENAI_SAMPLE_RATE from pipecat.services.openai.base_llm import OpenAILLMSettings from pipecat.services.openai.llm import OpenAILLMService from pipecat.services.openai.stt import ( @@ -53,6 +62,8 @@ from pipecat.services.rime.tts import RimeTTSService, RimeTTSSettings from pipecat.services.sarvam.llm import SarvamLLMService, SarvamLLMSettings from pipecat.services.sarvam.stt import SarvamSTTService, SarvamSTTSettings from pipecat.services.sarvam.tts import SarvamTTSService, SarvamTTSSettings +from pipecat.services.smallest.stt import SmallestSTTService, SmallestSTTSettings +from pipecat.services.smallest.tts import SmallestTTSService, SmallestTTSSettings from pipecat.services.speaches.llm import SpeachesLLMService, SpeachesLLMSettings from pipecat.services.speaches.stt import SpeachesSTTService, SpeachesSTTSettings from pipecat.services.speaches.tts import SpeachesTTSService, SpeachesTTSSettings @@ -218,6 +229,22 @@ def create_stt_service( ), sample_rate=audio_config.transport_in_sample_rate, ) + elif user_config.stt.provider == ServiceProviders.HUGGINGFACE.value: + base_url = ( + getattr(user_config.stt, "base_url", None) + or "https://router.huggingface.co/hf-inference" + ) + _validate_runtime_service_url(base_url, "base_url") + return HuggingFaceSTTService( + api_key=user_config.stt.api_key, + base_url=base_url, + bill_to=getattr(user_config.stt, "bill_to", None), + settings=HuggingFaceSTTSettings( + model=user_config.stt.model, + return_timestamps=getattr(user_config.stt, "return_timestamps", False), + ), + sample_rate=audio_config.transport_in_sample_rate, + ) elif user_config.stt.provider == ServiceProviders.ASSEMBLYAI.value: language = getattr(user_config.stt, "language", None) settings_kwargs = {"model": user_config.stt.model, "language": language} @@ -284,6 +311,20 @@ def create_stt_service( settings=AzureSTTSettings(language=pipecat_language), sample_rate=audio_config.transport_in_sample_rate, ) + elif user_config.stt.provider == ServiceProviders.SMALLEST.value: + language_code = getattr(user_config.stt, "language", None) or "en" + try: + pipecat_language = Language(language_code) + except ValueError: + pipecat_language = Language.EN + return SmallestSTTService( + api_key=user_config.stt.api_key, + settings=SmallestSTTSettings( + model=user_config.stt.model, + language=pipecat_language, + ), + sample_rate=audio_config.transport_in_sample_rate, + ) else: raise HTTPException( status_code=400, detail=f"Invalid STT provider {user_config.stt.provider}" @@ -320,6 +361,7 @@ def create_tts_service( kwargs["base_url"] = base_url return OpenAITTSService( api_key=user_config.tts.api_key, + sample_rate=OPENAI_SAMPLE_RATE, settings=OpenAITTSSettings(model=user_config.tts.model), text_filters=[xml_function_tag_filter], skip_aggregator_types=["recording_router", "recording"], @@ -493,13 +535,17 @@ def create_tts_service( pipecat_language = language_mapping.get(language, Language.HI) voice = getattr(user_config.tts, "voice", None) or "anushka" + speed = getattr(user_config.tts, "speed", None) + settings_kwargs = { + "model": user_config.tts.model, + "voice": voice, + "language": pipecat_language, + } + if speed and speed != 1.0: + settings_kwargs["pace"] = speed return SarvamTTSService( api_key=user_config.tts.api_key, - settings=SarvamTTSSettings( - model=user_config.tts.model, - voice=voice, - language=pipecat_language, - ), + settings=SarvamTTSSettings(**settings_kwargs), text_filters=[xml_function_tag_filter], skip_aggregator_types=["recording_router", "recording"], silence_time_s=1.0, @@ -560,6 +606,28 @@ def create_tts_service( skip_aggregator_types=["recording_router", "recording"], silence_time_s=1.0, ) + elif user_config.tts.provider == ServiceProviders.SMALLEST.value: + language_code = getattr(user_config.tts, "language", None) or "en" + try: + pipecat_language = Language(language_code) + except ValueError: + pipecat_language = Language.EN + speed = getattr(user_config.tts, "speed", None) + model = user_config.tts.model.replace("lightning-v", "lightning_v") + settings_kwargs = SmallestTTSSettings( + model=model, + voice=user_config.tts.voice, + language=pipecat_language, + ) + if speed and speed != 1.0: + settings_kwargs.speed = speed + return SmallestTTSService( + api_key=user_config.tts.api_key, + settings=settings_kwargs, + text_filters=[xml_function_tag_filter], + skip_aggregator_types=["recording_router", "recording"], + silence_time_s=1.0, + ) else: raise HTTPException( status_code=400, detail=f"Invalid TTS provider {user_config.tts.provider}" @@ -581,6 +649,7 @@ def create_llm_service_from_provider( location: str | None = None, credentials: str | None = None, temperature: float | None = None, + bill_to: str | None = None, ): """Create an LLM service from explicit provider/model/api_key. @@ -663,6 +732,15 @@ def create_llm_service_from_provider( api_key=api_key or "none", settings=SpeachesLLMSettings(model=model), ) + elif provider == ServiceProviders.HUGGINGFACE.value: + base_url = base_url or "https://router.huggingface.co/v1" + _validate_runtime_service_url(base_url, "base_url") + return HuggingFaceLLMService( + api_key=api_key, + base_url=base_url, + bill_to=bill_to, + settings=HuggingFaceLLMSettings(model=model, temperature=0.1), + ) elif provider == ServiceProviders.MINIMAX.value: base_url = base_url or "https://api.minimax.io/v1" _validate_runtime_service_url(base_url, "base_url") @@ -875,6 +953,9 @@ def create_llm_service(user_config, correlation_id: str | None = None): kwargs["endpoint"] = user_config.llm.endpoint elif provider == ServiceProviders.SPEACHES.value: kwargs["base_url"] = user_config.llm.base_url + elif provider == ServiceProviders.HUGGINGFACE.value: + kwargs["base_url"] = user_config.llm.base_url + kwargs["bill_to"] = user_config.llm.bill_to elif provider == ServiceProviders.AWS_BEDROCK.value: kwargs["aws_access_key"] = user_config.llm.aws_access_key kwargs["aws_secret_key"] = user_config.llm.aws_secret_key diff --git a/api/services/workflow/dto.py b/api/services/workflow/dto.py index 60aad758..8533de36 100644 --- a/api/services/workflow/dto.py +++ b/api/services/workflow/dto.py @@ -718,6 +718,8 @@ class TriggerNodeData(BaseNodeData): "rsvp": "{{gathered_context.rsvp}}", "duration": "{{cost_info.call_duration_seconds}}", "recording_url": "{{recording_url}}", + "user_recording_url": "{{user_recording_url}}", + "bot_recording_url": "{{bot_recording_url}}", "transcript_url": "{{transcript_url}}", }, }, diff --git a/api/tasks/run_integrations.py b/api/tasks/run_integrations.py index be11a3ce..d99eaf0e 100644 --- a/api/tasks/run_integrations.py +++ b/api/tasks/run_integrations.py @@ -27,6 +27,7 @@ from api.services.workflow.dto import ( ) from api.services.workflow.qa import run_per_node_qa_analysis from api.utils.credential_auth import build_auth_header +from api.utils.recording_artifacts import get_recording_storage_key from api.utils.template_renderer import render_template @@ -339,6 +340,10 @@ def _build_render_context( Returns: Dict containing all fields available for template rendering """ + extra = workflow_run.extra or {} + user_recording_key = get_recording_storage_key(extra, "user") + bot_recording_key = get_recording_storage_key(extra, "bot") + context = { # Top-level fields "workflow_run_id": workflow_run.id, @@ -353,6 +358,7 @@ def _build_render_context( "cost_info": workflow_run.usage_info or {}, # Annotations (includes QA results) "annotations": workflow_run.annotations or {}, + "extra": extra, } # Add public download URLs if token is available @@ -366,9 +372,17 @@ def _build_render_context( context["transcript_url"] = ( f"{base_url}/transcript" if workflow_run.transcript_url else None ) + context["user_recording_url"] = ( + f"{base_url}/user_recording" if user_recording_key else None + ) + context["bot_recording_url"] = ( + f"{base_url}/bot_recording" if bot_recording_key else None + ) else: context["recording_url"] = workflow_run.recording_url context["transcript_url"] = workflow_run.transcript_url + context["user_recording_url"] = user_recording_key + context["bot_recording_url"] = bot_recording_key return context diff --git a/api/tasks/workflow_completion.py b/api/tasks/workflow_completion.py index ff0482d2..6943c0d6 100644 --- a/api/tasks/workflow_completion.py +++ b/api/tasks/workflow_completion.py @@ -12,11 +12,51 @@ from api.services.workflow_run_billing import ( from api.tasks.run_integrations import run_integrations_post_workflow_run +def _recording_metadata(storage_key: str, storage_backend: str, track: str) -> dict: + return { + "storage_key": storage_key, + "storage_backend": storage_backend, + "format": "wav", + "track": track, + } + + +async def _upload_temp_file( + workflow_run_id: int, + temp_file_path: str, + storage_key: str, + label: str, +) -> bool: + try: + if not os.path.exists(temp_file_path): + logger.warning(f"{label} temp file not found: {temp_file_path}") + return False + + file_size = os.path.getsize(temp_file_path) + logger.debug(f"{label} file size: {file_size} bytes") + + await storage_fs.aupload_file(temp_file_path, storage_key) + logger.info(f"Successfully uploaded {label}: {storage_key}") + return True + except Exception as e: + logger.error(f"Error uploading {label} for workflow {workflow_run_id}: {e}") + return False + finally: + if os.path.exists(temp_file_path): + try: + os.remove(temp_file_path) + logger.debug(f"Cleaned up temp {label} file: {temp_file_path}") + except Exception as e: + logger.warning(f"Failed to clean up temp {label} file: {e}") + + async def process_workflow_completion( _ctx, workflow_run_id: int, audio_temp_path: Optional[str] = None, transcript_temp_path: Optional[str] = None, + user_audio_temp_path: Optional[str] = None, + bot_audio_temp_path: Optional[str] = None, ): """Process workflow completion: upload artifacts and run integrations. @@ -28,6 +68,8 @@ async def process_workflow_completion( workflow_run_id: The workflow run ID audio_temp_path: Optional path to temp audio file transcript_temp_path: Optional path to temp transcript file + user_audio_temp_path: Optional path to temp user-track audio file + bot_audio_temp_path: Optional path to temp bot-track audio file """ run_id = str(workflow_run_id) set_current_run_id(run_id) @@ -37,35 +79,55 @@ async def process_workflow_completion( storage_backend = get_current_storage_backend() # Step 1: Upload audio if provided + recordings_metadata: dict[str, dict] = {} + if audio_temp_path: - try: - if os.path.exists(audio_temp_path): - file_size = os.path.getsize(audio_temp_path) - logger.debug(f"Audio file size: {file_size} bytes") + recording_url = f"recordings/{workflow_run_id}.wav" + logger.info( + f"Uploading mixed audio to {storage_backend.name} - workflow_run_id: {workflow_run_id}" + ) + if await _upload_temp_file( + workflow_run_id, audio_temp_path, recording_url, "mixed audio" + ): + recordings_metadata["mixed"] = _recording_metadata( + recording_url, storage_backend.value, "mixed" + ) + await db_client.update_workflow_run( + run_id=workflow_run_id, + recording_url=recording_url, + storage_backend=storage_backend.value, + ) - recording_url = f"recordings/{workflow_run_id}.wav" - logger.info( - f"Uploading audio to {storage_backend.name} - workflow_run_id: {workflow_run_id}" - ) + if user_audio_temp_path: + user_recording_url = f"recordings/{workflow_run_id}/user.wav" + logger.info( + f"Uploading user audio to {storage_backend.name} - workflow_run_id: {workflow_run_id}" + ) + if await _upload_temp_file( + workflow_run_id, user_audio_temp_path, user_recording_url, "user audio" + ): + recordings_metadata["user"] = _recording_metadata( + user_recording_url, storage_backend.value, "user" + ) - await storage_fs.aupload_file(audio_temp_path, recording_url) - await db_client.update_workflow_run( - run_id=workflow_run_id, - recording_url=recording_url, - storage_backend=storage_backend.value, - ) - logger.info(f"Successfully uploaded audio: {recording_url}") - else: - logger.warning(f"Audio temp file not found: {audio_temp_path}") - except Exception as e: - logger.error(f"Error uploading audio for workflow {workflow_run_id}: {e}") - finally: - if audio_temp_path and os.path.exists(audio_temp_path): - try: - os.remove(audio_temp_path) - logger.debug(f"Cleaned up temp audio file: {audio_temp_path}") - except Exception as e: - logger.warning(f"Failed to clean up temp audio file: {e}") + if bot_audio_temp_path: + bot_recording_url = f"recordings/{workflow_run_id}/bot.wav" + logger.info( + f"Uploading bot audio to {storage_backend.name} - workflow_run_id: {workflow_run_id}" + ) + if await _upload_temp_file( + workflow_run_id, bot_audio_temp_path, bot_recording_url, "bot audio" + ): + recordings_metadata["bot"] = _recording_metadata( + bot_recording_url, storage_backend.value, "bot" + ) + + if recordings_metadata: + await db_client.update_workflow_run( + run_id=workflow_run_id, + storage_backend=storage_backend.value, + extra={"recordings": recordings_metadata}, + ) # Step 2: Upload transcript if provided if transcript_temp_path: diff --git a/api/tests/test_huggingface_stt_service_factory.py b/api/tests/test_huggingface_stt_service_factory.py new file mode 100644 index 00000000..e7516c8a --- /dev/null +++ b/api/tests/test_huggingface_stt_service_factory.py @@ -0,0 +1,131 @@ +from types import SimpleNamespace +from unittest.mock import patch + +from api.services.configuration.check_validity import UserConfigurationValidator +from api.services.configuration.registry import ( + REGISTRY, + HuggingFaceLLMConfiguration, + HuggingFaceSTTConfiguration, + ServiceProviders, + ServiceType, +) +from api.services.pipecat.service_factory import ( + create_llm_service, + create_stt_service, +) + + +def test_huggingface_stt_configuration_defaults_and_registry(): + config = HuggingFaceSTTConfiguration(api_key="hf_test") + + assert config.provider == ServiceProviders.HUGGINGFACE + assert config.model == "openai/whisper-large-v3-turbo" + assert config.base_url == "https://router.huggingface.co/hf-inference" + assert config.return_timestamps is False + assert ( + REGISTRY[ServiceType.STT][ServiceProviders.HUGGINGFACE] + is HuggingFaceSTTConfiguration + ) + + +def test_huggingface_llm_configuration_defaults_and_registry(): + config = HuggingFaceLLMConfiguration(api_key="hf_test") + + assert config.provider == ServiceProviders.HUGGINGFACE + assert config.model == "openai/gpt-oss-120b:cerebras" + assert config.base_url == "https://router.huggingface.co/v1" + assert ( + REGISTRY[ServiceType.LLM][ServiceProviders.HUGGINGFACE] + is HuggingFaceLLMConfiguration + ) + + +def test_create_huggingface_llm_service_uses_openai_compatible_router(): + user_config = SimpleNamespace( + llm=SimpleNamespace( + provider=ServiceProviders.HUGGINGFACE.value, + api_key="hf_test", + model="deepseek-ai/DeepSeek-R1:fastest", + base_url="https://router.huggingface.co/v1", + bill_to="demo-org", + ) + ) + + with patch( + "api.services.pipecat.service_factory.HuggingFaceLLMService" + ) as mock_service: + create_llm_service(user_config) + + assert mock_service.call_count == 1 + kwargs = mock_service.call_args.kwargs + assert kwargs["api_key"] == "hf_test" + assert kwargs["base_url"] == "https://router.huggingface.co/v1" + assert kwargs["bill_to"] == "demo-org" + assert kwargs["settings"].model == "deepseek-ai/DeepSeek-R1:fastest" + assert kwargs["settings"].temperature == 0.1 + + +def test_create_huggingface_stt_service_uses_hosted_defaults(): + user_config = SimpleNamespace( + stt=SimpleNamespace( + provider=ServiceProviders.HUGGINGFACE.value, + api_key="hf_test", + model="openai/whisper-large-v3-turbo", + base_url="https://router.huggingface.co/hf-inference", + bill_to="demo-org", + return_timestamps=True, + ) + ) + audio_config = SimpleNamespace(transport_in_sample_rate=16000) + + with patch( + "api.services.pipecat.service_factory.HuggingFaceSTTService" + ) as mock_service: + create_stt_service(user_config, audio_config) + + assert mock_service.call_count == 1 + kwargs = mock_service.call_args.kwargs + assert kwargs["api_key"] == "hf_test" + assert kwargs["base_url"] == "https://router.huggingface.co/hf-inference" + assert kwargs["bill_to"] == "demo-org" + assert kwargs["sample_rate"] == 16000 + assert kwargs["settings"].model == "openai/whisper-large-v3-turbo" + assert kwargs["settings"].return_timestamps is True + + +def test_validator_accepts_huggingface_stt_token_format(): + validator = UserConfigurationValidator() + + assert ( + validator._validate_service( + HuggingFaceSTTConfiguration(api_key="hf_test"), + "stt", + ) + == [] + ) + assert ( + validator._validate_service( + HuggingFaceLLMConfiguration(api_key="hf_test"), + "llm", + ) + == [] + ) + + +def test_validator_rejects_non_huggingface_token_format(): + validator = UserConfigurationValidator() + + errors = validator._validate_service( + HuggingFaceSTTConfiguration(api_key="not-hf-token"), + "stt", + ) + + assert errors == [ + { + "model": "stt", + "message": ( + "Invalid Hugging Face API token format. Use a token that starts with " + "'hf_' and has Inference Providers permission." + ), + } + ] diff --git a/api/tests/test_openai_tts_service_factory.py b/api/tests/test_openai_tts_service_factory.py new file mode 100644 index 00000000..cb44f4b1 --- /dev/null +++ b/api/tests/test_openai_tts_service_factory.py @@ -0,0 +1,31 @@ +from types import SimpleNamespace +from unittest.mock import patch + +from pipecat.services.openai._constants import OPENAI_SAMPLE_RATE + +from api.services.configuration.registry import ServiceProviders +from api.services.pipecat.service_factory import create_tts_service + + +def test_create_openai_tts_service_uses_openai_pcm_sample_rate(): + user_config = SimpleNamespace( + tts=SimpleNamespace( + provider=ServiceProviders.OPENAI.value, + api_key="test-key", + model="gpt-4o-mini-tts", + voice="alloy", + base_url=None, + ) + ) + audio_config = SimpleNamespace( + transport_out_sample_rate=16000, + transport_in_sample_rate=16000, + ) + + with patch("api.services.pipecat.service_factory.OpenAITTSService") as mock_service: + create_tts_service(user_config, audio_config) + + assert mock_service.call_count == 1 + kwargs = mock_service.call_args.kwargs + assert kwargs["sample_rate"] == OPENAI_SAMPLE_RATE + assert kwargs["settings"].model == "gpt-4o-mini-tts" diff --git a/api/tests/test_s3_signed_url.py b/api/tests/test_s3_signed_url.py new file mode 100644 index 00000000..95156dcb --- /dev/null +++ b/api/tests/test_s3_signed_url.py @@ -0,0 +1,30 @@ +from api.routes.s3_signed_url import ( + _extract_legacy_workflow_run_id, + _extract_org_id_from_key, +) + + +def test_split_recording_keys_are_workflow_run_artifacts_not_org_keys(): + assert _extract_legacy_workflow_run_id("recordings/1855/user.wav") == 1855 + assert _extract_legacy_workflow_run_id("recordings/1855/bot.wav") == 1855 + + assert _extract_org_id_from_key("recordings/1855/user.wav") is None + assert _extract_org_id_from_key("recordings/1855/bot.wav") is None + + +def test_legacy_recording_keys_do_not_fall_through_to_org_scoped_auth(): + assert _extract_legacy_workflow_run_id("recordings/1855.wav") == 1855 + assert _extract_legacy_workflow_run_id("recordings/1855/other.wav") is None + + assert _extract_org_id_from_key("recordings/1855.wav") is None + assert _extract_org_id_from_key("recordings/1855/other.wav") is None + + +def test_known_org_scoped_keys_extract_org_id(): + assert _extract_org_id_from_key("campaigns/42/source.csv") == 42 + assert _extract_org_id_from_key("knowledge_base/42/document/file.pdf") == 42 + assert _extract_legacy_workflow_run_id("campaigns/42/source.csv") is None + + +def test_unknown_numeric_prefix_is_not_treated_as_org_scoped(): + assert _extract_org_id_from_key("unknown/42/file.wav") is None diff --git a/api/tests/test_sarvam_service_factory.py b/api/tests/test_sarvam_service_factory.py index 3040769f..7abd0d0c 100644 --- a/api/tests/test_sarvam_service_factory.py +++ b/api/tests/test_sarvam_service_factory.py @@ -7,6 +7,7 @@ from pipecat.transcriptions.language import Language from api.services.configuration.registry import ( SarvamLLMConfiguration, + SarvamTTSConfiguration, ServiceProviders, ) from api.services.pipecat.audio_config import AudioConfig @@ -14,6 +15,7 @@ from api.services.pipecat.service_factory import ( create_llm_service, create_llm_service_from_provider, create_stt_service, + create_tts_service, ) @@ -112,3 +114,41 @@ class TestSarvamSTTServiceFactory: kwargs = mock_service.call_args.kwargs assert kwargs["settings"].language == expected_language + + +class TestSarvamTTSServiceFactory: + def test_sarvam_tts_configuration_defaults(self): + config = SarvamTTSConfiguration(api_key="test-key") + + assert config.provider == ServiceProviders.SARVAM + assert config.model == "bulbul:v2" + assert config.voice == "anushka" + assert config.language == "hi-IN" + assert config.speed == 1.0 + + def test_create_sarvam_tts_service_maps_speed_to_pace(self): + user_config = SimpleNamespace( + tts=SimpleNamespace( + provider=ServiceProviders.SARVAM.value, + api_key="test-key", + model="bulbul:v2", + voice="anushka", + language="hi-IN", + speed=1.25, + ) + ) + audio_config = AudioConfig( + transport_in_sample_rate=16000, transport_out_sample_rate=16000 + ) + + with patch( + "api.services.pipecat.service_factory.SarvamTTSService" + ) as mock_service: + create_tts_service(user_config, audio_config) + + kwargs = mock_service.call_args.kwargs + assert kwargs["api_key"] == "test-key" + assert kwargs["settings"].model == "bulbul:v2" + assert kwargs["settings"].voice == "anushka" + assert kwargs["settings"].language == Language.HI + assert kwargs["settings"].pace == 1.25 diff --git a/api/tests/test_smallest_service_factory.py b/api/tests/test_smallest_service_factory.py new file mode 100644 index 00000000..521fd2a8 --- /dev/null +++ b/api/tests/test_smallest_service_factory.py @@ -0,0 +1,80 @@ +from types import SimpleNamespace +from unittest.mock import patch + +from api.services.configuration.check_validity import UserConfigurationValidator +from api.services.configuration.registry import ( + REGISTRY, + ServiceProviders, + ServiceType, + SmallestAISTTConfiguration, + SmallestAITTSConfiguration, +) +from api.services.pipecat.service_factory import create_tts_service + + +def test_smallest_tts_configuration_defaults_and_registry(): + config = SmallestAITTSConfiguration(api_key="test-key") + + assert config.provider == ServiceProviders.SMALLEST + assert config.model == "lightning_v3.1" + assert config.voice == "sophia" + assert config.language == "en" + assert config.speed == 1.0 + assert ( + REGISTRY[ServiceType.TTS][ServiceProviders.SMALLEST] + is SmallestAITTSConfiguration + ) + + +def test_smallest_stt_configuration_defaults_and_registry(): + config = SmallestAISTTConfiguration(api_key="test-key") + + assert config.provider == ServiceProviders.SMALLEST + assert config.model == "pulse" + assert config.language == "en" + assert ( + REGISTRY[ServiceType.STT][ServiceProviders.SMALLEST] + is SmallestAISTTConfiguration + ) + + +def test_validator_accepts_smallest_services(): + validator = UserConfigurationValidator() + + assert ( + validator._validate_service( + SmallestAITTSConfiguration(api_key="test-key"), + "tts", + ) + == [] + ) + assert ( + validator._validate_service( + SmallestAISTTConfiguration(api_key="test-key"), + "stt", + ) + == [] + ) + + +def test_create_smallest_tts_service_normalizes_hyphenated_model_values(): + user_config = SimpleNamespace( + tts=SimpleNamespace( + provider=ServiceProviders.SMALLEST.value, + api_key="test-key", + model="lightning-v3.1", + voice="sophia", + language="en", + speed=1.0, + ) + ) + audio_config = SimpleNamespace(transport_in_sample_rate=16000) + + with patch( + "api.services.pipecat.service_factory.SmallestTTSService" + ) as mock_service: + create_tts_service(user_config, audio_config) + + assert mock_service.call_count == 1 + kwargs = mock_service.call_args.kwargs + assert kwargs["settings"].model == "lightning_v3.1" diff --git a/api/utils/recording_artifacts.py b/api/utils/recording_artifacts.py new file mode 100644 index 00000000..42044cf9 --- /dev/null +++ b/api/utils/recording_artifacts.py @@ -0,0 +1,35 @@ +from typing import Literal + +RecordingTrack = Literal["mixed", "user", "bot"] + + +def get_recording_storage_key(extra: dict | None, track: RecordingTrack) -> str | None: + recordings = (extra or {}).get("recordings", {}) + if not isinstance(recordings, dict): + return None + + artifact = recordings.get(track) + if isinstance(artifact, str): + return artifact + if isinstance(artifact, dict): + storage_key = artifact.get("storage_key") + return storage_key if isinstance(storage_key, str) else None + return None + + +def get_recording_storage_backend( + extra: dict | None, track: RecordingTrack +) -> str | None: + recordings = (extra or {}).get("recordings", {}) + if not isinstance(recordings, dict): + return None + + artifact = recordings.get(track) + if isinstance(artifact, dict): + storage_backend = artifact.get("storage_backend") + return storage_backend if isinstance(storage_backend, str) else None + return None + + +def has_recording_track(extra: dict | None, track: RecordingTrack) -> bool: + return bool(get_recording_storage_key(extra, track)) diff --git a/docs/api-reference/openapi.json b/docs/api-reference/openapi.json index f23112c3..b0372801 100644 --- a/docs/api-reference/openapi.json +++ b/docs/api-reference/openapi.json @@ -1 +1 @@ -{"openapi":"3.1.0","info":{"title":"Dograh API","description":"API for the Dograh app","version":"1.0.0"},"servers":[{"url":"https://app.dograh.com","description":"Production"},{"url":"http://localhost:8000","description":"Local development"}],"paths":{"/api/v1/telephony/initiate-call":{"post":{"tags":["main"],"summary":"Initiate Call","description":"Initiate a call using the configured telephony provider from web browser. This is\nsupposed to be a test call method for the draft version of the agent.","operationId":"initiate_call_api_v1_telephony_initiate_call_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitiateCallRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"test_phone_call","x-sdk-description":"Place a test call from a workflow to a phone number."}},"/api/v1/telephony/inbound/run":{"post":{"tags":["main"],"summary":"Handle Inbound Run","description":"Workflow-agnostic inbound dispatcher.\n\nAll providers can point a single webhook at this endpoint instead of one\nURL per workflow. The dispatcher resolves the org from the webhook's\naccount_id and the workflow from the called number's\n``inbound_workflow_id``. This is what ``configure_inbound`` writes into\neach provider's resource so per-workflow webhook bookkeeping disappears.\n\nProvider-specific signature/timestamp headers are not enumerated here \u2014\neach provider's ``verify_inbound_signature`` reads its own headers from\nthe dict, so adding a new provider doesn't require changes to this route.","operationId":"handle_inbound_run_api_v1_telephony_inbound_run_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"}}}},"/api/v1/telephony/inbound/fallback":{"post":{"tags":["main"],"summary":"Handle Inbound Fallback","description":"Fallback endpoint that returns audio message when calls cannot be processed.","operationId":"handle_inbound_fallback_api_v1_telephony_inbound_fallback_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"}}}},"/api/v1/telephony/inbound/{workflow_id}":{"post":{"tags":["main"],"summary":"Handle Inbound Telephony","description":"[LEGACY] Per-workflow inbound webhook.\n\nSuperseded by ``POST /inbound/run``, which resolves the workflow from\nthe called number's ``inbound_workflow_id`` and lets a single webhook\nURL serve every workflow in the org. New integrations should point\ntheir provider at ``/inbound/run``; this route is kept only for\nexisting provider configurations that still encode ``workflow_id``\nin the URL.","operationId":"handle_inbound_telephony_api_v1_telephony_inbound__workflow_id__post","deprecated":true,"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/transfer-result/{transfer_id}":{"post":{"tags":["main"],"summary":"Complete Transfer Function Call","description":"Webhook endpoint to complete the function call with transfer result.\n\nCalled by Twilio's StatusCallback when the transfer call status changes.","operationId":"complete_transfer_function_call_api_v1_telephony_transfer_result__transfer_id__post","parameters":[{"name":"transfer_id","in":"path","required":true,"schema":{"type":"string","title":"Transfer Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/cloudonix/status-callback/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Cloudonix Status Callback","description":"Handle Cloudonix-specific status callbacks.\n\nCloudonix sends call status updates to the callback URL specified during call initiation.","operationId":"handle_cloudonix_status_callback_api_v1_telephony_cloudonix_status_callback__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/cloudonix/cdr":{"post":{"tags":["main"],"summary":"Handle Cloudonix Cdr","description":"Handle Cloudonix CDR (Call Detail Record) webhooks.\n\nCloudonix sends CDR records when calls complete. The CDR contains:\n- domain: Used to identify the organization\n- call_id: Used to find the workflow run\n- disposition: Call termination status (ANSWER, BUSY, CANCEL, FAILED, CONGESTION, NOANSWER)\n- duration/billsec: Call duration information","operationId":"handle_cloudonix_cdr_api_v1_telephony_cloudonix_cdr_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"}}}},"/api/v1/telephony/plivo/hangup-callback/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Plivo Hangup Callback","description":"Handle Plivo hangup callbacks.","operationId":"handle_plivo_hangup_callback_api_v1_telephony_plivo_hangup_callback__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/plivo/ring-callback/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Plivo Ring Callback","description":"Handle Plivo ring callbacks.","operationId":"handle_plivo_ring_callback_api_v1_telephony_plivo_ring_callback__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/telnyx/events/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Telnyx Events","description":"Handle Telnyx Call Control webhook events.\n\nTelnyx sends all call lifecycle events (call.initiated, call.answered,\ncall.hangup, streaming.started, streaming.stopped) as JSON POST requests.","operationId":"handle_telnyx_events_api_v1_telephony_telnyx_events__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/telnyx/transfer-result/{transfer_id}":{"post":{"tags":["main"],"summary":"Handle Telnyx Transfer Result","description":"Handle Telnyx Call Control events for the transfer destination leg.\n\nThe destination leg is dialed by :meth:`TelnyxProvider.transfer_call` with\nthis URL as ``webhook_url``. Telnyx sends every event for that leg here.\nOutcomes:\n\n- ``call.answered``: seed a conference with the destination's live\n ``call_control_id``, stamp ``conference_id`` onto the TransferContext,\n and publish ``DESTINATION_ANSWERED`` so ``transfer_call_handler`` can\n end the pipeline. ``TelnyxConferenceStrategy`` then joins the caller\n into this conference at pipeline teardown.\n- ``call.hangup`` pre-answer (no ``conference_id`` on the context):\n publish ``TRANSFER_FAILED`` so the LLM can recover.\n- ``call.hangup`` post-answer (``conference_id`` set): the destination\n left a bridged conference; hang up the caller's leg to tear down the\n empty bridge (Telnyx's create_conference doesn't accept\n ``end_conference_on_exit`` on the seed leg).\n\nEvent references:\n - call.answered: https://developers.telnyx.com/api-reference/callbacks/call-answered\n - call.hangup: https://developers.telnyx.com/api-reference/callbacks/call-hangup","operationId":"handle_telnyx_transfer_result_api_v1_telephony_telnyx_transfer_result__transfer_id__post","parameters":[{"name":"transfer_id","in":"path","required":true,"schema":{"type":"string","title":"Transfer Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/twilio/status-callback/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Twilio Status Callback","description":"Handle Twilio-specific status callbacks.","operationId":"handle_twilio_status_callback_api_v1_telephony_twilio_status_callback__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/vobiz/hangup-callback/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Vobiz Hangup Callback","description":"Handle Vobiz hangup callback (sent when call ends).\n\nVobiz sends callbacks to hangup_url when the call terminates.\nThis includes call duration, status, and billing information.","operationId":"handle_vobiz_hangup_callback_api_v1_telephony_vobiz_hangup_callback__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/vobiz/ring-callback/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Vobiz Ring Callback","description":"Handle Vobiz ring callback (sent when call starts ringing).\n\nVobiz can send callbacks to ring_url when the call starts ringing.\nThis is optional and used for tracking ringing status.","operationId":"handle_vobiz_ring_callback_api_v1_telephony_vobiz_ring_callback__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/vobiz/hangup-callback/workflow/{workflow_id}":{"post":{"tags":["main"],"summary":"Handle Vobiz Hangup Callback By Workflow","description":"Handle Vobiz hangup callback with workflow_id - finds workflow run by call_id.","operationId":"handle_vobiz_hangup_callback_by_workflow_api_v1_telephony_vobiz_hangup_callback_workflow__workflow_id__post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/vonage/events/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Vonage Events","description":"Handle Vonage-specific event webhooks.\n\nVonage sends all call events to a single endpoint.\nEvents include: started, ringing, answered, complete, failed, etc.","operationId":"handle_vonage_events_api_v1_telephony_vonage_events__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/superuser/impersonate":{"post":{"tags":["main","superuser"],"summary":"Impersonate","description":"Impersonate a user as a super-admin.\nInternally, Stack Auth requires the **provider user ID** (a UUID-ish string)\nto create an impersonation session.","operationId":"impersonate_api_v1_superuser_impersonate_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImpersonateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImpersonateResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/superuser/workflow-runs":{"get":{"tags":["main","superuser"],"summary":"Get Workflow Runs","description":"Get paginated list of all workflow runs with organization information.\nRequires superuser privileges.\n\nFilters should be provided as a JSON-encoded array of filter criteria.\nExample: [{\"field\": \"id\", \"type\": \"number\", \"value\": {\"value\": 680}}]","operationId":"get_workflow_runs_api_v1_superuser_workflow_runs_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number (starts from 1)","default":1,"title":"Page"},"description":"Page number (starts from 1)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of items per page","default":50,"title":"Limit"},"description":"Number of items per page"},{"name":"filters","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-encoded filter criteria","title":"Filters"},"description":"JSON-encoded filter criteria"},{"name":"sort_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by (e.g., 'duration', 'created_at')","title":"Sort By"},"description":"Field to sort by (e.g., 'duration', 'created_at')"},{"name":"sort_order","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Sort order ('asc' or 'desc')","default":"desc","title":"Sort Order"},"description":"Sort order ('asc' or 'desc')"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuperuserWorkflowRunsListResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/validate":{"post":{"tags":["main"],"summary":"Validate Workflow","description":"Validate all nodes in a workflow to ensure they have required fields.\n\nArgs:\n workflow_id: The ID of the workflow to validate\n user: The authenticated user\n\nReturns:\n Object indicating if workflow is valid and any invalid nodes/edges","operationId":"validate_workflow_api_v1_workflow__workflow_id__validate_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateWorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/create/definition":{"post":{"tags":["main"],"summary":"Create Workflow","description":"Create a new workflow from the client\n\nArgs:\n request: The create workflow request\n user: The user to create the workflow for","operationId":"create_workflow_api_v1_workflow_create_definition_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkflowRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"create_workflow","x-sdk-description":"Create a new workflow from a workflow definition."}},"/api/v1/workflow/create/template":{"post":{"tags":["main"],"summary":"Create Workflow From Template","description":"Create a new workflow from a natural language template request.\n\nThis endpoint:\n1. Uses mps_service_key_client to call MPS workflow API\n2. Passes organization ID (authenticated mode) or created_by (OSS mode)\n3. Creates the workflow in the database\n\nArgs:\n request: The template creation request with call_type, use_case, and activity_description\n user: The authenticated user\n\nReturns:\n The created workflow\n\nRaises:\n HTTPException: If MPS API call fails","operationId":"create_workflow_from_template_api_v1_workflow_create_template_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkflowTemplateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/count":{"get":{"tags":["main"],"summary":"Get Workflow Count","description":"Get workflow counts for the authenticated user's organization.\n\nThis is a lightweight endpoint for checking if the user has workflows,\nuseful for redirect logic without fetching full workflow data.","operationId":"get_workflow_count_api_v1_workflow_count_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowCountResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/fetch":{"get":{"tags":["main"],"summary":"Get Workflows","description":"Get all workflows for the authenticated user's organization.\n\nReturns a lightweight response with only essential fields for listing.\nUse GET /workflow/fetch/{workflow_id} to get full workflow details.","operationId":"get_workflows_api_v1_workflow_fetch_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status - can be single value (active/archived) or comma-separated (active,archived)","title":"Status"},"description":"Filter by status - can be single value (active/archived) or comma-separated (active,archived)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowListResponse"},"title":"Response Get Workflows Api V1 Workflow Fetch Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"list_workflows","x-sdk-description":"List all workflows in the authenticated organization."}},"/api/v1/workflow/fetch/{workflow_id}":{"get":{"tags":["main"],"summary":"Get Workflow","description":"Get a single workflow by ID.\n\nIf a draft version exists, returns the draft content for editing.\nOtherwise returns the published version's content.","operationId":"get_workflow_api_v1_workflow_fetch__workflow_id__get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"get_workflow","x-sdk-description":"Get a single workflow by ID (returns draft if one exists, else published)."}},"/api/v1/workflow/{workflow_id}/versions":{"get":{"tags":["main"],"summary":"Get Workflow Versions","description":"List versions for a workflow, newest first.\n\nPass `limit`/`offset` to page through long histories. With no `limit`,\nreturns every version (legacy behavior).","operationId":"get_workflow_versions_api_v1_workflow__workflow_id__versions_get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":100,"minimum":1},{"type":"null"}],"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowVersionResponse"},"title":"Response Get Workflow Versions Api V1 Workflow Workflow Id Versions Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/publish":{"post":{"tags":["main"],"summary":"Publish Workflow","description":"Publish the current draft version of a workflow.\n\nDrafts are allowed to be incomplete (so the editor can save mid-edit),\nbut a published version is what runtime executes \u2014 so this is the gate\nwhere the full DTO + graph + trigger-conflict checks must pass.","operationId":"publish_workflow_api_v1_workflow__workflow_id__publish_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/create-draft":{"post":{"tags":["main"],"summary":"Create Workflow Draft","description":"Create a draft version from the current published version.\n\nIf a draft already exists, returns the existing draft.","operationId":"create_workflow_draft_api_v1_workflow__workflow_id__create_draft_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowVersionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/summary":{"get":{"tags":["main"],"summary":"Get Workflows Summary","description":"Get minimal workflow information (id and name only) for all workflows","operationId":"get_workflows_summary_api_v1_workflow_summary_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status (e.g. 'active' or 'archived'). Omit to return all.","title":"Status"},"description":"Filter by status (e.g. 'active' or 'archived'). Omit to return all."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowSummaryResponse"},"title":"Response Get Workflows Summary Api V1 Workflow Summary Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/status":{"put":{"tags":["main"],"summary":"Update Workflow Status","description":"Update the status of a workflow (e.g., archive/unarchive).\n\nArgs:\n workflow_id: The ID of the workflow to update\n request: The status update request\n\nReturns:\n The updated workflow","operationId":"update_workflow_status_api_v1_workflow__workflow_id__status_put","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkflowStatusRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/folder":{"put":{"tags":["main"],"summary":"Move Workflow To Folder","description":"Move a workflow into a folder, or to \"Uncategorized\" (folder_id=null).\n\nValidates that the target folder belongs to the caller's organization \u2014\nthe FK alone proves the folder exists, not that the caller may use it.","operationId":"move_workflow_to_folder_api_v1_workflow__workflow_id__folder_put","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveWorkflowToFolderRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowListResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}":{"put":{"tags":["main"],"summary":"Update Workflow","description":"Update an existing workflow.\n\nArgs:\n workflow_id: The ID of the workflow to update\n request: The update request containing the new name and workflow definition\n\nReturns:\n The updated workflow\n\nRaises:\n HTTPException: If the workflow is not found or if there's a database error","operationId":"update_workflow_api_v1_workflow__workflow_id__put","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkflowRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"update_workflow","x-sdk-description":"Update a workflow's name and/or definition. Saves as a new draft."}},"/api/v1/workflow/{workflow_id}/duplicate":{"post":{"tags":["main"],"summary":"Duplicate Workflow Endpoint","description":"Duplicate a workflow including its definition, configuration, recordings, and triggers.","operationId":"duplicate_workflow_endpoint_api_v1_workflow__workflow_id__duplicate_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/runs":{"post":{"tags":["main"],"summary":"Create Workflow Run","description":"Create a new workflow run when the user decides to execute the workflow via chat or voice\n\nArgs:\n workflow_id: The ID of the workflow to run\n request: The create workflow run request\n user: The user to create the workflow run for","operationId":"create_workflow_run_api_v1_workflow__workflow_id__runs_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkflowRunRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkflowRunResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["main"],"summary":"Get Workflow Runs","description":"Get workflow runs with optional filtering and sorting.\n\nFilters should be provided as a JSON-encoded array of filter criteria.\nExample: [{\"attribute\": \"dateRange\", \"value\": {\"from\": \"2024-01-01\", \"to\": \"2024-01-31\"}}]","operationId":"get_workflow_runs_api_v1_workflow__workflow_id__runs_get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"filters","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-encoded filter criteria","title":"Filters"},"description":"JSON-encoded filter criteria"},{"name":"sort_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by (e.g., 'duration', 'created_at')","title":"Sort By"},"description":"Field to sort by (e.g., 'duration', 'created_at')"},{"name":"sort_order","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Sort order ('asc' or 'desc')","default":"desc","title":"Sort Order"},"description":"Sort order ('asc' or 'desc')"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/runs/{run_id}":{"get":{"tags":["main"],"summary":"Get Workflow Run","operationId":"get_workflow_run_api_v1_workflow__workflow_id__runs__run_id__get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"integer","title":"Run Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/report":{"get":{"tags":["main"],"summary":"Download Workflow Report","description":"Download a CSV report of completed runs for a workflow.","operationId":"download_workflow_report_api_v1_workflow__workflow_id__report_get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Filter runs created on or after this datetime (ISO 8601)","title":"Start Date"},"description":"Filter runs created on or after this datetime (ISO 8601)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Filter runs created on or before this datetime (ISO 8601)","title":"End Date"},"description":"Filter runs created on or before this datetime (ISO 8601)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/templates":{"get":{"tags":["main"],"summary":"Get Workflow Templates","description":"Get all available workflow templates.\n\nReturns:\n List of workflow templates","operationId":"get_workflow_templates_api_v1_workflow_templates_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/WorkflowTemplateResponse"},"type":"array","title":"Response Get Workflow Templates Api V1 Workflow Templates Get"}}}},"404":{"description":"Not found"}}}},"/api/v1/workflow/templates/duplicate":{"post":{"tags":["main"],"summary":"Duplicate Workflow Template","description":"Duplicate a workflow template to create a new workflow for the user.\n\nArgs:\n request: The duplicate template request\n user: The authenticated user\n\nReturns:\n The newly created workflow","operationId":"duplicate_workflow_template_api_v1_workflow_templates_duplicate_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DuplicateTemplateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/ambient-noise/upload-url":{"post":{"tags":["main"],"summary":"Get a presigned URL to upload a custom ambient noise audio file","description":"Generate a presigned PUT URL for uploading a custom ambient noise file.","operationId":"get_ambient_noise_upload_url_api_v1_workflow_ambient_noise_upload_url_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AmbientNoiseUploadRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AmbientNoiseUploadResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/text-chat/sessions":{"post":{"tags":["main","workflow-text-chat"],"summary":"Create Text Chat Session","operationId":"create_text_chat_session_api_v1_workflow__workflow_id__text_chat_sessions_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTextChatSessionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunTextSessionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/text-chat/sessions/{run_id}":{"get":{"tags":["main","workflow-text-chat"],"summary":"Get Text Chat Session","operationId":"get_text_chat_session_api_v1_workflow__workflow_id__text_chat_sessions__run_id__get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"integer","title":"Run Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunTextSessionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/text-chat/sessions/{run_id}/messages":{"post":{"tags":["main","workflow-text-chat"],"summary":"Append Text Chat Message","operationId":"append_text_chat_message_api_v1_workflow__workflow_id__text_chat_sessions__run_id__messages_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"integer","title":"Run Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppendTextChatMessageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunTextSessionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/text-chat/sessions/{run_id}/rewind":{"post":{"tags":["main","workflow-text-chat"],"summary":"Rewind Text Chat Session","operationId":"rewind_text_chat_session_api_v1_workflow__workflow_id__text_chat_sessions__run_id__rewind_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"integer","title":"Run Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewindTextChatSessionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunTextSessionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/configurations/defaults":{"get":{"tags":["main"],"summary":"Get Default Configurations","operationId":"get_default_configurations_api_v1_user_configurations_defaults_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DefaultConfigurationsResponse"}}}},"404":{"description":"Not found"}}}},"/api/v1/user/auth/user":{"get":{"tags":["main"],"summary":"Get Auth User","operationId":"get_auth_user_api_v1_user_auth_user_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthUserResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/configurations/user":{"get":{"tags":["main"],"summary":"Get User Configurations","operationId":"get_user_configurations_api_v1_user_configurations_user_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConfigurationRequestResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main"],"summary":"Update User Configurations","operationId":"update_user_configurations_api_v1_user_configurations_user_put","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConfigurationRequestResponseSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConfigurationRequestResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/onboarding-state":{"get":{"tags":["main"],"summary":"Get User Onboarding State","operationId":"get_user_onboarding_state_api_v1_user_onboarding_state_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingState"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main"],"summary":"Update User Onboarding State","operationId":"update_user_onboarding_state_api_v1_user_onboarding_state_put","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStateUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingState"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/configurations/user/validate":{"get":{"tags":["main"],"summary":"Validate User Configurations","operationId":"validate_user_configurations_api_v1_user_configurations_user_validate_get","parameters":[{"name":"validity_ttl_seconds","in":"query","required":false,"schema":{"type":"integer","maximum":86400,"minimum":0,"default":60,"title":"Validity Ttl Seconds"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyStatusResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/api-keys":{"get":{"tags":["main"],"summary":"Get Api Keys","description":"Get all API keys for the user's selected organization.","operationId":"get_api_keys_api_v1_user_api_keys_get","parameters":[{"name":"include_archived","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Archived"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/APIKeyResponse"},"title":"Response Get Api Keys Api V1 User Api Keys Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main"],"summary":"Create Api Key","description":"Create a new API key for the user's selected organization.","operationId":"create_api_key_api_v1_user_api_keys_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/api-keys/{api_key_id}":{"delete":{"tags":["main"],"summary":"Archive Api Key","description":"Archive an API key (soft delete).","operationId":"archive_api_key_api_v1_user_api_keys__api_key_id__delete","parameters":[{"name":"api_key_id","in":"path","required":true,"schema":{"type":"integer","title":"Api Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Archive Api Key Api V1 User Api Keys Api Key Id Delete"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/api-keys/{api_key_id}/reactivate":{"put":{"tags":["main"],"summary":"Reactivate Api Key","description":"Reactivate an archived API key.","operationId":"reactivate_api_key_api_v1_user_api_keys__api_key_id__reactivate_put","parameters":[{"name":"api_key_id","in":"path","required":true,"schema":{"type":"integer","title":"Api Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Reactivate Api Key Api V1 User Api Keys Api Key Id Reactivate Put"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/configurations/voices/{provider}":{"get":{"tags":["main"],"summary":"Get Voices","description":"Get available voices for a TTS provider.","operationId":"get_voices_api_v1_user_configurations_voices__provider__get","parameters":[{"name":"provider","in":"path","required":true,"schema":{"enum":["elevenlabs","deepgram","sarvam","cartesia","dograh","rime"],"type":"string","title":"Provider"}},{"name":"model","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"}},{"name":"language","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoicesResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/create":{"post":{"tags":["main"],"summary":"Create Campaign","description":"Create a new campaign","operationId":"create_campaign_api_v1_campaign_create_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCampaignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/":{"get":{"tags":["main"],"summary":"Get Campaigns","description":"Get campaigns for user's organization","operationId":"get_campaigns_api_v1_campaign__get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}":{"get":{"tags":["main"],"summary":"Get Campaign","description":"Get campaign details","operationId":"get_campaign_api_v1_campaign__campaign_id__get","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["main"],"summary":"Update Campaign","description":"Update campaign settings (name, retry config, max concurrency, schedule)","operationId":"update_campaign_api_v1_campaign__campaign_id__patch","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCampaignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/start":{"post":{"tags":["main"],"summary":"Start Campaign","description":"Start campaign execution","operationId":"start_campaign_api_v1_campaign__campaign_id__start_post","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/pause":{"post":{"tags":["main"],"summary":"Pause Campaign","description":"Pause campaign execution","operationId":"pause_campaign_api_v1_campaign__campaign_id__pause_post","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/runs":{"get":{"tags":["main"],"summary":"Get Campaign Runs","description":"Get campaign workflow runs with pagination, filters and sorting","operationId":"get_campaign_runs_api_v1_campaign__campaign_id__runs_get","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"filters","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-encoded filter criteria","title":"Filters"},"description":"JSON-encoded filter criteria"},{"name":"sort_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by (e.g., 'duration', 'created_at')","title":"Sort By"},"description":"Field to sort by (e.g., 'duration', 'created_at')"},{"name":"sort_order","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Sort order ('asc' or 'desc')","default":"desc","title":"Sort Order"},"description":"Sort order ('asc' or 'desc')"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRunsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/redial":{"post":{"tags":["main"],"summary":"Redial Campaign","description":"Create a new campaign that re-dials unique subscribers from a completed\ncampaign whose latest call resulted in voicemail, no-answer, or busy.\n\nThe new campaign is created in 'created' state with queued_runs pre-seeded\nfrom the parent's original initial contexts. A campaign can be redialed at\nmost once.","operationId":"redial_campaign_api_v1_campaign__campaign_id__redial_post","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedialCampaignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/resume":{"post":{"tags":["main"],"summary":"Resume Campaign","description":"Resume a paused campaign","operationId":"resume_campaign_api_v1_campaign__campaign_id__resume_post","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/progress":{"get":{"tags":["main"],"summary":"Get Campaign Progress","description":"Get current campaign progress and statistics","operationId":"get_campaign_progress_api_v1_campaign__campaign_id__progress_get","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignProgressResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/source-download-url":{"get":{"tags":["main"],"summary":"Get Campaign Source Download Url","description":"Get presigned download URL for campaign CSV source file\nValidates that the campaign belongs to the user's organization for security.","operationId":"get_campaign_source_download_url_api_v1_campaign__campaign_id__source_download_url_get","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSourceDownloadResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/report":{"get":{"tags":["main"],"summary":"Download Campaign Report","description":"Download a CSV report of completed campaign runs.","operationId":"download_campaign_report_api_v1_campaign__campaign_id__report_get","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Filter runs created on or after this datetime (ISO 8601)","title":"Start Date"},"description":"Filter runs created on or after this datetime (ISO 8601)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Filter runs created on or before this datetime (ISO 8601)","title":"End Date"},"description":"Filter runs created on or before this datetime (ISO 8601)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/credentials/":{"get":{"tags":["main"],"summary":"List Credentials","description":"List all webhook credentials for the user's organization.\n\nReturns:\n List of credentials (without sensitive data)","operationId":"list_credentials_api_v1_credentials__get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CredentialResponse"},"title":"Response List Credentials Api V1 Credentials Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"list_credentials","x-sdk-description":"List webhook credentials available to the authenticated organization."},"post":{"tags":["main"],"summary":"Create Credential","description":"Create a new webhook credential.\n\nArgs:\n request: The credential creation request\n\nReturns:\n The created credential (without sensitive data)","operationId":"create_credential_api_v1_credentials__post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCredentialRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CredentialResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/credentials/{credential_uuid}":{"get":{"tags":["main"],"summary":"Get Credential","description":"Get a specific webhook credential by UUID.\n\nArgs:\n credential_uuid: The UUID of the credential\n\nReturns:\n The credential (without sensitive data)","operationId":"get_credential_api_v1_credentials__credential_uuid__get","parameters":[{"name":"credential_uuid","in":"path","required":true,"schema":{"type":"string","title":"Credential Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CredentialResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main"],"summary":"Update Credential","description":"Update a webhook credential.\n\nArgs:\n credential_uuid: The UUID of the credential to update\n request: The update request\n\nReturns:\n The updated credential (without sensitive data)","operationId":"update_credential_api_v1_credentials__credential_uuid__put","parameters":[{"name":"credential_uuid","in":"path","required":true,"schema":{"type":"string","title":"Credential Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCredentialRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CredentialResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main"],"summary":"Delete Credential","description":"Delete (soft delete) a webhook credential.\n\nArgs:\n credential_uuid: The UUID of the credential to delete\n\nReturns:\n Success message","operationId":"delete_credential_api_v1_credentials__credential_uuid__delete","parameters":[{"name":"credential_uuid","in":"path","required":true,"schema":{"type":"string","title":"Credential Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Credential Api V1 Credentials Credential Uuid Delete"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/":{"get":{"tags":["main"],"summary":"List Tools","description":"List all tools for the user's organization.\n\nArgs:\n status: Optional filter by status (active, archived, draft)\n category: Optional filter by category (http_api, native, integration)\n\nReturns:\n List of tools","operationId":"list_tools_api_v1_tools__get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ToolResponse"},"title":"Response List Tools Api V1 Tools Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"list_tools","x-sdk-description":"List tools available to the authenticated organization."},"post":{"tags":["main"],"summary":"Create Tool","description":"Create a new tool.\n\nArgs:\n request: The tool creation request\n\nReturns:\n The created tool","operationId":"create_tool_api_v1_tools__post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateToolRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"create_tool","x-sdk-description":"Create a reusable tool for the authenticated organization."}},"/api/v1/tools/{tool_uuid}":{"get":{"tags":["main"],"summary":"Get Tool","description":"Get a specific tool by UUID.\n\nArgs:\n tool_uuid: The UUID of the tool\n\nReturns:\n The tool","operationId":"get_tool_api_v1_tools__tool_uuid__get","parameters":[{"name":"tool_uuid","in":"path","required":true,"schema":{"type":"string","title":"Tool Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main"],"summary":"Update Tool","description":"Update a tool.\n\nArgs:\n tool_uuid: The UUID of the tool to update\n request: The update request\n\nReturns:\n The updated tool","operationId":"update_tool_api_v1_tools__tool_uuid__put","parameters":[{"name":"tool_uuid","in":"path","required":true,"schema":{"type":"string","title":"Tool Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateToolRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main"],"summary":"Delete Tool","description":"Archive (soft delete) a tool.\n\nArgs:\n tool_uuid: The UUID of the tool to delete\n\nReturns:\n Success message","operationId":"delete_tool_api_v1_tools__tool_uuid__delete","parameters":[{"name":"tool_uuid","in":"path","required":true,"schema":{"type":"string","title":"Tool Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Tool Api V1 Tools Tool Uuid Delete"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/{tool_uuid}/mcp/refresh":{"post":{"tags":["main"],"summary":"Refresh Mcp Tools","description":"Re-discover an MCP tool's server catalog and overwrite the cached\n``definition.config.discovered_tools``. Server down \u2192 200 with error\n(cache not overwritten on transient failure).","operationId":"refresh_mcp_tools_api_v1_tools__tool_uuid__mcp_refresh_post","parameters":[{"name":"tool_uuid","in":"path","required":true,"schema":{"type":"string","title":"Tool Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpRefreshResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/{tool_uuid}/unarchive":{"post":{"tags":["main"],"summary":"Unarchive Tool","description":"Unarchive a tool (restore from archived state).\n\nArgs:\n tool_uuid: The UUID of the tool to unarchive\n\nReturns:\n The unarchived tool","operationId":"unarchive_tool_api_v1_tools__tool_uuid__unarchive_post","parameters":[{"name":"tool_uuid","in":"path","required":true,"schema":{"type":"string","title":"Tool Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/context":{"get":{"tags":["main","organizations"],"summary":"Get Current Organization Context","description":"Return organization-scoped configuration signals owned by Dograh.","operationId":"get_current_organization_context_api_v1_organizations_context_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationContextResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-providers/metadata":{"get":{"tags":["main","organizations"],"summary":"Get Telephony Providers Metadata","description":"Return the list of available telephony providers and their form schemas.\n\nThe UI uses this to render the configuration form generically instead of\nhard-coding fields per provider. Adding a new provider only requires\ndeclaring its ui_metadata in providers//__init__.py.","operationId":"get_telephony_providers_metadata_api_v1_organizations_telephony_providers_metadata_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyProvidersMetadataResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-config-warnings":{"get":{"tags":["main","organizations"],"summary":"Get Telephony Config Warnings","description":"Return aggregated warning counts for the current org's telephony configs.\n\nToday this surfaces only Telnyx configs missing ``webhook_public_key``;\nadditional warning types should be added as new fields on the response.","operationId":"get_telephony_config_warnings_api_v1_organizations_telephony_config_warnings_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigWarningsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/model-configurations/v2/defaults":{"get":{"tags":["main","organizations"],"summary":"Get Model Configuration V2 Defaults","operationId":"get_model_configuration_v2_defaults_api_v1_organizations_model_configurations_v2_defaults_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/model-configurations/v2":{"get":{"tags":["main","organizations"],"summary":"Get Model Configuration V2","operationId":"get_model_configuration_v2_api_v1_organizations_model_configurations_v2_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationAIModelConfigurationResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main","organizations"],"summary":"Save Model Configuration V2","operationId":"save_model_configuration_v2_api_v1_organizations_model_configurations_v2_put","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationAIModelConfigurationV2"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationAIModelConfigurationResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/model-configurations/v2/migration-preview":{"get":{"tags":["main","organizations"],"summary":"Preview Model Configuration V2 Migration","operationId":"preview_model_configuration_v2_migration_api_v1_organizations_model_configurations_v2_migration_preview_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/model-configurations/v2/migrate":{"post":{"tags":["main","organizations"],"summary":"Migrate Model Configuration V2","operationId":"migrate_model_configuration_v2_api_v1_organizations_model_configurations_v2_migrate_post","parameters":[{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationAIModelConfigurationResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/preferences":{"get":{"tags":["main","organizations"],"summary":"Get Preferences","operationId":"get_preferences_api_v1_organizations_preferences_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationPreferences"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main","organizations"],"summary":"Save Preferences","operationId":"save_preferences_api_v1_organizations_preferences_put","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationPreferences"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationPreferences"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-configs":{"get":{"tags":["main","organizations"],"summary":"List Telephony Configurations","description":"List the org's telephony configurations with phone-number counts.","operationId":"list_telephony_configurations_api_v1_organizations_telephony_configs_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationListResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main","organizations"],"summary":"Create Telephony Configuration","description":"Create a new telephony configuration for the org.","operationId":"create_telephony_configuration_api_v1_organizations_telephony_configs_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationCreateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationDetail"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-configs/{config_id}":{"get":{"tags":["main","organizations"],"summary":"Get Telephony Configuration By Id","operationId":"get_telephony_configuration_by_id_api_v1_organizations_telephony_configs__config_id__get","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationDetail"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main","organizations"],"summary":"Update Telephony Configuration","operationId":"update_telephony_configuration_api_v1_organizations_telephony_configs__config_id__put","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationDetail"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main","organizations"],"summary":"Delete Telephony Configuration","operationId":"delete_telephony_configuration_api_v1_organizations_telephony_configs__config_id__delete","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-configs/{config_id}/set-default-outbound":{"post":{"tags":["main","organizations"],"summary":"Set Default Outbound","operationId":"set_default_outbound_api_v1_organizations_telephony_configs__config_id__set_default_outbound_post","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationDetail"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-configs/{config_id}/phone-numbers":{"get":{"tags":["main","organizations"],"summary":"List Phone Numbers","operationId":"list_phone_numbers_api_v1_organizations_telephony_configs__config_id__phone_numbers_get","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberListResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main","organizations"],"summary":"Create Phone Number","operationId":"create_phone_number_api_v1_organizations_telephony_configs__config_id__phone_numbers_post","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberCreateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-configs/{config_id}/phone-numbers/{phone_number_id}":{"get":{"tags":["main","organizations"],"summary":"Get Phone Number","operationId":"get_phone_number_api_v1_organizations_telephony_configs__config_id__phone_numbers__phone_number_id__get","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"phone_number_id","in":"path","required":true,"schema":{"type":"integer","title":"Phone Number Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main","organizations"],"summary":"Update Phone Number","operationId":"update_phone_number_api_v1_organizations_telephony_configs__config_id__phone_numbers__phone_number_id__put","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"phone_number_id","in":"path","required":true,"schema":{"type":"integer","title":"Phone Number Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main","organizations"],"summary":"Delete Phone Number","operationId":"delete_phone_number_api_v1_organizations_telephony_configs__config_id__phone_numbers__phone_number_id__delete","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"phone_number_id","in":"path","required":true,"schema":{"type":"integer","title":"Phone Number Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-configs/{config_id}/phone-numbers/{phone_number_id}/set-default-caller":{"post":{"tags":["main","organizations"],"summary":"Set Default Caller Id","operationId":"set_default_caller_id_api_v1_organizations_telephony_configs__config_id__phone_numbers__phone_number_id__set_default_caller_post","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"phone_number_id","in":"path","required":true,"schema":{"type":"integer","title":"Phone Number Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-config":{"get":{"tags":["main","organizations"],"summary":"Get Telephony Configuration","description":"Legacy: returns the org's default config in the original per-provider\nresponse shape so the existing single-form UI keeps working. Prefer the\nmulti-config endpoints (``/telephony-configs``) for new clients.","operationId":"get_telephony_configuration_api_v1_organizations_telephony_config_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main","organizations"],"summary":"Save Telephony Configuration","description":"Legacy: upserts the org's default config (and its phone numbers) in the\noriginal payload shape so existing UI clients keep working. Prefer the\nmulti-config + phone-number endpoints for new clients.","operationId":"save_telephony_configuration_api_v1_organizations_telephony_config_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ARIConfigurationRequest"},{"$ref":"#/components/schemas/CloudonixConfigurationRequest"},{"$ref":"#/components/schemas/PlivoConfigurationRequest"},{"$ref":"#/components/schemas/TelnyxConfigurationRequest"},{"$ref":"#/components/schemas/TwilioConfigurationRequest"},{"$ref":"#/components/schemas/VobizConfigurationRequest"},{"$ref":"#/components/schemas/VonageConfigurationRequest"}],"discriminator":{"propertyName":"provider","mapping":{"ari":"#/components/schemas/ARIConfigurationRequest","cloudonix":"#/components/schemas/CloudonixConfigurationRequest","plivo":"#/components/schemas/PlivoConfigurationRequest","telnyx":"#/components/schemas/TelnyxConfigurationRequest","twilio":"#/components/schemas/TwilioConfigurationRequest","vobiz":"#/components/schemas/VobizConfigurationRequest","vonage":"#/components/schemas/VonageConfigurationRequest"}},"title":"Request"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/langfuse-credentials":{"get":{"tags":["main","organizations"],"summary":"Get Langfuse Credentials","description":"Get Langfuse credentials for the user's organization with masked sensitive fields.","operationId":"get_langfuse_credentials_api_v1_organizations_langfuse_credentials_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LangfuseCredentialsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main","organizations"],"summary":"Save Langfuse Credentials","description":"Save Langfuse credentials for the user's organization.","operationId":"save_langfuse_credentials_api_v1_organizations_langfuse_credentials_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LangfuseCredentialsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main","organizations"],"summary":"Delete Langfuse Credentials","description":"Delete Langfuse credentials for the user's organization.","operationId":"delete_langfuse_credentials_api_v1_organizations_langfuse_credentials_delete","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/campaign-defaults":{"get":{"tags":["main","organizations"],"summary":"Get Campaign Defaults","description":"Get campaign limits for the user's organization.\n\nReturns the organization's concurrent call limit and default retry configuration.","operationId":"get_campaign_defaults_api_v1_organizations_campaign_defaults_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignDefaultsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/s3/signed-url":{"get":{"tags":["main","s3"],"summary":"Generate a signed S3 URL","description":"Return a short-lived signed URL for a file stored on S3 / MinIO.\n\nAccess Control:\n* Keys that embed an organization ID (``{prefix}/{org_id}/...``) are\n authorized by matching the org_id against the requesting user's\n organization.\n* Legacy keys (``recordings/{run_id}.wav``, ``transcripts/{run_id}.txt``)\n are authorized via the workflow run they belong to.\n* Superusers can request any key.","operationId":"get_signed_url_api_v1_s3_signed_url_get","parameters":[{"name":"key","in":"query","required":true,"schema":{"type":"string","description":"S3 object key","title":"Key"},"description":"S3 object key"},{"name":"expires_in","in":"query","required":false,"schema":{"type":"integer","default":3600,"title":"Expires In"}},{"name":"inline","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Inline"}},{"name":"storage_backend","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Storage backend to use (e.g. 'minio', 's3'). When omitted the backend is inferred from the resource.","title":"Storage Backend"},"description":"Storage backend to use (e.g. 'minio', 's3'). When omitted the backend is inferred from the resource."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/S3SignedUrlResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/s3/file-metadata":{"get":{"tags":["main","s3"],"summary":"Get file metadata for debugging","description":"Get file metadata including creation timestamp for debugging.\n\nAccess Control:\n* Superusers can request any key.\n* Regular users can only request resources belonging to **their** workflow runs.","operationId":"get_file_metadata_api_v1_s3_file_metadata_get","parameters":[{"name":"key","in":"query","required":true,"schema":{"type":"string","description":"S3 object key","title":"Key"},"description":"S3 object key"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileMetadataResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/s3/presigned-upload-url":{"post":{"tags":["main","s3"],"summary":"Generate a presigned URL for direct CSV upload","description":"Generate a presigned PUT URL for direct CSV file upload to S3/MinIO.\n\nThis endpoint enables browser-to-storage uploads without passing through the backend\n\nAccess Control:\n* All authenticated users can upload CSV files scoped to their organization.\n* Files are stored with organization-scoped keys for multi-tenancy.\n\nReturns:\n* upload_url: Presigned URL (valid for 15 minutes) for PUT request\n* file_key: Unique storage key to use as source_id in campaign creation\n* expires_in: URL expiration time in seconds","operationId":"get_presigned_upload_url_api_v1_s3_presigned_upload_url_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignedUploadUrlRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignedUploadUrlResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/service-keys":{"get":{"tags":["main"],"summary":"Get Service Keys","description":"Get all service keys for the user's organization.","operationId":"get_service_keys_api_v1_user_service_keys_get","parameters":[{"name":"include_archived","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Archived"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ServiceKeyResponse"},"title":"Response Get Service Keys Api V1 User Service Keys Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main"],"summary":"Create Service Key","description":"Create a new service key for the user's organization.","operationId":"create_service_key_api_v1_user_service_keys_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateServiceKeyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateServiceKeyResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/service-keys/{service_key_id}":{"delete":{"tags":["main"],"summary":"Archive Service Key","description":"Archive a service key.","operationId":"archive_service_key_api_v1_user_service_keys__service_key_id__delete","parameters":[{"name":"service_key_id","in":"path","required":true,"schema":{"type":"string","title":"Service Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/service-keys/{service_key_id}/reactivate":{"put":{"tags":["main"],"summary":"Reactivate Service Key","description":"Reactivate an archived service key.\n\nNote: This endpoint is provided for API compatibility but service key\nreactivation is not supported by MPS. Once archived, a service key\ncannot be reactivated and a new key must be created instead.","operationId":"reactivate_service_key_api_v1_user_service_keys__service_key_id__reactivate_put","parameters":[{"name":"service_key_id","in":"path","required":true,"schema":{"type":"string","title":"Service Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/usage/current-period":{"get":{"tags":["main"],"summary":"Get Current Period Usage","description":"Get current reporting-period usage for the user's organization.","operationId":"get_current_period_usage_api_v1_organizations_usage_current_period_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentUsageResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/usage/mps-credits":{"get":{"tags":["main"],"summary":"Get Mps Credits","description":"Get aggregated usage and quota from MPS.\n\nOSS users: queries by provider_id (created_by).\nHosted users: queries by organization_id.","operationId":"get_mps_credits_api_v1_organizations_usage_mps_credits_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MPSCreditsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/billing/credits":{"get":{"tags":["main"],"summary":"Get Billing Credits","description":"Return legacy MPS credits or paginated v2 billing ledger details for the org.","operationId":"get_billing_credits_api_v1_organizations_billing_credits_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MPSBillingCreditsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/usage/mps-credits/purchase-url":{"post":{"tags":["main"],"summary":"Create Mps Credit Purchase Url","description":"Create a checkout URL for organizations using Dograh-managed MPS v2.","operationId":"create_mps_credit_purchase_url_api_v1_organizations_usage_mps_credits_purchase_url_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MPSCreditPurchaseUrlResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/usage/runs":{"get":{"tags":["main"],"summary":"Get Usage History","description":"Get paginated workflow runs with usage for the organization.","operationId":"get_usage_history_api_v1_organizations_usage_runs_get","parameters":[{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 date-time string (UTC). Lower bound (inclusive) on `created_at`.","examples":["2026-04-01T00:00:00Z"],"title":"Start Date"},"description":"ISO 8601 date-time string (UTC). Lower bound (inclusive) on `created_at`."},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 date-time string (UTC). Upper bound (inclusive) on `created_at`.","examples":["2026-05-01T00:00:00Z"],"title":"End Date"},"description":"ISO 8601 date-time string (UTC). Upper bound (inclusive) on `created_at`."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"filters","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-encoded array of filter objects. Each object has the shape:\n\n```json\n{ \"attribute\": \"\", \"type\": \"\", \"value\": }\n```\n\nSupported `attribute` / `type` / `value` combinations:\n\n| attribute | type | value shape | matches |\n|-----------------|---------------|----------------------------------------------|------------------------------------------------------|\n| `runId` | `number` | `{ \"value\": 12345 }` | exact run id |\n| `workflowId` | `number` | `{ \"value\": 42 }` | exact agent (workflow) id |\n| `campaignId` | `number` | `{ \"value\": 7 }` | exact campaign id |\n| `callerNumber` | `text` | `{ \"value\": \"415555\" }` | substring match on `initial_context.caller_number` |\n| `calledNumber` | `text` | `{ \"value\": \"9911848\" }` | substring match on `initial_context.called_number` |\n| `dispositionCode` | `multiSelect` | `{ \"codes\": [\"XFER\", \"DNC\"] }` | any of the codes in `gathered_context.mapped_call_disposition` |\n| `duration` | `numberRange` | `{ \"min\": 60, \"max\": 300 }` | call duration (seconds), inclusive bounds |\n\nUnknown attributes and unsupported `type` values are silently ignored.\n\nDate filtering on this endpoint is done via the dedicated `start_date` / `end_date` query params, not via a `dateRange` filter object.\n","examples":["[{\"attribute\":\"callerNumber\",\"type\":\"text\",\"value\":{\"value\":\"415555\"}}]","[{\"attribute\":\"campaignId\",\"type\":\"number\",\"value\":{\"value\":7}},{\"attribute\":\"duration\",\"type\":\"numberRange\",\"value\":{\"min\":60,\"max\":300}}]","[{\"attribute\":\"dispositionCode\",\"type\":\"multiSelect\",\"value\":{\"codes\":[\"XFER\",\"DNC\"]}}]"],"title":"Filters"},"description":"JSON-encoded array of filter objects. Each object has the shape:\n\n```json\n{ \"attribute\": \"\", \"type\": \"\", \"value\": }\n```\n\nSupported `attribute` / `type` / `value` combinations:\n\n| attribute | type | value shape | matches |\n|-----------------|---------------|----------------------------------------------|------------------------------------------------------|\n| `runId` | `number` | `{ \"value\": 12345 }` | exact run id |\n| `workflowId` | `number` | `{ \"value\": 42 }` | exact agent (workflow) id |\n| `campaignId` | `number` | `{ \"value\": 7 }` | exact campaign id |\n| `callerNumber` | `text` | `{ \"value\": \"415555\" }` | substring match on `initial_context.caller_number` |\n| `calledNumber` | `text` | `{ \"value\": \"9911848\" }` | substring match on `initial_context.called_number` |\n| `dispositionCode` | `multiSelect` | `{ \"codes\": [\"XFER\", \"DNC\"] }` | any of the codes in `gathered_context.mapped_call_disposition` |\n| `duration` | `numberRange` | `{ \"min\": 60, \"max\": 300 }` | call duration (seconds), inclusive bounds |\n\nUnknown attributes and unsupported `type` values are silently ignored.\n\nDate filtering on this endpoint is done via the dedicated `start_date` / `end_date` query params, not via a `dateRange` filter object.\n"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageHistoryResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/usage/runs/report":{"get":{"tags":["main"],"summary":"Download Usage Runs Report","description":"Download a CSV of runs matching the same filters as `/usage/runs`.","operationId":"download_usage_runs_report_api_v1_organizations_usage_runs_report_get","parameters":[{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 date-time string (UTC). Lower bound (inclusive) on `created_at`.","title":"Start Date"},"description":"ISO 8601 date-time string (UTC). Lower bound (inclusive) on `created_at`."},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 date-time string (UTC). Upper bound (inclusive) on `created_at`.","title":"End Date"},"description":"ISO 8601 date-time string (UTC). Upper bound (inclusive) on `created_at`."},{"name":"filters","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-encoded array of filter objects. Each object has the shape:\n\n```json\n{ \"attribute\": \"\", \"type\": \"\", \"value\": }\n```\n\nSupported `attribute` / `type` / `value` combinations:\n\n| attribute | type | value shape | matches |\n|-----------------|---------------|----------------------------------------------|------------------------------------------------------|\n| `runId` | `number` | `{ \"value\": 12345 }` | exact run id |\n| `workflowId` | `number` | `{ \"value\": 42 }` | exact agent (workflow) id |\n| `campaignId` | `number` | `{ \"value\": 7 }` | exact campaign id |\n| `callerNumber` | `text` | `{ \"value\": \"415555\" }` | substring match on `initial_context.caller_number` |\n| `calledNumber` | `text` | `{ \"value\": \"9911848\" }` | substring match on `initial_context.called_number` |\n| `dispositionCode` | `multiSelect` | `{ \"codes\": [\"XFER\", \"DNC\"] }` | any of the codes in `gathered_context.mapped_call_disposition` |\n| `duration` | `numberRange` | `{ \"min\": 60, \"max\": 300 }` | call duration (seconds), inclusive bounds |\n\nUnknown attributes and unsupported `type` values are silently ignored.\n\nDate filtering on this endpoint is done via the dedicated `start_date` / `end_date` query params, not via a `dateRange` filter object.\n","title":"Filters"},"description":"JSON-encoded array of filter objects. Each object has the shape:\n\n```json\n{ \"attribute\": \"\", \"type\": \"\", \"value\": }\n```\n\nSupported `attribute` / `type` / `value` combinations:\n\n| attribute | type | value shape | matches |\n|-----------------|---------------|----------------------------------------------|------------------------------------------------------|\n| `runId` | `number` | `{ \"value\": 12345 }` | exact run id |\n| `workflowId` | `number` | `{ \"value\": 42 }` | exact agent (workflow) id |\n| `campaignId` | `number` | `{ \"value\": 7 }` | exact campaign id |\n| `callerNumber` | `text` | `{ \"value\": \"415555\" }` | substring match on `initial_context.caller_number` |\n| `calledNumber` | `text` | `{ \"value\": \"9911848\" }` | substring match on `initial_context.called_number` |\n| `dispositionCode` | `multiSelect` | `{ \"codes\": [\"XFER\", \"DNC\"] }` | any of the codes in `gathered_context.mapped_call_disposition` |\n| `duration` | `numberRange` | `{ \"min\": 60, \"max\": 300 }` | call duration (seconds), inclusive bounds |\n\nUnknown attributes and unsupported `type` values are silently ignored.\n\nDate filtering on this endpoint is done via the dedicated `start_date` / `end_date` query params, not via a `dateRange` filter object.\n"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/usage/daily-breakdown":{"get":{"tags":["main"],"summary":"Get Daily Usage Breakdown","description":"Get daily usage breakdown for the last N days. Only available for organizations with pricing.","operationId":"get_daily_usage_breakdown_api_v1_organizations_usage_daily_breakdown_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":30,"minimum":1,"description":"Number of days to include","default":7,"title":"Days"},"description":"Number of days to include"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DailyUsageBreakdownResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/reports/daily":{"get":{"tags":["main"],"summary":"Get Daily Report","description":"Get daily report for the specified date and timezone.\nIf workflow_id is provided, filters results to that specific workflow.\nIf workflow_id is None, includes all workflows for the organization.","operationId":"get_daily_report_api_v1_organizations_reports_daily_get","parameters":[{"name":"date","in":"query","required":true,"schema":{"type":"string","description":"Date in YYYY-MM-DD format","title":"Date"},"description":"Date in YYYY-MM-DD format"},{"name":"timezone","in":"query","required":true,"schema":{"type":"string","description":"IANA timezone (e.g., 'America/New_York')","title":"Timezone"},"description":"IANA timezone (e.g., 'America/New_York')"},{"name":"workflow_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Optional workflow ID to filter by","title":"Workflow Id"},"description":"Optional workflow ID to filter by"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DailyReportResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/reports/workflows":{"get":{"tags":["main"],"summary":"Get Workflow Options","description":"Get all workflows for the user's organization.\nUsed to populate the workflow selector dropdown in the reports page.","operationId":"get_workflow_options_api_v1_organizations_reports_workflows_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowOption"},"title":"Response Get Workflow Options Api V1 Organizations Reports Workflows Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/reports/daily/runs":{"get":{"tags":["main"],"summary":"Get Daily Runs Detail","description":"Get detailed workflow runs for the specified date.\nUsed for CSV export functionality.","operationId":"get_daily_runs_detail_api_v1_organizations_reports_daily_runs_get","parameters":[{"name":"date","in":"query","required":true,"schema":{"type":"string","description":"Date in YYYY-MM-DD format","title":"Date"},"description":"Date in YYYY-MM-DD format"},{"name":"timezone","in":"query","required":true,"schema":{"type":"string","description":"IANA timezone (e.g., 'America/New_York')","title":"Timezone"},"description":"IANA timezone (e.g., 'America/New_York')"},{"name":"workflow_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Optional workflow ID to filter by","title":"Workflow Id"},"description":"Optional workflow ID to filter by"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowRunDetail"},"title":"Response Get Daily Runs Detail Api V1 Organizations Reports Daily Runs Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/turn/credentials":{"get":{"tags":["main","turn"],"summary":"Get Turn Credentials","description":"Get time-limited TURN credentials for WebRTC connections.\n\nThis endpoint generates ephemeral TURN credentials that are:\n- Valid for the configured TTL (default: 24 hours)\n- Cryptographically bound to the user via HMAC\n- Compatible with coturn's use-auth-secret mode\n\nReturns:\n TurnCredentialsResponse with username, password, ttl, and TURN URIs","operationId":"get_turn_credentials_api_v1_turn_credentials_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TurnCredentialsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/embed/init":{"post":{"tags":["main"],"summary":"Initialize Embed Session","description":"Initialize an embed session with token validation and domain checking.\n\nThis endpoint:\n1. Validates the embed token\n2. Checks domain whitelist\n3. Creates a workflow run\n4. Generates a temporary session token\n5. Returns configuration for the widget","operationId":"initialize_embed_session_api_v1_public_embed_init_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitEmbedRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitEmbedResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"options":{"tags":["main"],"summary":"Options Init","description":"Fallback OPTIONS handler for init endpoint.","operationId":"options_init_api_v1_public_embed_init_options","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"}}}},"/api/v1/public/embed/config/{token}":{"options":{"tags":["main"],"summary":"Options Embed Config","description":"Fallback OPTIONS handler for the embed config endpoint.\n\nBrowser preflights include Access-Control-Request-Method and are handled by\nPublicEmbedCORSMiddleware before global CORS. This keeps non-conformant\nOPTIONS requests on the same validation path.","operationId":"options_embed_config_api_v1_public_embed_config__token__options","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["main"],"summary":"Get Embed Config","description":"Get embed configuration without creating a session.\n\nThis endpoint is used to fetch widget configuration for display purposes\nwithout actually starting a call session.","operationId":"get_embed_config_api_v1_public_embed_config__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbedConfigResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/embed/turn-credentials/{session_token}":{"get":{"tags":["main"],"summary":"Get Public Turn Credentials","description":"Get TURN credentials for an embed session.\n\nThis endpoint allows embedded widgets to obtain TURN server credentials\nfor WebRTC connections without requiring authentication.\n\nArgs:\n session_token: The session token from embed initialization\n\nReturns:\n TurnCredentialsResponse with username, password, ttl, and TURN URIs","operationId":"get_public_turn_credentials_api_v1_public_embed_turn_credentials__session_token__get","parameters":[{"name":"session_token","in":"path","required":true,"schema":{"type":"string","title":"Session Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TurnCredentialsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"options":{"tags":["main"],"summary":"Options Turn Credentials","description":"Fallback OPTIONS handler for TURN credentials endpoint.","operationId":"options_turn_credentials_api_v1_public_embed_turn_credentials__session_token__options","parameters":[{"name":"session_token","in":"path","required":true,"schema":{"type":"string","title":"Session Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/agent/{uuid}":{"post":{"tags":["main"],"summary":"Initiate Call","description":"Initiate a phone call against the published agent.\n\nExecutes the workflow's currently released definition.","operationId":"initiate_call_api_v1_public_agent__uuid__post","parameters":[{"name":"uuid","in":"path","required":true,"schema":{"type":"string","title":"Uuid"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/agent/test/{uuid}":{"post":{"tags":["main"],"summary":"Initiate Call Test","description":"Initiate a phone call against the latest draft of the agent.\n\nUseful for verifying changes before publishing. Falls back to the\npublished definition when no draft exists.","operationId":"initiate_call_test_api_v1_public_agent_test__uuid__post","parameters":[{"name":"uuid","in":"path","required":true,"schema":{"type":"string","title":"Uuid"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/agent/workflow/{workflow_uuid}":{"post":{"tags":["main"],"summary":"Initiate Call By Workflow Uuid","description":"Initiate a phone call against the published workflow identified by UUID.","operationId":"initiate_call_by_workflow_uuid_api_v1_public_agent_workflow__workflow_uuid__post","parameters":[{"name":"workflow_uuid","in":"path","required":true,"schema":{"type":"string","title":"Workflow Uuid"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/agent/test/workflow/{workflow_uuid}":{"post":{"tags":["main"],"summary":"Initiate Call Test By Workflow Uuid","description":"Initiate a phone call against the latest draft of the workflow by UUID.","operationId":"initiate_call_test_by_workflow_uuid_api_v1_public_agent_test_workflow__workflow_uuid__post","parameters":[{"name":"workflow_uuid","in":"path","required":true,"schema":{"type":"string","title":"Workflow Uuid"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/download/workflow/{token}/{artifact_type}":{"get":{"tags":["main"],"summary":"Download Workflow Artifact","description":"Download a workflow recording or transcript via public access token.\n\nThis endpoint:\n1. Validates the public access token\n2. Looks up the corresponding workflow run\n3. Generates a signed URL for the requested artifact\n4. Redirects to the signed URL\n\nArgs:\n token: The public access token (UUID format)\n artifact_type: Type of artifact - \"recording\" or \"transcript\"\n inline: If true, sets Content-Disposition to inline for browser preview\n\nReturns:\n RedirectResponse to the signed URL (302 redirect)\n\nRaises:\n HTTPException 404: If token is invalid or artifact not found","operationId":"download_workflow_artifact_api_v1_public_download_workflow__token___artifact_type__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"artifact_type","in":"path","required":true,"schema":{"enum":["recording","transcript"],"type":"string","title":"Artifact Type"}},{"name":"inline","in":"query","required":false,"schema":{"type":"boolean","description":"Display inline in browser instead of download","default":false,"title":"Inline"},"description":"Display inline in browser instead of download"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/embed-token":{"post":{"tags":["main"],"summary":"Create Or Update Embed Token","description":"Create or update an embed token for a workflow.\nEach workflow can have only one active embed token.","operationId":"create_or_update_embed_token_api_v1_workflow__workflow_id__embed_token_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbedTokenRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbedTokenResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["main"],"summary":"Get Embed Token","description":"Get the embed token for a workflow if it exists.","operationId":"get_embed_token_api_v1_workflow__workflow_id__embed_token_get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/EmbedTokenResponse"},{"type":"null"}],"title":"Response Get Embed Token Api V1 Workflow Workflow Id Embed Token Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main"],"summary":"Deactivate Embed Token","description":"Deactivate the embed token for a workflow.","operationId":"deactivate_embed_token_api_v1_workflow__workflow_id__embed_token_delete","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Deactivate Embed Token Api V1 Workflow Workflow Id Embed Token Delete"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/knowledge-base/upload-url":{"post":{"tags":["main","knowledge-base"],"summary":"Get presigned URL for document upload","description":"Generate a presigned PUT URL for uploading a document.\n\nThis endpoint:\n1. Generates a unique document UUID for organizing the S3 key\n2. Generates a presigned S3/MinIO URL for uploading the file\n3. Returns the upload URL and document metadata\n\nAfter uploading to the returned URL, call /process-document to create\nthe document record and trigger processing.\n\nAccess Control:\n* All authenticated users can upload documents scoped to their organization.","operationId":"get_upload_url_api_v1_knowledge_base_upload_url_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentUploadRequestSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentUploadResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/knowledge-base/process-document":{"post":{"tags":["main","knowledge-base"],"summary":"Trigger document processing","description":"Trigger asynchronous processing of an uploaded document.\n\nThis endpoint should be called after successfully uploading a file to the presigned URL.\nIt will:\n1. Create a document record in the database with the specified UUID\n2. Enqueue a background task to process the document (chunking and embedding)\n\nThe document status will be updated from 'pending' -> 'processing' -> 'completed' or 'failed'.\n\nEmbedding:\nUses OpenAI text-embedding-3-small (1536-dimensional embeddings, requires API key configured in Model Configurations).\n\nAccess Control:\n* Users can only process documents in their organization.","operationId":"process_document_api_v1_knowledge_base_process_document_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProcessDocumentRequestSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/knowledge-base/documents":{"get":{"tags":["main","knowledge-base"],"summary":"List documents","description":"List all documents for the user's organization.\n\nAccess Control:\n* Users can only see documents from their organization.","operationId":"list_documents_api_v1_knowledge_base_documents_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by processing status","title":"Status"},"description":"Filter by processing status"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentListResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"list_documents","x-sdk-description":"List knowledge base documents available to the authenticated organization."}},"/api/v1/knowledge-base/documents/{document_uuid}":{"get":{"tags":["main","knowledge-base"],"summary":"Get document details","description":"Get details of a specific document.\n\nAccess Control:\n* Users can only access documents from their organization.","operationId":"get_document_api_v1_knowledge_base_documents__document_uuid__get","parameters":[{"name":"document_uuid","in":"path","required":true,"schema":{"type":"string","title":"Document Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main","knowledge-base"],"summary":"Delete document","description":"Soft delete a document and its chunks.\n\nAccess Control:\n* Users can only delete documents from their organization.","operationId":"delete_document_api_v1_knowledge_base_documents__document_uuid__delete","parameters":[{"name":"document_uuid","in":"path","required":true,"schema":{"type":"string","title":"Document Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/knowledge-base/search":{"post":{"tags":["main","knowledge-base"],"summary":"Search for similar chunks","description":"Search for document chunks similar to the query.\n\nThis endpoint uses vector similarity search to find relevant chunks.\nResults are returned without threshold filtering - apply similarity\nthresholds at the application layer after optional reranking.\n\nAccess Control:\n* Users can only search documents from their organization.","operationId":"search_chunks_api_v1_knowledge_base_search_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkSearchRequestSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkSearchResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow-recordings/upload-url":{"post":{"tags":["main","workflow-recordings"],"summary":"Get presigned URLs for recording uploads","description":"Generate presigned PUT URLs for uploading one or more audio recordings.","operationId":"get_upload_urls_api_v1_workflow_recordings_upload_url_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRecordingUploadRequestSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRecordingUploadResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow-recordings/":{"post":{"tags":["main","workflow-recordings"],"summary":"Create recording records after upload","description":"Create one or more recording records after audio files have been uploaded.","operationId":"create_recordings_api_v1_workflow_recordings__post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRecordingCreateRequestSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRecordingCreateResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["main","workflow-recordings"],"summary":"List recordings","description":"List recordings for the organization, optionally filtered.","operationId":"list_recordings_api_v1_workflow_recordings__get","parameters":[{"name":"workflow_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filter by workflow ID","title":"Workflow Id"},"description":"Filter by workflow ID"},{"name":"tts_provider","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by TTS provider","title":"Tts Provider"},"description":"Filter by TTS provider"},{"name":"tts_model","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by TTS model","title":"Tts Model"},"description":"Filter by TTS model"},{"name":"tts_voice_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by TTS voice ID","title":"Tts Voice Id"},"description":"Filter by TTS voice ID"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingListResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"list_recordings","x-sdk-description":"List workflow recordings available to the authenticated organization."}},"/api/v1/workflow-recordings/{recording_id}":{"delete":{"tags":["main","workflow-recordings"],"summary":"Delete a recording","description":"Soft delete a recording.","operationId":"delete_recording_api_v1_workflow_recordings__recording_id__delete","parameters":[{"name":"recording_id","in":"path","required":true,"schema":{"type":"string","title":"Recording Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow-recordings/{id}":{"patch":{"tags":["main","workflow-recordings"],"summary":"Update a recording's Recording ID","description":"Update the recording_id (descriptive name) of a recording.","operationId":"update_recording_api_v1_workflow_recordings__id__patch","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingUpdateRequestSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow-recordings/transcribe":{"post":{"tags":["main","workflow-recordings"],"summary":"Transcribe an audio file","description":"Transcribe an uploaded audio file using MPS STT.","operationId":"transcribe_audio_api_v1_workflow_recordings_transcribe_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_transcribe_audio_api_v1_workflow_recordings_transcribe_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folder/":{"get":{"tags":["main"],"summary":"List Folders","description":"List all folders in the authenticated user's organization.","operationId":"list_folders_api_v1_folder__get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FolderResponse"},"title":"Response List Folders Api V1 Folder Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main"],"summary":"Create Folder","description":"Create a new folder in the authenticated user's organization.","operationId":"create_folder_api_v1_folder__post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFolderRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folder/{folder_id}":{"put":{"tags":["main"],"summary":"Rename Folder","description":"Rename a folder owned by the authenticated user's organization.","operationId":"rename_folder_api_v1_folder__folder_id__put","parameters":[{"name":"folder_id","in":"path","required":true,"schema":{"type":"integer","title":"Folder Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFolderRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main"],"summary":"Delete Folder","description":"Delete a folder. Member agents are moved to \"Uncategorized\", not deleted.","operationId":"delete_folder_api_v1_folder__folder_id__delete","parameters":[{"name":"folder_id","in":"path","required":true,"schema":{"type":"integer","title":"Folder Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"boolean"},"title":"Response Delete Folder Api V1 Folder Folder Id Delete"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/signup":{"post":{"tags":["main","auth"],"summary":"Signup","operationId":"signup_api_v1_auth_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["main","auth"],"summary":"Login","operationId":"login_api_v1_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/me":{"get":{"tags":["main","auth"],"summary":"Get Current User","operationId":"get_current_user_api_v1_auth_me_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/node-types":{"get":{"tags":["main"],"summary":"List Node Types","description":"List every registered NodeSpec.\n\nSDK clients should pin to `spec_version` and warn if the server reports\na higher version than what they were generated against.","operationId":"list_node_types_api_v1_node_types_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NodeTypesResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"list_node_types","x-sdk-description":"List every registered node type with its spec. Pinned to spec_version."}},"/api/v1/node-types/{name}":{"get":{"tags":["main"],"summary":"Get Node Type","operationId":"get_node_type_api_v1_node_types__name__get","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NodeSpec"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"get_node_type","x-sdk-description":"Fetch a single node spec by name."}},"/api/v1/health":{"get":{"tags":["main"],"summary":"Health","operationId":"health_api_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"404":{"description":"Not found"}}}}},"components":{"schemas":{"APIKeyResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"key_prefix":{"type":"string","title":"Key Prefix"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"archived_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Archived At"}},"type":"object","required":["id","name","key_prefix","is_active","created_at"],"title":"APIKeyResponse"},"APIKeyStatus":{"properties":{"model":{"type":"string","title":"Model"},"message":{"type":"string","title":"Message"}},"type":"object","required":["model","message"],"title":"APIKeyStatus"},"APIKeyStatusResponse":{"properties":{"status":{"items":{"$ref":"#/components/schemas/APIKeyStatus"},"type":"array","title":"Status"}},"type":"object","required":["status"],"title":"APIKeyStatusResponse"},"ARIConfigurationRequest":{"properties":{"provider":{"type":"string","const":"ari","title":"Provider","default":"ari"},"ari_endpoint":{"type":"string","title":"Ari Endpoint","description":"ARI base URL (e.g., http://asterisk.example.com:8088)"},"app_name":{"type":"string","title":"App Name","description":"Stasis application name registered in Asterisk"},"app_password":{"type":"string","title":"App Password","description":"ARI user password"},"ws_client_name":{"type":"string","title":"Ws Client Name","description":"websocket_client.conf connection name for externalMedia (e.g., dograh_staging)","default":""},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of SIP extensions/numbers for outbound calls (optional)"}},"type":"object","required":["ari_endpoint","app_name","app_password"],"title":"ARIConfigurationRequest","description":"Request schema for Asterisk ARI configuration."},"ARIConfigurationResponse":{"properties":{"provider":{"type":"string","const":"ari","title":"Provider","default":"ari"},"ari_endpoint":{"type":"string","title":"Ari Endpoint"},"app_name":{"type":"string","title":"App Name"},"app_password":{"type":"string","title":"App Password"},"ws_client_name":{"type":"string","title":"Ws Client Name","default":""},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["ari_endpoint","app_name","app_password","from_numbers"],"title":"ARIConfigurationResponse","description":"Response schema for ARI configuration with masked sensitive fields."},"AWSBedrockLLMConfiguration":{"properties":{"provider":{"type":"string","const":"aws_bedrock","title":"Provider","default":"aws_bedrock"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Not used for Bedrock \u2014 authentication is via the AWS credentials above. Leave blank."},"model":{"type":"string","title":"Model","description":"Bedrock model ID \u2014 include the region inference-profile prefix (e.g. 'us.').","default":"us.amazon.nova-pro-v1:0","examples":["us.amazon.nova-pro-v1:0","us.amazon.nova-lite-v1:0","us.amazon.nova-micro-v1:0","us.anthropic.claude-sonnet-4-20250514-v1:0","us.anthropic.claude-3-5-sonnet-20241022-v2:0","us.anthropic.claude-haiku-4-5-20251001-v1:0"],"allow_custom_input":true},"aws_access_key":{"type":"string","title":"Aws Access Key","description":"AWS access key ID with bedrock:InvokeModel permission.","default":""},"aws_secret_key":{"type":"string","title":"Aws Secret Key","description":"AWS secret access key paired with the access key ID.","default":""},"aws_region":{"type":"string","title":"Aws Region","description":"AWS region where the Bedrock model is available.","default":"us-east-1"}},"type":"object","title":"AWS Bedrock"},"AmbientNoiseUploadRequest":{"properties":{"workflow_id":{"type":"integer","title":"Workflow Id"},"filename":{"type":"string","title":"Filename"},"mime_type":{"type":"string","title":"Mime Type","default":"audio/wav"},"file_size":{"type":"integer","maximum":10485760.0,"exclusiveMinimum":0.0,"title":"File Size","description":"Max 10MB"}},"type":"object","required":["workflow_id","filename","file_size"],"title":"AmbientNoiseUploadRequest"},"AmbientNoiseUploadResponse":{"properties":{"upload_url":{"type":"string","title":"Upload Url"},"storage_key":{"type":"string","title":"Storage Key"},"storage_backend":{"type":"string","title":"Storage Backend"}},"type":"object","required":["upload_url","storage_key","storage_backend"],"title":"AmbientNoiseUploadResponse"},"AppendTextChatMessageRequest":{"properties":{"text":{"type":"string","minLength":1,"title":"Text"},"expected_revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Revision"}},"type":"object","required":["text"],"title":"AppendTextChatMessageRequest"},"AssemblyAISTTConfiguration":{"properties":{"provider":{"type":"string","const":"assemblyai","title":"Provider","default":"assemblyai"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"AssemblyAI realtime STT model.","default":"u3-rt-pro","examples":["u3-rt-pro"]},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code.","default":"en","examples":["en","es","de","fr","pt","it"]}},"type":"object","required":["api_key"],"title":"AssemblyAI"},"AuthResponse":{"properties":{"token":{"type":"string","title":"Token"},"user":{"$ref":"#/components/schemas/UserResponse"}},"type":"object","required":["token","user"],"title":"AuthResponse"},"AuthUserResponse":{"properties":{"id":{"type":"integer","title":"Id"},"is_superuser":{"type":"boolean","title":"Is Superuser"}},"type":"object","required":["id","is_superuser"],"title":"AuthUserResponse"},"AzureLLMService":{"properties":{"provider":{"type":"string","const":"azure","title":"Provider","default":"azure"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Azure deployment name (not the upstream OpenAI model id).","default":"gpt-4.1-mini","examples":["gpt-4.1-mini"],"allow_custom_input":true},"endpoint":{"type":"string","title":"Endpoint","description":"Azure OpenAI resource endpoint (e.g. https://.openai.azure.com)."}},"type":"object","required":["api_key","endpoint"],"title":"Azure OpenAI"},"AzureOpenAIEmbeddingsConfiguration":{"properties":{"provider":{"type":"string","const":"azure","title":"Provider","default":"azure"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Azure OpenAI embedding deployment name. The deployment must return 1536-dimensional embeddings.","default":"text-embedding-3-small","examples":["text-embedding-3-small","text-embedding-ada-002"],"allow_custom_input":true},"endpoint":{"type":"string","title":"Endpoint","description":"Azure OpenAI resource endpoint (e.g. https://.openai.azure.com)."},"api_version":{"type":"string","title":"Api Version","description":"Azure OpenAI API version for embeddings.","default":"2024-02-15-preview"}},"type":"object","required":["api_key","endpoint"],"title":"Azure OpenAI"},"AzureRealtimeLLMConfiguration":{"properties":{"provider":{"type":"string","const":"azure_realtime","title":"Provider","default":"azure_realtime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Azure OpenAI realtime deployment name.","default":"gpt-4o-realtime-preview","examples":["gpt-4o-realtime-preview"],"allow_custom_input":true},"endpoint":{"type":"string","title":"Endpoint","description":"Azure OpenAI resource endpoint (e.g. https://.openai.azure.com)."},"voice":{"type":"string","title":"Voice","description":"Voice the model speaks in.","default":"alloy","examples":["alloy","ash","ballad","coral","echo","sage","shimmer","verse"],"allow_custom_input":true},"api_version":{"type":"string","title":"Api Version","description":"Azure OpenAI API version.","default":"2025-04-01-preview","examples":["2025-04-01-preview","2024-10-01-preview","2024-12-17"]}},"type":"object","required":["api_key","endpoint"],"title":"Azure OpenAI Realtime","description":"Azure OpenAI Realtime API \u2014 low-latency speech-to-speech conversations.","provider_docs_url":"https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/realtime-audio-quickstart"},"AzureSpeechSTTConfiguration":{"properties":{"provider":{"type":"string","const":"azure_speech","title":"Provider","default":"azure_speech"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Azure Speech recognition model (use 'latest_long' for continuous recognition).","default":"latest_long","examples":["latest_long","latest_short"]},"region":{"type":"string","title":"Region","description":"Azure region for Speech Services (e.g. 'eastus', 'westeurope').","default":"eastus","examples":["eastus","eastus2","westus","westus2","westus3","centralus","northcentralus","southcentralus","westcentralus","westeurope","northeurope","uksouth","ukwest","francecentral","switzerlandnorth","germanywestcentral","norwayeast","australiaeast","eastasia","southeastasia","japaneast","japanwest","koreacentral","centralindia","southindia","brazilsouth"]},"language":{"type":"string","title":"Language","description":"BCP-47 language code for recognition.","default":"en-US","examples":["en-US","en-GB","en-AU","en-CA","en-IN","es-ES","es-MX","fr-FR","fr-CA","de-DE","it-IT","ja-JP","ko-KR","zh-CN","pt-BR","pt-PT","ru-RU","ar-SA","nl-NL","pl-PL","hi-IN"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Azure Speech Services","description":"Azure Cognitive Services Speech \u2014 TTS and STT via the Azure Speech SDK.","provider_docs_url":"https://learn.microsoft.com/en-us/azure/ai-services/speech-service/"},"AzureSpeechTTSConfiguration":{"properties":{"provider":{"type":"string","const":"azure_speech","title":"Provider","default":"azure_speech"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Azure Speech synthesis engine (neural voices only).","default":"neural","examples":["neural"]},"region":{"type":"string","title":"Region","description":"Azure region for Speech Services (e.g. 'eastus', 'westeurope').","default":"eastus","examples":["eastus","eastus2","westus","westus2","westus3","centralus","northcentralus","southcentralus","westcentralus","westeurope","northeurope","uksouth","ukwest","francecentral","switzerlandnorth","germanywestcentral","norwayeast","australiaeast","eastasia","southeastasia","japaneast","japanwest","koreacentral","centralindia","southindia","brazilsouth"]},"voice":{"type":"string","title":"Voice","description":"Azure Neural voice name (e.g. 'en-US-AriaNeural').","default":"en-US-AriaNeural","examples":["en-US-AriaNeural","en-US-GuyNeural","en-US-JennyNeural","en-US-DavisNeural","en-US-AmberNeural","en-US-AnaNeural","en-US-AshleyNeural","en-US-BrandonNeural","en-US-ChristopherNeural","en-US-ElizabethNeural","en-US-EricNeural","en-US-JacobNeural","en-US-MichelleNeural","en-US-MonicaNeural","en-US-NancyNeural","en-US-RogerNeural","en-US-SaraNeural","en-US-SteffanNeural","en-US-TonyNeural"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"BCP-47 language code for synthesis.","default":"en-US","examples":["en-US","en-GB","en-AU","en-CA","en-IN","es-ES","es-MX","fr-FR","fr-CA","de-DE","it-IT","ja-JP","ko-KR","zh-CN","zh-HK","zh-TW","pt-BR","pt-PT","ru-RU","ar-SA","nl-NL","pl-PL","sv-SE","hi-IN"],"allow_custom_input":true},"speed":{"type":"number","maximum":2.0,"minimum":0.5,"title":"Speed","description":"Speech speed multiplier (0.5 to 2.0).","default":1.0}},"type":"object","required":["api_key"],"title":"Azure Speech Services","description":"Azure Cognitive Services Speech \u2014 TTS and STT via the Azure Speech SDK.","provider_docs_url":"https://learn.microsoft.com/en-us/azure/ai-services/speech-service/"},"BYOKAIModelConfiguration":{"properties":{"mode":{"type":"string","enum":["pipeline","realtime"],"title":"Mode"},"pipeline":{"anyOf":[{"$ref":"#/components/schemas/BYOKPipelineAIModelConfiguration"},{"type":"null"}]},"realtime":{"anyOf":[{"$ref":"#/components/schemas/BYOKRealtimeAIModelConfiguration"},{"type":"null"}]}},"type":"object","required":["mode"],"title":"BYOKAIModelConfiguration"},"BYOKPipelineAIModelConfiguration":{"properties":{"llm":{"oneOf":[{"$ref":"#/components/schemas/OpenAILLMService"},{"$ref":"#/components/schemas/GoogleVertexLLMConfiguration"},{"$ref":"#/components/schemas/GroqLLMService"},{"$ref":"#/components/schemas/OpenRouterLLMConfiguration"},{"$ref":"#/components/schemas/GoogleLLMService"},{"$ref":"#/components/schemas/AzureLLMService"},{"$ref":"#/components/schemas/DograhLLMService"},{"$ref":"#/components/schemas/AWSBedrockLLMConfiguration"},{"$ref":"#/components/schemas/SpeachesLLMConfiguration"},{"$ref":"#/components/schemas/MiniMaxLLMConfiguration"},{"$ref":"#/components/schemas/SarvamLLMConfiguration"}],"title":"Llm","discriminator":{"propertyName":"provider","mapping":{"aws_bedrock":"#/components/schemas/AWSBedrockLLMConfiguration","azure":"#/components/schemas/AzureLLMService","dograh":"#/components/schemas/DograhLLMService","google":"#/components/schemas/GoogleLLMService","google_vertex":"#/components/schemas/GoogleVertexLLMConfiguration","groq":"#/components/schemas/GroqLLMService","minimax":"#/components/schemas/MiniMaxLLMConfiguration","openai":"#/components/schemas/OpenAILLMService","openrouter":"#/components/schemas/OpenRouterLLMConfiguration","sarvam":"#/components/schemas/SarvamLLMConfiguration","speaches":"#/components/schemas/SpeachesLLMConfiguration"}}},"tts":{"oneOf":[{"$ref":"#/components/schemas/DeepgramTTSConfiguration"},{"$ref":"#/components/schemas/GoogleTTSConfiguration"},{"$ref":"#/components/schemas/OpenAITTSService"},{"$ref":"#/components/schemas/ElevenlabsTTSConfiguration"},{"$ref":"#/components/schemas/CartesiaTTSConfiguration"},{"$ref":"#/components/schemas/DograhTTSService"},{"$ref":"#/components/schemas/SarvamTTSConfiguration"},{"$ref":"#/components/schemas/CambTTSConfiguration"},{"$ref":"#/components/schemas/RimeTTSConfiguration"},{"$ref":"#/components/schemas/SpeachesTTSConfiguration"},{"$ref":"#/components/schemas/MiniMaxTTSConfiguration"},{"$ref":"#/components/schemas/AzureSpeechTTSConfiguration"}],"title":"Tts","discriminator":{"propertyName":"provider","mapping":{"azure_speech":"#/components/schemas/AzureSpeechTTSConfiguration","camb":"#/components/schemas/CambTTSConfiguration","cartesia":"#/components/schemas/CartesiaTTSConfiguration","deepgram":"#/components/schemas/DeepgramTTSConfiguration","dograh":"#/components/schemas/DograhTTSService","elevenlabs":"#/components/schemas/ElevenlabsTTSConfiguration","google":"#/components/schemas/GoogleTTSConfiguration","minimax":"#/components/schemas/MiniMaxTTSConfiguration","openai":"#/components/schemas/OpenAITTSService","rime":"#/components/schemas/RimeTTSConfiguration","sarvam":"#/components/schemas/SarvamTTSConfiguration","speaches":"#/components/schemas/SpeachesTTSConfiguration"}}},"stt":{"oneOf":[{"$ref":"#/components/schemas/DeepgramSTTConfiguration"},{"$ref":"#/components/schemas/CartesiaSTTConfiguration"},{"$ref":"#/components/schemas/OpenAISTTConfiguration"},{"$ref":"#/components/schemas/GoogleSTTConfiguration"},{"$ref":"#/components/schemas/DograhSTTService"},{"$ref":"#/components/schemas/SpeechmaticsSTTConfiguration"},{"$ref":"#/components/schemas/SarvamSTTConfiguration"},{"$ref":"#/components/schemas/SpeachesSTTConfiguration"},{"$ref":"#/components/schemas/AssemblyAISTTConfiguration"},{"$ref":"#/components/schemas/GladiaSTTConfiguration"},{"$ref":"#/components/schemas/AzureSpeechSTTConfiguration"}],"title":"Stt","discriminator":{"propertyName":"provider","mapping":{"assemblyai":"#/components/schemas/AssemblyAISTTConfiguration","azure_speech":"#/components/schemas/AzureSpeechSTTConfiguration","cartesia":"#/components/schemas/CartesiaSTTConfiguration","deepgram":"#/components/schemas/DeepgramSTTConfiguration","dograh":"#/components/schemas/DograhSTTService","gladia":"#/components/schemas/GladiaSTTConfiguration","google":"#/components/schemas/GoogleSTTConfiguration","openai":"#/components/schemas/OpenAISTTConfiguration","sarvam":"#/components/schemas/SarvamSTTConfiguration","speaches":"#/components/schemas/SpeachesSTTConfiguration","speechmatics":"#/components/schemas/SpeechmaticsSTTConfiguration"}}},"embeddings":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/OpenAIEmbeddingsConfiguration"},{"$ref":"#/components/schemas/OpenRouterEmbeddingsConfiguration"},{"$ref":"#/components/schemas/AzureOpenAIEmbeddingsConfiguration"},{"$ref":"#/components/schemas/DograhEmbeddingsConfiguration"}],"discriminator":{"propertyName":"provider","mapping":{"azure":"#/components/schemas/AzureOpenAIEmbeddingsConfiguration","dograh":"#/components/schemas/DograhEmbeddingsConfiguration","openai":"#/components/schemas/OpenAIEmbeddingsConfiguration","openrouter":"#/components/schemas/OpenRouterEmbeddingsConfiguration"}}},{"type":"null"}],"title":"Embeddings"}},"type":"object","required":["llm","tts","stt"],"title":"BYOKPipelineAIModelConfiguration"},"BYOKRealtimeAIModelConfiguration":{"properties":{"realtime":{"oneOf":[{"$ref":"#/components/schemas/OpenAIRealtimeLLMConfiguration"},{"$ref":"#/components/schemas/GrokRealtimeLLMConfiguration"},{"$ref":"#/components/schemas/UltravoxRealtimeLLMConfiguration"},{"$ref":"#/components/schemas/GoogleRealtimeLLMConfiguration"},{"$ref":"#/components/schemas/GoogleVertexRealtimeLLMConfiguration"},{"$ref":"#/components/schemas/AzureRealtimeLLMConfiguration"}],"title":"Realtime","discriminator":{"propertyName":"provider","mapping":{"azure_realtime":"#/components/schemas/AzureRealtimeLLMConfiguration","google_realtime":"#/components/schemas/GoogleRealtimeLLMConfiguration","google_vertex_realtime":"#/components/schemas/GoogleVertexRealtimeLLMConfiguration","grok_realtime":"#/components/schemas/GrokRealtimeLLMConfiguration","openai_realtime":"#/components/schemas/OpenAIRealtimeLLMConfiguration","ultravox_realtime":"#/components/schemas/UltravoxRealtimeLLMConfiguration"}}},"llm":{"oneOf":[{"$ref":"#/components/schemas/OpenAILLMService"},{"$ref":"#/components/schemas/GoogleVertexLLMConfiguration"},{"$ref":"#/components/schemas/GroqLLMService"},{"$ref":"#/components/schemas/OpenRouterLLMConfiguration"},{"$ref":"#/components/schemas/GoogleLLMService"},{"$ref":"#/components/schemas/AzureLLMService"},{"$ref":"#/components/schemas/DograhLLMService"},{"$ref":"#/components/schemas/AWSBedrockLLMConfiguration"},{"$ref":"#/components/schemas/SpeachesLLMConfiguration"},{"$ref":"#/components/schemas/MiniMaxLLMConfiguration"},{"$ref":"#/components/schemas/SarvamLLMConfiguration"}],"title":"Llm","discriminator":{"propertyName":"provider","mapping":{"aws_bedrock":"#/components/schemas/AWSBedrockLLMConfiguration","azure":"#/components/schemas/AzureLLMService","dograh":"#/components/schemas/DograhLLMService","google":"#/components/schemas/GoogleLLMService","google_vertex":"#/components/schemas/GoogleVertexLLMConfiguration","groq":"#/components/schemas/GroqLLMService","minimax":"#/components/schemas/MiniMaxLLMConfiguration","openai":"#/components/schemas/OpenAILLMService","openrouter":"#/components/schemas/OpenRouterLLMConfiguration","sarvam":"#/components/schemas/SarvamLLMConfiguration","speaches":"#/components/schemas/SpeachesLLMConfiguration"}}},"embeddings":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/OpenAIEmbeddingsConfiguration"},{"$ref":"#/components/schemas/OpenRouterEmbeddingsConfiguration"},{"$ref":"#/components/schemas/AzureOpenAIEmbeddingsConfiguration"},{"$ref":"#/components/schemas/DograhEmbeddingsConfiguration"}],"discriminator":{"propertyName":"provider","mapping":{"azure":"#/components/schemas/AzureOpenAIEmbeddingsConfiguration","dograh":"#/components/schemas/DograhEmbeddingsConfiguration","openai":"#/components/schemas/OpenAIEmbeddingsConfiguration","openrouter":"#/components/schemas/OpenRouterEmbeddingsConfiguration"}}},{"type":"null"}],"title":"Embeddings"}},"type":"object","required":["realtime","llm"],"title":"BYOKRealtimeAIModelConfiguration"},"BatchRecordingCreateRequestSchema":{"properties":{"recordings":{"items":{"$ref":"#/components/schemas/RecordingCreateRequestSchema"},"type":"array","maxItems":20,"minItems":1,"title":"Recordings","description":"List of recordings to create"}},"type":"object","required":["recordings"],"title":"BatchRecordingCreateRequestSchema","description":"Request schema for creating one or more recording records after upload."},"BatchRecordingCreateResponseSchema":{"properties":{"recordings":{"items":{"$ref":"#/components/schemas/RecordingResponseSchema"},"type":"array","title":"Recordings","description":"Created recording records"}},"type":"object","required":["recordings"],"title":"BatchRecordingCreateResponseSchema","description":"Response schema for recording creation."},"BatchRecordingUploadRequestSchema":{"properties":{"files":{"items":{"$ref":"#/components/schemas/FileDescriptor"},"type":"array","maxItems":20,"minItems":1,"title":"Files","description":"List of files to upload"}},"type":"object","required":["files"],"title":"BatchRecordingUploadRequestSchema","description":"Request schema for getting presigned upload URLs for one or more files."},"BatchRecordingUploadResponseSchema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/RecordingUploadResponseSchema"},"type":"array","title":"Items","description":"Upload URLs for each file"}},"type":"object","required":["items"],"title":"BatchRecordingUploadResponseSchema","description":"Response schema with presigned upload URLs."},"Body_transcribe_audio_api_v1_workflow_recordings_transcribe_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"language":{"type":"string","title":"Language","default":"en"}},"type":"object","required":["file"],"title":"Body_transcribe_audio_api_v1_workflow_recordings_transcribe_post"},"CalculatorToolDefinition":{"properties":{"schema_version":{"type":"integer","title":"Schema Version","description":"Schema version.","default":1},"type":{"type":"string","const":"calculator","title":"Type","description":"Tool type."}},"type":"object","required":["type"],"title":"CalculatorToolDefinition","description":"Tool definition for Calculator tools."},"CallDispositionCodes":{"properties":{"disposition_codes":{"items":{"type":"string"},"type":"array","title":"Disposition Codes","default":[]}},"type":"object","title":"CallDispositionCodes"},"CallType":{"type":"string","enum":["inbound","outbound"],"title":"CallType"},"CambTTSConfiguration":{"properties":{"provider":{"type":"string","const":"camb","title":"Provider","default":"camb"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Camb.ai TTS model.","default":"mars-flash","examples":["mars-flash","mars-pro","mars-instruct"]},"voice":{"type":"string","title":"Voice","description":"Camb.ai voice ID.","default":"147320"},"language":{"type":"string","title":"Language","description":"BCP-47 language code.","default":"en-us"}},"type":"object","required":["api_key"],"title":"Camb.ai"},"CampaignDefaultsResponse":{"properties":{"concurrent_call_limit":{"type":"integer","title":"Concurrent Call Limit"},"from_numbers_count":{"type":"integer","title":"From Numbers Count"},"default_retry_config":{"$ref":"#/components/schemas/RetryConfigResponse"},"last_campaign_settings":{"anyOf":[{"$ref":"#/components/schemas/LastCampaignSettingsResponse"},{"type":"null"}]}},"type":"object","required":["concurrent_call_limit","from_numbers_count","default_retry_config"],"title":"CampaignDefaultsResponse"},"CampaignLogEntryResponse":{"properties":{"ts":{"type":"string","title":"Ts"},"level":{"type":"string","title":"Level"},"event":{"type":"string","title":"Event"},"message":{"type":"string","title":"Message"},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details"}},"type":"object","required":["ts","level","event","message"],"title":"CampaignLogEntryResponse","description":"A single timestamped entry from the campaign's append-only log.\n\nSurfaced in the UI so operators can see why a campaign moved to\npaused / failed without digging through server logs."},"CampaignProgressResponse":{"properties":{"campaign_id":{"type":"integer","title":"Campaign Id"},"state":{"type":"string","title":"State"},"total_rows":{"type":"integer","title":"Total Rows"},"processed_rows":{"type":"integer","title":"Processed Rows"},"failed_calls":{"type":"integer","title":"Failed Calls"},"progress_percentage":{"type":"number","title":"Progress Percentage"},"source_sync":{"additionalProperties":true,"type":"object","title":"Source Sync"},"rate_limit":{"type":"integer","title":"Rate Limit"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["campaign_id","state","total_rows","processed_rows","failed_calls","progress_percentage","source_sync","rate_limit","started_at","completed_at"],"title":"CampaignProgressResponse"},"CampaignResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"workflow_id":{"type":"integer","title":"Workflow Id"},"workflow_name":{"type":"string","title":"Workflow Name"},"state":{"type":"string","title":"State"},"source_type":{"type":"string","title":"Source Type"},"source_id":{"type":"string","title":"Source Id"},"total_rows":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Rows"},"processed_rows":{"type":"integer","title":"Processed Rows"},"failed_rows":{"type":"integer","title":"Failed Rows"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"retry_config":{"$ref":"#/components/schemas/RetryConfigResponse"},"max_concurrency":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Concurrency"},"schedule_config":{"anyOf":[{"$ref":"#/components/schemas/ScheduleConfigResponse"},{"type":"null"}]},"circuit_breaker":{"anyOf":[{"$ref":"#/components/schemas/CircuitBreakerConfigResponse"},{"type":"null"}]},"executed_count":{"type":"integer","title":"Executed Count","default":0},"total_queued_count":{"type":"integer","title":"Total Queued Count","default":0},"parent_campaign_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Campaign Id"},"redialed_campaign_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Redialed Campaign Id"},"telephony_configuration_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Telephony Configuration Id"},"telephony_configuration_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Telephony Configuration Name"},"logs":{"items":{"$ref":"#/components/schemas/CampaignLogEntryResponse"},"type":"array","title":"Logs"}},"type":"object","required":["id","name","workflow_id","workflow_name","state","source_type","source_id","total_rows","processed_rows","failed_rows","created_at","started_at","completed_at","retry_config"],"title":"CampaignResponse"},"CampaignRunsResponse":{"properties":{"runs":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Runs"},"total_count":{"type":"integer","title":"Total Count"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["runs","total_count","page","limit","total_pages"],"title":"CampaignRunsResponse","description":"Paginated response for campaign workflow runs"},"CampaignSourceDownloadResponse":{"properties":{"download_url":{"type":"string","title":"Download Url"},"expires_in":{"type":"integer","title":"Expires In"}},"type":"object","required":["download_url","expires_in"],"title":"CampaignSourceDownloadResponse"},"CampaignsResponse":{"properties":{"campaigns":{"items":{"$ref":"#/components/schemas/CampaignResponse"},"type":"array","title":"Campaigns"}},"type":"object","required":["campaigns"],"title":"CampaignsResponse"},"CartesiaSTTConfiguration":{"properties":{"provider":{"type":"string","const":"cartesia","title":"Provider","default":"cartesia"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Cartesia STT model.","default":"ink-whisper","examples":["ink-whisper"]}},"type":"object","required":["api_key"],"title":"Cartesia"},"CartesiaTTSConfiguration":{"properties":{"provider":{"type":"string","const":"cartesia","title":"Provider","default":"cartesia"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Cartesia TTS model.","default":"sonic-3.5","examples":["sonic-3.5","sonic-3"]},"voice":{"type":"string","title":"Voice","description":"Cartesia voice UUID from your Cartesia dashboard.","default":"3faa81ae-d3d8-4ab1-9e44-e50e46d33c30"},"speed":{"type":"number","maximum":1.5,"minimum":0.6,"title":"Speed","description":"Speed of the voice.","default":1.0},"volume":{"type":"number","maximum":2.0,"minimum":0.5,"title":"Volume","description":"Volume multiplier for generated speech.","default":1.0}},"type":"object","required":["api_key"],"title":"Cartesia"},"ChunkResponseSchema":{"properties":{"id":{"type":"integer","title":"Id"},"document_id":{"type":"integer","title":"Document Id"},"chunk_text":{"type":"string","title":"Chunk Text"},"contextualized_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contextualized Text"},"chunk_index":{"type":"integer","title":"Chunk Index"},"chunk_metadata":{"additionalProperties":true,"type":"object","title":"Chunk Metadata"},"filename":{"type":"string","title":"Filename"},"document_uuid":{"type":"string","title":"Document Uuid"},"similarity":{"type":"number","title":"Similarity"}},"type":"object","required":["id","document_id","chunk_text","contextualized_text","chunk_index","chunk_metadata","filename","document_uuid","similarity"],"title":"ChunkResponseSchema","description":"Response schema for a document chunk."},"ChunkSearchRequestSchema":{"properties":{"query":{"type":"string","title":"Query","description":"Search query text"},"limit":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Limit","description":"Maximum number of results","default":5},"document_uuids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Document Uuids","description":"Filter by specific document UUIDs"},"min_similarity":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Min Similarity","description":"Minimum similarity threshold"}},"type":"object","required":["query"],"title":"ChunkSearchRequestSchema","description":"Request schema for searching similar chunks."},"ChunkSearchResponseSchema":{"properties":{"chunks":{"items":{"$ref":"#/components/schemas/ChunkResponseSchema"},"type":"array","title":"Chunks"},"query":{"type":"string","title":"Query"},"total_results":{"type":"integer","title":"Total Results"}},"type":"object","required":["chunks","query","total_results"],"title":"ChunkSearchResponseSchema","description":"Response schema for chunk search results."},"CircuitBreakerConfigRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"failure_threshold":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Failure Threshold","default":0.5},"window_seconds":{"type":"integer","maximum":600.0,"minimum":30.0,"title":"Window Seconds","default":120},"min_calls_in_window":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Min Calls In Window","default":5}},"type":"object","title":"CircuitBreakerConfigRequest"},"CircuitBreakerConfigResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":false},"failure_threshold":{"type":"number","title":"Failure Threshold","default":0.5},"window_seconds":{"type":"integer","title":"Window Seconds","default":120},"min_calls_in_window":{"type":"integer","title":"Min Calls In Window","default":5}},"type":"object","title":"CircuitBreakerConfigResponse"},"CloudonixConfigurationRequest":{"properties":{"provider":{"type":"string","const":"cloudonix","title":"Provider","default":"cloudonix"},"bearer_token":{"type":"string","title":"Bearer Token","description":"Cloudonix API Bearer Token"},"domain_id":{"type":"string","title":"Domain Id","description":"Cloudonix Domain ID"},"application_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Name","description":"Cloudonix Voice Application name. The application's url is updated when inbound workflows are attached to numbers on this domain. If omitted, an application is auto-created on save and its name is stored on the configuration."},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of Cloudonix phone numbers (optional)"}},"type":"object","required":["bearer_token","domain_id"],"title":"CloudonixConfigurationRequest","description":"Request schema for Cloudonix configuration."},"CloudonixConfigurationResponse":{"properties":{"provider":{"type":"string","const":"cloudonix","title":"Provider","default":"cloudonix"},"bearer_token":{"type":"string","title":"Bearer Token"},"domain_id":{"type":"string","title":"Domain Id"},"application_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Name"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["bearer_token","domain_id","from_numbers"],"title":"CloudonixConfigurationResponse","description":"Response schema for Cloudonix configuration with masked sensitive fields."},"CreateAPIKeyRequest":{"properties":{"name":{"type":"string","title":"Name"}},"type":"object","required":["name"],"title":"CreateAPIKeyRequest"},"CreateAPIKeyResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"key_prefix":{"type":"string","title":"Key Prefix"},"api_key":{"type":"string","title":"Api Key"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","key_prefix","api_key","created_at"],"title":"CreateAPIKeyResponse"},"CreateCampaignRequest":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"workflow_id":{"type":"integer","title":"Workflow Id"},"source_type":{"type":"string","pattern":"^csv$","title":"Source Type"},"source_id":{"type":"string","title":"Source Id"},"telephony_configuration_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Telephony Configuration Id"},"retry_config":{"anyOf":[{"$ref":"#/components/schemas/RetryConfigRequest"},{"type":"null"}]},"max_concurrency":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":1.0},{"type":"null"}],"title":"Max Concurrency"},"schedule_config":{"anyOf":[{"$ref":"#/components/schemas/ScheduleConfigRequest"},{"type":"null"}]},"circuit_breaker":{"anyOf":[{"$ref":"#/components/schemas/CircuitBreakerConfigRequest"},{"type":"null"}]}},"type":"object","required":["name","workflow_id","source_type","source_id"],"title":"CreateCampaignRequest"},"CreateCredentialRequest":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"credential_type":{"$ref":"#/components/schemas/WebhookCredentialType"},"credential_data":{"additionalProperties":true,"type":"object","title":"Credential Data"}},"type":"object","required":["name","credential_type","credential_data"],"title":"CreateCredentialRequest","description":"Request schema for creating a webhook credential."},"CreateFolderRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"}},"type":"object","required":["name"],"title":"CreateFolderRequest"},"CreateServiceKeyRequest":{"properties":{"name":{"type":"string","title":"Name"},"expires_in_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires In Days","default":90}},"type":"object","required":["name"],"title":"CreateServiceKeyRequest"},"CreateServiceKeyResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"service_key":{"type":"string","title":"Service Key"},"key_prefix":{"type":"string","title":"Key Prefix"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["id","name","service_key","key_prefix"],"title":"CreateServiceKeyResponse"},"CreateTextChatSessionRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"},"annotations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Annotations"}},"type":"object","title":"CreateTextChatSessionRequest"},"CreateToolRequest":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name","description":"Display name for the tool.","llm_hint":"Use a concise action-oriented name; this influences the function name shown to the agent."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Description shown to the agent when deciding whether to call it.","llm_hint":"State exactly when the agent should call the tool and what result it gets."},"category":{"type":"string","enum":["http_api","end_call","transfer_call","calculator","native","integration","mcp"],"title":"Category","description":"Tool category. Must match definition.type.","default":"http_api"},"icon":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Icon","description":"Lucide icon identifier.","default":"globe"},"icon_color":{"anyOf":[{"type":"string","maxLength":7},{"type":"null"}],"title":"Icon Color","description":"Hex color for the tool icon.","default":"#3B82F6"},"definition":{"oneOf":[{"$ref":"#/components/schemas/HttpApiToolDefinition"},{"$ref":"#/components/schemas/EndCallToolDefinition"},{"$ref":"#/components/schemas/TransferCallToolDefinition"},{"$ref":"#/components/schemas/CalculatorToolDefinition"},{"$ref":"#/components/schemas/McpToolDefinition"}],"title":"Definition","description":"Typed tool definition.","discriminator":{"propertyName":"type","mapping":{"calculator":"#/components/schemas/CalculatorToolDefinition","end_call":"#/components/schemas/EndCallToolDefinition","http_api":"#/components/schemas/HttpApiToolDefinition","mcp":"#/components/schemas/McpToolDefinition","transfer_call":"#/components/schemas/TransferCallToolDefinition"}}}},"type":"object","required":["name","definition"],"title":"CreateToolRequest","description":"Request schema for creating a reusable tool."},"CreateWorkflowRequest":{"properties":{"name":{"type":"string","title":"Name"},"workflow_definition":{"additionalProperties":true,"type":"object","title":"Workflow Definition"}},"type":"object","required":["name","workflow_definition"],"title":"CreateWorkflowRequest"},"CreateWorkflowRunRequest":{"properties":{"mode":{"type":"string","title":"Mode"},"name":{"type":"string","title":"Name"}},"type":"object","required":["mode","name"],"title":"CreateWorkflowRunRequest"},"CreateWorkflowRunResponse":{"properties":{"id":{"type":"integer","title":"Id"},"workflow_id":{"type":"integer","title":"Workflow Id"},"name":{"type":"string","title":"Name"},"mode":{"type":"string","title":"Mode"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"definition_id":{"type":"integer","title":"Definition Id"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"}},"type":"object","required":["id","workflow_id","name","mode","created_at","definition_id"],"title":"CreateWorkflowRunResponse"},"CreateWorkflowTemplateRequest":{"properties":{"call_type":{"type":"string","enum":["inbound","outbound"],"title":"Call Type"},"use_case":{"type":"string","title":"Use Case"},"activity_description":{"type":"string","title":"Activity Description"}},"type":"object","required":["call_type","use_case","activity_description"],"title":"CreateWorkflowTemplateRequest"},"CreatedByResponse":{"properties":{"id":{"type":"integer","title":"Id"},"provider_id":{"type":"string","title":"Provider Id"}},"type":"object","required":["id","provider_id"],"title":"CreatedByResponse","description":"Response schema for the user who created a tool."},"CredentialResponse":{"properties":{"uuid":{"type":"string","title":"Uuid"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"credential_type":{"type":"string","title":"Credential Type"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["uuid","name","description","credential_type","created_at","updated_at"],"title":"CredentialResponse","description":"Response schema for a webhook credential (never includes sensitive data)."},"CurrentUsageResponse":{"properties":{"period_start":{"type":"string","title":"Period Start"},"period_end":{"type":"string","title":"Period End"},"used_dograh_tokens":{"type":"number","title":"Used Dograh Tokens"},"total_duration_seconds":{"type":"integer","title":"Total Duration Seconds"},"used_amount_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Used Amount Usd"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"price_per_second_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Per Second Usd"}},"type":"object","required":["period_start","period_end","used_dograh_tokens","total_duration_seconds"],"title":"CurrentUsageResponse"},"DailyReportResponse":{"properties":{"date":{"type":"string","title":"Date"},"timezone":{"type":"string","title":"Timezone"},"workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Workflow Id"},"metrics":{"additionalProperties":{"type":"integer"},"type":"object","title":"Metrics"},"disposition_distribution":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Disposition Distribution"},"call_duration_distribution":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Call Duration Distribution"}},"type":"object","required":["date","timezone","workflow_id","metrics","disposition_distribution","call_duration_distribution"],"title":"DailyReportResponse"},"DailyUsageBreakdownResponse":{"properties":{"breakdown":{"items":{"$ref":"#/components/schemas/DailyUsageItem"},"type":"array","title":"Breakdown"},"total_minutes":{"type":"number","title":"Total Minutes"},"total_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Cost Usd"},"total_dograh_tokens":{"type":"number","title":"Total Dograh Tokens"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"}},"type":"object","required":["breakdown","total_minutes","total_dograh_tokens"],"title":"DailyUsageBreakdownResponse"},"DailyUsageItem":{"properties":{"date":{"type":"string","title":"Date"},"minutes":{"type":"number","title":"Minutes"},"cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost Usd"},"dograh_tokens":{"type":"number","title":"Dograh Tokens"},"call_count":{"type":"integer","title":"Call Count"}},"type":"object","required":["date","minutes","dograh_tokens","call_count"],"title":"DailyUsageItem"},"DeepgramSTTConfiguration":{"properties":{"provider":{"type":"string","const":"deepgram","title":"Provider","default":"deepgram"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Deepgram STT model.","default":"nova-3-general","examples":["nova-3-general","flux-general-en","flux-general-multi"]},"language":{"type":"string","title":"Language","description":"Language code; 'multi' enables auto-detect (Nova-3 only).","default":"multi","examples":["multi","ar","ar-AE","ar-SA","ar-QA","ar-KW","ar-SY","ar-LB","ar-PS","ar-JO","ar-EG","ar-SD","ar-TD","ar-MA","ar-DZ","ar-TN","ar-IQ","ar-IR","be","bn","bs","bg","ca","cs","da","da-DK","de","de-CH","el","en","en-US","en-AU","en-GB","en-IN","en-NZ","es","es-419","et","fa","fi","fr","fr-CA","he","hi","hr","hu","id","it","ja","kn","ko","ko-KR","lt","lv","mk","mr","ms","nl","nl-BE","no","pl","pt","pt-BR","pt-PT","ro","ru","sk","sl","sr","sv","sv-SE","ta","te","th","tl","tr","uk","ur","vi","zh-CN","zh-TW"],"model_options":{"flux-general-en":["en"],"nova-3-general":["multi","ar","ar-AE","ar-SA","ar-QA","ar-KW","ar-SY","ar-LB","ar-PS","ar-JO","ar-EG","ar-SD","ar-TD","ar-MA","ar-DZ","ar-TN","ar-IQ","ar-IR","be","bn","bs","bg","ca","cs","da","da-DK","de","de-CH","el","en","en-US","en-AU","en-GB","en-IN","en-NZ","es","es-419","et","fa","fi","fr","fr-CA","he","hi","hr","hu","id","it","ja","kn","ko","ko-KR","lt","lv","mk","mr","ms","nl","nl-BE","no","pl","pt","pt-BR","pt-PT","ro","ru","sk","sl","sr","sv","sv-SE","ta","te","th","tl","tr","uk","ur","vi","zh-CN","zh-TW"]}}},"type":"object","required":["api_key"],"title":"Deepgram"},"DeepgramTTSConfiguration":{"properties":{"provider":{"type":"string","const":"deepgram","title":"Provider","default":"deepgram"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"voice":{"type":"string","title":"Voice","description":"Deepgram voice ID (model is inferred from the 'aura-N' prefix).","default":"aura-2-helena-en"}},"type":"object","required":["api_key"],"title":"Deepgram"},"DefaultConfigurationsResponse":{"properties":{"llm":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Llm"},"tts":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Tts"},"stt":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Stt"},"embeddings":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Embeddings"},"realtime":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Realtime"},"default_providers":{"additionalProperties":{"type":"string"},"type":"object","title":"Default Providers"}},"type":"object","required":["llm","tts","stt","embeddings","realtime","default_providers"],"title":"DefaultConfigurationsResponse"},"DisplayOptions":{"properties":{"show":{"anyOf":[{"additionalProperties":{"items":{},"type":"array"},"type":"object"},{"type":"null"}],"title":"Show"},"hide":{"anyOf":[{"additionalProperties":{"items":{},"type":"array"},"type":"object"},{"type":"null"}],"title":"Hide"}},"additionalProperties":false,"type":"object","title":"DisplayOptions","description":"Conditional visibility rules.\n\n`show` keys are AND-combined: this property is visible only when EVERY\nreferenced field's value matches one of the listed values.\n\n`hide` keys are OR-combined: this property is hidden when ANY referenced\nfield's value matches one of the listed values.\n\nExample:\n DisplayOptions(show={\"extraction_enabled\": [True]})\n DisplayOptions(show={\"greeting_type\": [\"audio\"]})"},"DocumentListResponseSchema":{"properties":{"documents":{"items":{"$ref":"#/components/schemas/DocumentResponseSchema"},"type":"array","title":"Documents"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["documents","total","limit","offset"],"title":"DocumentListResponseSchema","description":"Response schema for list of documents."},"DocumentResponseSchema":{"properties":{"id":{"type":"integer","title":"Id"},"document_uuid":{"type":"string","title":"Document Uuid"},"filename":{"type":"string","title":"Filename"},"file_size_bytes":{"type":"integer","title":"File Size Bytes"},"file_hash":{"type":"string","title":"File Hash"},"mime_type":{"type":"string","title":"Mime Type"},"processing_status":{"type":"string","title":"Processing Status"},"processing_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Processing Error"},"total_chunks":{"type":"integer","title":"Total Chunks"},"retrieval_mode":{"type":"string","title":"Retrieval Mode","default":"chunked"},"custom_metadata":{"additionalProperties":true,"type":"object","title":"Custom Metadata"},"docling_metadata":{"additionalProperties":true,"type":"object","title":"Docling Metadata"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"organization_id":{"type":"integer","title":"Organization Id"},"created_by":{"type":"integer","title":"Created By"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","document_uuid","filename","file_size_bytes","file_hash","mime_type","processing_status","total_chunks","custom_metadata","docling_metadata","created_at","updated_at","organization_id","created_by","is_active"],"title":"DocumentResponseSchema","description":"Response schema for document metadata."},"DocumentUploadRequestSchema":{"properties":{"filename":{"type":"string","title":"Filename","description":"Name of the file to upload"},"mime_type":{"type":"string","title":"Mime Type","description":"MIME type of the file"},"custom_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Custom Metadata","description":"Optional custom metadata"}},"type":"object","required":["filename","mime_type"],"title":"DocumentUploadRequestSchema","description":"Request schema for initiating document upload."},"DocumentUploadResponseSchema":{"properties":{"upload_url":{"type":"string","title":"Upload Url","description":"Signed URL for uploading the file"},"document_uuid":{"type":"string","title":"Document Uuid","description":"Unique identifier for the document"},"s3_key":{"type":"string","title":"S3 Key","description":"S3 key where file should be uploaded"}},"type":"object","required":["upload_url","document_uuid","s3_key"],"title":"DocumentUploadResponseSchema","description":"Response schema containing upload URL and document metadata."},"DograhEmbeddingsConfiguration":{"properties":{"provider":{"type":"string","const":"dograh","title":"Provider","default":"dograh"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Dograh-managed embedding model.","default":"default","examples":["default"]}},"type":"object","required":["api_key"],"title":"Dograh"},"DograhLLMService":{"properties":{"provider":{"type":"string","const":"dograh","title":"Provider","default":"dograh"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Dograh-hosted model tier.","default":"default","examples":["default","accurate","fast","lite","zen"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Dograh"},"DograhManagedAIModelConfiguration":{"properties":{"api_key":{"type":"string","title":"Api Key"},"voice":{"type":"string","title":"Voice","default":"default"},"speed":{"type":"number","title":"Speed","default":1.0},"language":{"type":"string","title":"Language","default":"multi"}},"type":"object","required":["api_key"],"title":"DograhManagedAIModelConfiguration"},"DograhSTTService":{"properties":{"provider":{"type":"string","const":"dograh","title":"Provider","default":"dograh"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Dograh STT tier.","default":"default","examples":["default"]},"language":{"type":"string","title":"Language","description":"Language code; use 'multi' for auto-detect.","default":"multi","examples":["multi","ar","ar-AE","ar-SA","ar-QA","ar-KW","ar-SY","ar-LB","ar-PS","ar-JO","ar-EG","ar-SD","ar-TD","ar-MA","ar-DZ","ar-TN","ar-IQ","ar-IR","be","bn","bs","bg","ca","cs","da","da-DK","de","de-CH","el","en","en-US","en-AU","en-GB","en-IN","en-NZ","es","es-419","et","fa","fi","fr","fr-CA","he","hi","hr","hu","id","it","ja","kn","ko","ko-KR","lt","lv","mk","mr","ms","nl","nl-BE","no","pl","pt","pt-BR","pt-PT","ro","ru","sk","sl","sr","sv","sv-SE","ta","te","th","tl","tr","uk","ur","vi","zh-CN","zh-TW"]}},"type":"object","required":["api_key"],"title":"Dograh"},"DograhTTSService":{"properties":{"provider":{"type":"string","const":"dograh","title":"Provider","default":"dograh"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Dograh TTS tier.","default":"default","examples":["default"]},"voice":{"type":"string","title":"Voice","description":"Voice preset.","default":"default"},"speed":{"type":"number","maximum":2.0,"minimum":0.5,"title":"Speed","description":"Speed of the voice.","default":1.0}},"type":"object","required":["api_key"],"title":"Dograh"},"DuplicateTemplateRequest":{"properties":{"template_id":{"type":"integer","title":"Template Id"},"workflow_name":{"type":"string","title":"Workflow Name"}},"type":"object","required":["template_id","workflow_name"],"title":"DuplicateTemplateRequest"},"ElevenlabsTTSConfiguration":{"properties":{"provider":{"type":"string","const":"elevenlabs","title":"Provider","default":"elevenlabs"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"voice":{"type":"string","title":"Voice","description":"ElevenLabs voice ID from your Voice Library.","default":"21m00Tcm4TlvDq8ikWAM"},"speed":{"type":"number","maximum":2.0,"minimum":0.1,"title":"Speed","description":"Speed of the voice.","default":1.0},"model":{"type":"string","title":"Model","description":"ElevenLabs TTS model.","default":"eleven_flash_v2_5","examples":["eleven_flash_v2_5"]},"base_url":{"type":"string","title":"Base Url","description":"ElevenLabs API base URL. Override to use a Data Residency endpoint (e.g. https://api.eu.residency.elevenlabs.io) for GDPR / HIPAA / regional compliance.","default":"https://api.elevenlabs.io"}},"type":"object","required":["api_key"],"title":"ElevenLabs"},"EmbedConfigResponse":{"properties":{"workflow_id":{"type":"integer","title":"Workflow Id"},"settings":{"additionalProperties":true,"type":"object","title":"Settings"},"theme":{"type":"string","title":"Theme"},"position":{"type":"string","title":"Position"},"button_text":{"type":"string","title":"Button Text"},"button_color":{"type":"string","title":"Button Color"},"size":{"type":"string","title":"Size"},"auto_start":{"type":"boolean","title":"Auto Start"}},"type":"object","required":["workflow_id","settings","theme","position","button_text","button_color","size","auto_start"],"title":"EmbedConfigResponse","description":"Response model for embed configuration"},"EmbedTokenRequest":{"properties":{"allowed_domains":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Domains"},"settings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Settings"},"usage_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Usage Limit"},"expires_in_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires In Days","default":30}},"type":"object","title":"EmbedTokenRequest"},"EmbedTokenResponse":{"properties":{"id":{"type":"integer","title":"Id"},"token":{"type":"string","title":"Token"},"allowed_domains":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Domains"},"settings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Settings"},"is_active":{"type":"boolean","title":"Is Active"},"usage_count":{"type":"integer","title":"Usage Count"},"usage_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Usage Limit"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"embed_script":{"type":"string","title":"Embed Script"}},"type":"object","required":["id","token","allowed_domains","settings","is_active","usage_count","usage_limit","expires_at","created_at","embed_script"],"title":"EmbedTokenResponse"},"EndCallConfig":{"properties":{"messageType":{"type":"string","enum":["none","custom","audio"],"title":"Messagetype","description":"Type of goodbye message.","default":"none"},"customMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custommessage","description":"Custom message to play before ending the call."},"audioRecordingId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Audiorecordingid","description":"Recording ID for audio goodbye message."},"endCallReason":{"type":"boolean","title":"Endcallreason","description":"When enabled, the model must provide a reason for ending the call. The reason is set as call disposition and added to call tags.","default":false},"endCallReasonDescription":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endcallreasondescription","description":"Description shown to the model for the reason parameter. Used only when endCallReason is enabled."}},"type":"object","title":"EndCallConfig","description":"Configuration for End Call tools."},"EndCallToolDefinition":{"properties":{"schema_version":{"type":"integer","title":"Schema Version","description":"Schema version.","default":1},"type":{"type":"string","const":"end_call","title":"Type","description":"Tool type."},"config":{"$ref":"#/components/schemas/EndCallConfig","description":"End Call configuration."}},"type":"object","required":["type","config"],"title":"EndCallToolDefinition","description":"Tool definition for End Call tools."},"FileDescriptor":{"properties":{"filename":{"type":"string","title":"Filename","description":"Original filename of the audio file"},"mime_type":{"type":"string","title":"Mime Type","description":"MIME type of the audio file","default":"audio/wav"},"file_size":{"type":"integer","maximum":5242880.0,"exclusiveMinimum":0.0,"title":"File Size","description":"File size in bytes (max 5MB)"}},"type":"object","required":["filename","file_size"],"title":"FileDescriptor","description":"Descriptor for a single file in a batch upload request."},"FileMetadataResponse":{"properties":{"key":{"type":"string","title":"Key"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","required":["key","metadata"],"title":"FileMetadataResponse"},"FolderResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","created_at"],"title":"FolderResponse"},"GladiaSTTConfiguration":{"properties":{"provider":{"type":"string","const":"gladia","title":"Provider","default":"gladia"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Gladia STT model.","default":"solaria-1","examples":["solaria-1"]},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code.","default":"en","examples":["af","am","ar","as","az","ba","be","bg","bn","bo","br","bs","ca","cs","cy","da","de","el","en","es","et","eu","fa","fi","fo","fr","gl","gu","ha","haw","he","hi","hr","ht","hu","hy","id","is","it","ja","jw","ka","kk","km","kn","ko","la","lb","ln","lo","lt","lv","mg","mi","mk","ml","mn","mr","ms","mt","my","ne","nl","nn","no","oc","pa","pl","ps","pt","ro","ru","sa","sd","si","sk","sl","sn","so","sq","sr","su","sv","sw","ta","te","tg","th","tk","tl","tr","tt","uk","ur","uz","vi","wo","yi","yo","zh"]}},"type":"object","required":["api_key"],"title":"Gladia"},"GoogleLLMService":{"properties":{"provider":{"type":"string","const":"google","title":"Provider","default":"google"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Gemini model on Google AI Studio (not Vertex).","default":"gemini-2.0-flash","examples":["gemini-2.0-flash","gemini-2.0-flash-lite","gemini-2.5-flash","gemini-2.5-flash-lite","gemini-3.5-flash","gemini-3.5-flash-lite"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Google"},"GoogleRealtimeLLMConfiguration":{"properties":{"provider":{"type":"string","const":"google_realtime","title":"Provider","default":"google_realtime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Gemini Live model on Google AI Studio (not Vertex).","default":"gemini-3.1-flash-live-preview","examples":["gemini-3.1-flash-live-preview"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Voice the model speaks in.","default":"Puck","examples":["Puck","Charon","Kore","Fenrir","Aoede"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code.","default":"en","examples":["ar","bn","de","en","es","fr","gu","hi","id","it","ja","kn","ko","ml","mr","nl","pl","pt","ru","ta","te","th","tr","vi","zh"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Google Realtime"},"GoogleSTTConfiguration":{"properties":{"provider":{"type":"string","const":"google","title":"Provider","default":"google"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Not used for Google Cloud STT. Leave blank."},"model":{"type":"string","title":"Model","description":"Google Cloud Speech-to-Text V2 recognition model.","default":"latest_long","examples":["latest_long","latest_short","chirp_3"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"Primary BCP-47 language code for recognition.","default":"en-US","examples":["af-ZA","am-ET","ar-AE","ar-BH","ar-DZ","ar-EG","ar-IL","ar-IQ","ar-JO","ar-KW","ar-LB","ar-MA","ar-MR","ar-OM","ar-PS","ar-QA","ar-SA","ar-SY","ar-TN","ar-XA","ar-YE","as-IN","ast-ES","az-AZ","be-BY","bg-BG","bn-BD","bn-IN","bs-BA","ca-ES","ceb-PH","ckb-IQ","cmn-Hans-CN","cmn-Hant-TW","cs-CZ","cy-GB","da-DK","de-AT","de-CH","de-DE","el-GR","en-AU","en-GB","en-HK","en-IE","en-IN","en-NZ","en-PH","en-PK","en-SG","en-US","es-419","es-AR","es-BO","es-CL","es-CO","es-CR","es-DO","es-EC","es-ES","es-GT","es-HN","es-MX","es-NI","es-PA","es-PE","es-PR","es-SV","es-US","es-UY","es-VE","et-EE","eu-ES","fa-IR","ff-SN","fi-FI","fil-PH","fr-BE","fr-CA","fr-CH","fr-FR","ga-IE","gl-ES","gu-IN","ha-NG","hi-IN","hr-HR","hu-HU","hy-AM","id-ID","ig-NG","is-IS","it-CH","it-IT","iw-IL","ja-JP","jv-ID","ka-GE","kam-KE","kea-CV","kk-KZ","km-KH","kn-IN","ko-KR","ky-KG","lb-LU","lg-UG","ln-CD","lo-LA","lt-LT","luo-KE","lv-LV","mi-NZ","mk-MK","ml-IN","mn-MN","mr-IN","ms-MY","mt-MT","my-MM","ne-NP","nl-BE","nl-NL","no-NO","nso-ZA","ny-MW","oc-FR","om-ET","or-IN","pa-Guru-IN","pl-PL","ps-AF","pt-BR","pt-PT","ro-RO","ru-RU","rup-BG","rw-RW","sd-IN","si-LK","sk-SK","sl-SI","sn-ZW","so-SO","sq-AL","sr-RS","ss-Latn-ZA","st-ZA","su-ID","sv-SE","sw","sw-KE","ta-IN","te-IN","tg-TJ","th-TH","tn-Latn-ZA","tr-TR","ts-ZA","uk-UA","umb-AO","ur-PK","uz-UZ","ve-ZA","vi-VN","wo-SN","xh-ZA","yo-NG","yue-Hant-HK","zu-ZA"],"allow_custom_input":true,"docs_url":"https://docs.cloud.google.com/speech-to-text/docs/speech-to-text-supported-languages"},"location":{"type":"string","title":"Location","description":"Google Cloud Speech-to-Text region (for example 'global' or 'us-central1').","default":"global"},"credentials":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credentials","description":"Paste the entire Google Cloud service-account JSON. If omitted, the server falls back to Application Default Credentials (ADC).","multiline":true}},"type":"object","title":"Google Cloud"},"GoogleTTSConfiguration":{"properties":{"provider":{"type":"string","const":"google","title":"Provider","default":"google"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Not used for Google Cloud TTS. Leave blank."},"model":{"type":"string","title":"Model","description":"Google Cloud low-latency TTS engine. Dograh maps this to Pipecat's streaming Google TTS service for Chirp 3 HD and Journey voices.","default":"chirp_3_hd","examples":["chirp_3_hd"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Google Cloud voice name. Use a Chirp 3 HD or Journey voice for streaming TTS.","default":"en-US-Chirp3-HD-Charon","examples":["en-US-Chirp3-HD-Charon"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"BCP-47 language code for synthesis.","default":"en-US","examples":["ar-XA","bn-IN","bg-BG","yue-HK","hr-HR","cs-CZ","da-DK","nl-BE","nl-NL","en-AU","en-IN","en-GB","en-US","et-EE","fi-FI","fr-CA","fr-FR","de-DE","el-GR","gu-IN","he-IL","hi-IN","hu-HU","id-ID","it-IT","ja-JP","kn-IN","ko-KR","lv-LV","lt-LT","ml-IN","cmn-CN","mr-IN","nb-NO","pl-PL","pt-BR","pa-IN","ro-RO","ru-RU","sr-RS","sk-SK","sl-SI","es-ES","es-US","sw-KE","sv-SE","ta-IN","te-IN","th-TH","tr-TR","uk-UA","ur-IN","vi-VN"],"allow_custom_input":true},"speed":{"type":"number","maximum":2.0,"minimum":0.25,"title":"Speed","description":"Speech speed multiplier for Google streaming TTS.","default":1.0},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location","description":"Optional Google Cloud regional Text-to-Speech endpoint (for example 'us-central1'). Leave blank to use the default endpoint."},"credentials":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credentials","description":"Paste the entire Google Cloud service-account JSON. If omitted, the server falls back to Application Default Credentials (ADC).","multiline":true}},"type":"object","title":"Google Cloud"},"GoogleVertexLLMConfiguration":{"properties":{"provider":{"type":"string","const":"google_vertex","title":"Provider","default":"google_vertex"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Not used for Vertex AI \u2014 authentication is via the service account in `credentials` (or ADC). Leave blank."},"model":{"type":"string","title":"Model","description":"Gemini model on Vertex AI.","default":"gemini-2.5-flash","examples":["gemini-2.5-flash","gemini-2.5-flash-lite","gemini-3.1-flash-lite","gemini-3.5-flash"],"allow_custom_input":true},"project_id":{"type":"string","title":"Project Id","description":"Google Cloud project ID for Vertex AI."},"location":{"type":"string","title":"Location","description":"GCP region for the Vertex AI endpoint (e.g. 'global').","default":"global"},"credentials":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credentials","description":"Paste the entire service-account JSON file contents. If omitted, falls back to Application Default Credentials (ADC).","multiline":true}},"type":"object","required":["project_id"],"title":"Google Vertex"},"GoogleVertexRealtimeLLMConfiguration":{"properties":{"provider":{"type":"string","const":"google_vertex_realtime","title":"Provider","default":"google_vertex_realtime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Not used for Vertex AI \u2014 authentication is via the service account in `credentials` (or ADC). Leave blank."},"model":{"type":"string","title":"Model","description":"Vertex AI publisher/model identifier.","default":"google/gemini-live-2.5-flash-native-audio","examples":["google/gemini-live-2.5-flash-native-audio"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Voice the model speaks in.","default":"Charon","examples":["Puck","Charon","Kore","Fenrir","Aoede"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"BCP-47 language code (e.g. 'en-US').","default":"en","examples":["ar","bn","de","en","es","fr","gu","hi","id","it","ja","kn","ko","ml","mr","nl","pl","pt","ru","ta","te","th","tr","vi","zh"],"allow_custom_input":true},"project_id":{"type":"string","title":"Project Id","description":"Google Cloud project ID for Vertex AI."},"location":{"type":"string","title":"Location","description":"GCP region for the Vertex AI endpoint (e.g. 'global').","default":"global"},"credentials":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credentials","description":"Paste the entire service-account JSON file contents. If omitted, falls back to Application Default Credentials (ADC).","multiline":true}},"type":"object","required":["project_id"],"title":"Google Vertex Realtime"},"GraphConstraints":{"properties":{"min_incoming":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Incoming"},"max_incoming":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Incoming"},"min_outgoing":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Outgoing"},"max_outgoing":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Outgoing"}},"additionalProperties":false,"type":"object","title":"GraphConstraints","description":"Per-node-type graph rules. WorkflowGraph enforces these at validation."},"GrokRealtimeLLMConfiguration":{"properties":{"provider":{"type":"string","const":"grok_realtime","title":"Provider","default":"grok_realtime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Grok realtime voice-agent model.","default":"grok-voice-think-fast-1.0","examples":["grok-voice-think-fast-1.0"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Voice the model speaks in.","default":"Ara","examples":["Ara","Rex","Sal","Eve","Leo"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Grok Realtime"},"GroqLLMService":{"properties":{"provider":{"type":"string","const":"groq","title":"Provider","default":"groq"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Groq-hosted model identifier.","default":"llama-3.3-70b-versatile","examples":["llama-3.3-70b-versatile","deepseek-r1-distill-llama-70b","qwen-qwq-32b","meta-llama/llama-4-scout-17b-16e-instruct","meta-llama/llama-4-maverick-17b-128e-instruct","gemma2-9b-it","llama-3.1-8b-instant","openai/gpt-oss-120b"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Groq"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status"},"version":{"type":"string","title":"Version"},"backend_api_endpoint":{"type":"string","title":"Backend Api Endpoint"},"deployment_mode":{"type":"string","title":"Deployment Mode"},"auth_provider":{"type":"string","title":"Auth Provider"},"turn_enabled":{"type":"boolean","title":"Turn Enabled"},"force_turn_relay":{"type":"boolean","title":"Force Turn Relay"}},"type":"object","required":["status","version","backend_api_endpoint","deployment_mode","auth_provider","turn_enabled","force_turn_relay"],"title":"HealthResponse"},"HttpApiConfig":{"properties":{"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"title":"Method","description":"HTTP method to use for the request.","llm_hint":"Use one of GET, POST, PUT, PATCH, DELETE."},"url":{"type":"string","title":"Url","description":"Target HTTP or HTTPS URL.","llm_hint":"Use the final endpoint URL. Authentication belongs in credential_uuid, not embedded in the URL."},"headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Headers","description":"Static headers to include with every request.","llm_hint":"Do not place secrets here. Store secrets in the UI credential manager and reference them with credential_uuid."},"credential_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credential Uuid","description":"Reference to an external credential for request authentication.","llm_hint":"Use a credential_uuid returned by list_credentials. The MCP flow does not create credential secrets."},"parameters":{"anyOf":[{"items":{"$ref":"#/components/schemas/ToolParameter"},"type":"array"},{"type":"null"}],"title":"Parameters","description":"Parameters the model must provide when calling this tool."},"preset_parameters":{"anyOf":[{"items":{"$ref":"#/components/schemas/PresetToolParameter"},"type":"array"},{"type":"null"}],"title":"Preset Parameters","description":"Parameters injected by Dograh from fixed values or workflow context templates."},"timeout_ms":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Timeout Ms","description":"Request timeout in milliseconds.","default":5000},"customMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custommessage","description":"Custom message to play after tool execution."},"customMessageType":{"anyOf":[{"type":"string","enum":["text","audio"]},{"type":"null"}],"title":"Custommessagetype","description":"Type of custom message."},"customMessageRecordingId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custommessagerecordingid","description":"Recording ID for an audio custom message."}},"type":"object","required":["method","url"],"title":"HttpApiConfig","description":"Configuration for HTTP API tools."},"HttpApiToolDefinition":{"properties":{"schema_version":{"type":"integer","title":"Schema Version","description":"Schema version.","default":1},"type":{"type":"string","const":"http_api","title":"Type","description":"Tool type."},"config":{"$ref":"#/components/schemas/HttpApiConfig","description":"HTTP API configuration."}},"type":"object","required":["type","config"],"title":"HttpApiToolDefinition","description":"Tool definition for HTTP API tools."},"ImpersonateRequest":{"properties":{"provider_user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider User Id"},"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"}},"type":"object","title":"ImpersonateRequest","description":"Request payload for superadmin impersonation.\n\nEither ``provider_user_id`` **or** ``user_id`` must be supplied. If both are\nprovided, ``provider_user_id`` takes precedence."},"ImpersonateResponse":{"properties":{"refresh_token":{"type":"string","title":"Refresh Token"},"access_token":{"type":"string","title":"Access Token"}},"type":"object","required":["refresh_token","access_token"],"title":"ImpersonateResponse"},"InitEmbedRequest":{"properties":{"token":{"type":"string","title":"Token"},"context_variables":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Context Variables"}},"type":"object","required":["token"],"title":"InitEmbedRequest","description":"Request model for initializing an embed session"},"InitEmbedResponse":{"properties":{"session_token":{"type":"string","title":"Session Token"},"workflow_run_id":{"type":"integer","title":"Workflow Run Id"},"config":{"additionalProperties":true,"type":"object","title":"Config"}},"type":"object","required":["session_token","workflow_run_id","config"],"title":"InitEmbedResponse","description":"Response model for embed initialization"},"InitiateCallRequest":{"properties":{"workflow_id":{"type":"integer","title":"Workflow Id"},"workflow_run_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Workflow Run Id"},"phone_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone Number"},"telephony_configuration_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Telephony Configuration Id"},"from_phone_number_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"From Phone Number Id"}},"type":"object","required":["workflow_id"],"title":"InitiateCallRequest"},"ItemKind":{"type":"string","enum":["node","edge","workflow"],"title":"ItemKind"},"LangfuseCredentialsRequest":{"properties":{"host":{"type":"string","title":"Host"},"public_key":{"type":"string","title":"Public Key"},"secret_key":{"type":"string","title":"Secret Key"}},"type":"object","required":["host","public_key","secret_key"],"title":"LangfuseCredentialsRequest"},"LangfuseCredentialsResponse":{"properties":{"host":{"type":"string","title":"Host","default":""},"public_key":{"type":"string","title":"Public Key","default":""},"secret_key":{"type":"string","title":"Secret Key","default":""},"configured":{"type":"boolean","title":"Configured","default":false}},"type":"object","title":"LangfuseCredentialsResponse"},"LastCampaignSettingsResponse":{"properties":{"retry_config":{"anyOf":[{"$ref":"#/components/schemas/RetryConfigResponse"},{"type":"null"}]},"max_concurrency":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Concurrency"},"schedule_config":{"anyOf":[{"$ref":"#/components/schemas/ScheduleConfigResponse"},{"type":"null"}]},"circuit_breaker":{"anyOf":[{"$ref":"#/components/schemas/CircuitBreakerConfigResponse"},{"type":"null"}]}},"type":"object","title":"LastCampaignSettingsResponse"},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest"},"MPSBillingAccountResponse":{"properties":{"id":{"type":"integer","title":"Id"},"organization_id":{"type":"integer","title":"Organization Id"},"billing_mode":{"type":"string","title":"Billing Mode"},"cached_balance_credits":{"type":"number","title":"Cached Balance Credits"},"currency":{"type":"string","title":"Currency"}},"type":"object","required":["id","organization_id","billing_mode","cached_balance_credits","currency"],"title":"MPSBillingAccountResponse"},"MPSBillingCreditsResponse":{"properties":{"billing_version":{"type":"string","enum":["legacy","v2"],"title":"Billing Version"},"total_credits_used":{"type":"number","title":"Total Credits Used","default":0.0},"remaining_credits":{"type":"number","title":"Remaining Credits","default":0.0},"total_quota":{"type":"number","title":"Total Quota","default":0.0},"account":{"anyOf":[{"$ref":"#/components/schemas/MPSBillingAccountResponse"},{"type":"null"}]},"ledger_entries":{"items":{"$ref":"#/components/schemas/MPSCreditLedgerEntryResponse"},"type":"array","title":"Ledger Entries"},"total_count":{"type":"integer","title":"Total Count","default":0},"page":{"type":"integer","title":"Page","default":1},"limit":{"type":"integer","title":"Limit","default":50},"total_pages":{"type":"integer","title":"Total Pages","default":0}},"type":"object","required":["billing_version"],"title":"MPSBillingCreditsResponse"},"MPSCreditLedgerEntryResponse":{"properties":{"id":{"type":"integer","title":"Id"},"entry_type":{"type":"string","title":"Entry Type"},"origin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin"},"credits_delta":{"type":"number","title":"Credits Delta"},"balance_after":{"type":"number","title":"Balance After"},"amount_minor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Amount Minor"},"amount_currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Amount Currency"},"payment_order_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Payment Order Id"},"metric_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metric Code"},"correlation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Correlation Id"},"aggregation_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aggregation Key"},"usage_event_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Usage Event Id"},"workflow_run_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Workflow Run Id"},"workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Workflow Id"},"billable_quantity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Billable Quantity"},"quantity_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quantity Unit"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","entry_type","credits_delta","balance_after","created_at"],"title":"MPSCreditLedgerEntryResponse"},"MPSCreditPurchaseUrlResponse":{"properties":{"checkout_url":{"type":"string","title":"Checkout Url"}},"type":"object","required":["checkout_url"],"title":"MPSCreditPurchaseUrlResponse"},"MPSCreditsResponse":{"properties":{"total_credits_used":{"type":"number","title":"Total Credits Used"},"remaining_credits":{"type":"number","title":"Remaining Credits"},"total_quota":{"type":"number","title":"Total Quota"}},"type":"object","required":["total_credits_used","remaining_credits","total_quota"],"title":"MPSCreditsResponse"},"McpRefreshResponse":{"properties":{"tool_uuid":{"type":"string","title":"Tool Uuid"},"discovered_tools":{"items":{},"type":"array","title":"Discovered Tools"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["tool_uuid"],"title":"McpRefreshResponse","description":"Result of re-discovering an MCP server's tool catalog."},"McpToolConfig":{"properties":{"transport":{"type":"string","const":"streamable_http","title":"Transport","description":"MCP transport protocol.","default":"streamable_http"},"url":{"type":"string","title":"Url","description":"MCP server URL. Must use http:// or https://.","llm_hint":"Use the server's streamable HTTP MCP endpoint."},"credential_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credential Uuid","description":"Reference to an external credential for MCP server auth.","llm_hint":"Use a credential_uuid returned by list_credentials. Credentials are created by the user in the UI."},"tools_filter":{"items":{"type":"string"},"type":"array","title":"Tools Filter","description":"Allowlist of MCP tool names to expose. Empty exposes all tools.","llm_hint":"Use exact MCP tool names from the remote server catalog when you need to restrict the exposed tools."},"timeout_secs":{"type":"integer","minimum":0.0,"title":"Timeout Secs","description":"Connection timeout in seconds.","default":30},"sse_read_timeout_secs":{"type":"integer","minimum":0.0,"title":"Sse Read Timeout Secs","description":"SSE read timeout in seconds.","default":300},"discovered_tools":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Discovered Tools","description":"Server-managed cache of the MCP server's tool catalog [{name, description}]. Populated best-effort by the backend.","llm_hint":"Do not author this field; the server fills it."}},"type":"object","required":["url"],"title":"McpToolConfig","description":"Configuration for a customer MCP server tool definition."},"McpToolDefinition":{"properties":{"schema_version":{"type":"integer","title":"Schema Version","description":"Schema version.","default":1},"type":{"type":"string","const":"mcp","title":"Type","description":"Tool type."},"config":{"$ref":"#/components/schemas/McpToolConfig","description":"MCP server configuration."}},"type":"object","required":["type","config"],"title":"McpToolDefinition","description":"Persisted MCP tool definition."},"MiniMaxLLMConfiguration":{"properties":{"provider":{"type":"string","const":"minimax","title":"Provider","default":"minimax"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"MiniMax chat model.","default":"MiniMax-M2.7","examples":["MiniMax-M2.7","MiniMax-M2.7-highspeed"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"MiniMax OpenAI-compatible API endpoint.","default":"https://api.minimax.io/v1"},"temperature":{"type":"number","maximum":2.0,"exclusiveMinimum":0.0,"title":"Temperature","description":"Sampling temperature. MiniMax requires > 0.","default":1.0}},"type":"object","required":["api_key"],"title":"MiniMaxLLMConfiguration"},"MiniMaxTTSConfiguration":{"properties":{"provider":{"type":"string","const":"minimax","title":"Provider","default":"minimax"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"MiniMax TTS model.","default":"speech-2.8-hd","examples":["speech-2.8-hd","speech-2.8-turbo"]},"voice":{"type":"string","title":"Voice","description":"MiniMax voice ID.","default":"English_Graceful_Lady","examples":["English_Graceful_Lady","English_Insightful_Speaker","English_radiant_girl","English_Persuasive_Man","English_Lucky_Robot","English_expressive_narrator"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"MiniMax TTS API endpoint (must include the /v1/t2a_v2 path). Defaults to the global endpoint; override with https://api.minimaxi.chat/v1/t2a_v2 (mainland China) or https://api-uw.minimax.io/v1/t2a_v2 (US-West).","default":"https://api.minimax.io/v1/t2a_v2"},"speed":{"type":"number","maximum":2.0,"minimum":0.5,"title":"Speed","description":"Speech speed (0.5 to 2.0).","default":1.0},"group_id":{"type":"string","title":"Group Id","description":"MiniMax Group ID (found in your MiniMax dashboard under Account \u2192 Group)."}},"type":"object","required":["api_key","group_id"],"title":"MiniMaxTTSConfiguration"},"MoveWorkflowToFolderRequest":{"properties":{"folder_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Folder Id"}},"type":"object","title":"MoveWorkflowToFolderRequest","description":"Move a workflow into a folder, or to \"Uncategorized\" when null."},"NodeCategory":{"type":"string","enum":["call_node","global_node","trigger","integration"],"title":"NodeCategory","description":"Drives grouping in the AddNodePanel UI."},"NodeExample":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"data":{"additionalProperties":true,"type":"object","title":"Data"}},"additionalProperties":false,"type":"object","required":["name","data"],"title":"NodeExample","description":"A worked example LLMs can pattern-match. Keep small and realistic."},"NodeSpec":{"properties":{"name":{"type":"string","title":"Name"},"display_name":{"type":"string","title":"Display Name"},"description":{"type":"string","minLength":1,"title":"Description","description":"Human-facing explanation shown in AddNodePanel."},"llm_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Hint","description":"LLM-only guidance; omitted from the UI."},"category":{"$ref":"#/components/schemas/NodeCategory"},"icon":{"type":"string","title":"Icon"},"version":{"type":"string","title":"Version","default":"1.0.0"},"properties":{"items":{"$ref":"#/components/schemas/PropertySpec"},"type":"array","title":"Properties"},"examples":{"items":{"$ref":"#/components/schemas/NodeExample"},"type":"array","title":"Examples"},"graph_constraints":{"anyOf":[{"$ref":"#/components/schemas/GraphConstraints"},{"type":"null"}]}},"additionalProperties":false,"type":"object","required":["name","display_name","description","category","icon","properties"],"title":"NodeSpec","description":"Single source of truth for a node type."},"NodeTypesResponse":{"properties":{"spec_version":{"type":"string","title":"Spec Version"},"node_types":{"items":{"$ref":"#/components/schemas/NodeSpec"},"type":"array","title":"Node Types"}},"type":"object","required":["spec_version","node_types"],"title":"NodeTypesResponse"},"OnboardingState":{"properties":{"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"skipped":{"type":"boolean","title":"Skipped","default":false},"seen_tooltips":{"items":{"type":"string"},"type":"array","title":"Seen Tooltips"},"completed_actions":{"items":{"type":"string"},"type":"array","title":"Completed Actions"}},"type":"object","title":"OnboardingState","description":"Per-user onboarding state, stored under UserConfigurationKey.ONBOARDING.\n\nServer-authoritative replacement for the browser-localStorage onboarding\nstore, so the post-signup gate and one-time tooltips hold across devices."},"OnboardingStateUpdate":{"properties":{"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"skipped":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Skipped"},"seen_tooltips":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Seen Tooltips"},"completed_actions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Completed Actions"}},"type":"object","title":"OnboardingStateUpdate","description":"Partial update merged into the stored state.\n\nScalars overwrite when supplied; list entries are unioned into the stored\nlists, so concurrent updates (e.g. two tabs marking different tooltips)\ndon't drop each other's items."},"OpenAIEmbeddingsConfiguration":{"properties":{"provider":{"type":"string","const":"openai","title":"Provider","default":"openai"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenAI embedding model.","default":"text-embedding-3-small","examples":["text-embedding-3-small"]}},"type":"object","required":["api_key"],"title":"OpenAI"},"OpenAILLMService":{"properties":{"provider":{"type":"string","const":"openai","title":"Provider","default":"openai"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenAI chat model to use.","default":"gpt-4.1","examples":["gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","gpt-5","gpt-5-mini","gpt-5-nano","gpt-3.5-turbo"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"Override only if using an OpenAI-compatible API (e.g. local LLM, proxy).","default":"https://api.openai.com/v1"}},"type":"object","required":["api_key"],"title":"OpenAI"},"OpenAIRealtimeLLMConfiguration":{"properties":{"provider":{"type":"string","const":"openai_realtime","title":"Provider","default":"openai_realtime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenAI realtime (speech-to-speech) model.","default":"gpt-realtime-2","examples":["gpt-realtime-2"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Voice the model speaks in.","default":"alloy","examples":["alloy","ash","ballad","coral","echo","sage","shimmer","verse"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"OpenAI Realtime"},"OpenAISTTConfiguration":{"properties":{"provider":{"type":"string","const":"openai","title":"Provider","default":"openai"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenAI transcription model.","default":"gpt-4o-transcribe","examples":["gpt-4o-transcribe"]},"base_url":{"type":"string","title":"Base Url","description":"Override only if using an OpenAI-compatible API (e.g. local STT, proxy).","default":"https://api.openai.com/v1"}},"type":"object","required":["api_key"],"title":"OpenAI"},"OpenAITTSService":{"properties":{"provider":{"type":"string","const":"openai","title":"Provider","default":"openai"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenAI TTS model.","default":"gpt-4o-mini-tts","examples":["gpt-4o-mini-tts"]},"voice":{"type":"string","title":"Voice","description":"OpenAI TTS voice name.","default":"alloy"},"base_url":{"type":"string","title":"Base Url","description":"Override only if using an OpenAI-compatible API (e.g. local TTS, proxy).","default":"https://api.openai.com/v1"}},"type":"object","required":["api_key"],"title":"OpenAI"},"OpenRouterEmbeddingsConfiguration":{"properties":{"provider":{"type":"string","const":"openrouter","title":"Provider","default":"openrouter"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenRouter-hosted embedding model slug.","default":"openai/text-embedding-3-small","examples":["openai/text-embedding-3-small"]},"base_url":{"type":"string","title":"Base Url","description":"Override only if proxying OpenRouter through your own gateway.","default":"https://openrouter.ai/api/v1"}},"type":"object","required":["api_key"],"title":"Open Router"},"OpenRouterLLMConfiguration":{"properties":{"provider":{"type":"string","const":"openrouter","title":"Provider","default":"openrouter"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenRouter model slug in 'vendor/model' form.","default":"openai/gpt-4.1","examples":["openai/gpt-4.1","openai/gpt-4.1-mini","anthropic/claude-sonnet-4","google/gemini-2.5-flash","google/gemini-2.0-flash","meta-llama/llama-3.3-70b-instruct","deepseek/deepseek-chat-v3-0324"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"Override only if proxying OpenRouter through your own gateway.","default":"https://openrouter.ai/api/v1"}},"type":"object","required":["api_key"],"title":"Open Router"},"OrganizationAIModelConfigurationResponse":{"properties":{"configuration":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Configuration"},"effective_configuration":{"additionalProperties":true,"type":"object","title":"Effective Configuration"},"source":{"type":"string","enum":["organization_v2","legacy_user_v1","empty"],"title":"Source"}},"type":"object","required":["configuration","effective_configuration","source"],"title":"OrganizationAIModelConfigurationResponse"},"OrganizationAIModelConfigurationV2":{"properties":{"version":{"type":"integer","const":2,"title":"Version","default":2},"mode":{"type":"string","enum":["dograh","byok"],"title":"Mode"},"dograh":{"anyOf":[{"$ref":"#/components/schemas/DograhManagedAIModelConfiguration"},{"type":"null"}]},"byok":{"anyOf":[{"$ref":"#/components/schemas/BYOKAIModelConfiguration"},{"type":"null"}]}},"type":"object","required":["mode"],"title":"OrganizationAIModelConfigurationV2"},"OrganizationContextResponse":{"properties":{"organization_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Organization Id"},"organization_provider_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organization Provider Id"},"model_services":{"$ref":"#/components/schemas/OrganizationModelServicesContext"}},"type":"object","required":["model_services"],"title":"OrganizationContextResponse"},"OrganizationModelServicesContext":{"properties":{"config_source":{"type":"string","enum":["organization_v2","legacy_user_v1","empty"],"title":"Config Source"},"has_model_configuration_v2":{"type":"boolean","title":"Has Model Configuration V2"},"managed_service_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Managed Service Version"},"uses_managed_service_v2":{"type":"boolean","title":"Uses Managed Service V2"}},"type":"object","required":["config_source","has_model_configuration_v2","uses_managed_service_v2"],"title":"OrganizationModelServicesContext"},"OrganizationPreferences":{"properties":{"test_phone_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Phone Number"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timezone"}},"type":"object","title":"OrganizationPreferences"},"PhoneNumberCreateRequest":{"properties":{"address":{"type":"string","maxLength":255,"minLength":1,"title":"Address"},"country_code":{"anyOf":[{"type":"string","maxLength":2,"minLength":2},{"type":"null"}],"title":"Country Code"},"label":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Label"},"inbound_workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inbound Workflow Id"},"is_active":{"type":"boolean","title":"Is Active","default":true},"is_default_caller_id":{"type":"boolean","title":"Is Default Caller Id","default":false},"extra_metadata":{"additionalProperties":true,"type":"object","title":"Extra Metadata"}},"type":"object","required":["address"],"title":"PhoneNumberCreateRequest","description":"Create a new phone number under a telephony configuration.\n\n``address_normalized`` and ``address_type`` are computed server-side from\n``address`` (and ``country_code`` if PSTN). ``address`` itself is stored\nverbatim for display."},"PhoneNumberListResponse":{"properties":{"phone_numbers":{"items":{"$ref":"#/components/schemas/PhoneNumberResponse"},"type":"array","title":"Phone Numbers"}},"type":"object","required":["phone_numbers"],"title":"PhoneNumberListResponse"},"PhoneNumberResponse":{"properties":{"id":{"type":"integer","title":"Id"},"telephony_configuration_id":{"type":"integer","title":"Telephony Configuration Id"},"address":{"type":"string","title":"Address"},"address_normalized":{"type":"string","title":"Address Normalized"},"address_type":{"type":"string","title":"Address Type"},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"inbound_workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inbound Workflow Id"},"inbound_workflow_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inbound Workflow Name"},"is_active":{"type":"boolean","title":"Is Active"},"is_default_caller_id":{"type":"boolean","title":"Is Default Caller Id"},"extra_metadata":{"additionalProperties":true,"type":"object","title":"Extra Metadata"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"provider_sync":{"anyOf":[{"$ref":"#/components/schemas/ProviderSyncStatus"},{"type":"null"}]}},"type":"object","required":["id","telephony_configuration_id","address","address_normalized","address_type","is_active","is_default_caller_id","extra_metadata","created_at","updated_at"],"title":"PhoneNumberResponse"},"PhoneNumberUpdateRequest":{"properties":{"label":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Label"},"inbound_workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inbound Workflow Id"},"clear_inbound_workflow":{"type":"boolean","title":"Clear Inbound Workflow","default":false},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"country_code":{"anyOf":[{"type":"string","maxLength":2,"minLength":2},{"type":"null"}],"title":"Country Code"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"}},"type":"object","title":"PhoneNumberUpdateRequest","description":"Partial update. ``address`` is intentionally immutable \u2014 to change a\nnumber, delete the row and create a new one."},"PlivoConfigurationRequest":{"properties":{"provider":{"type":"string","const":"plivo","title":"Provider","default":"plivo"},"auth_id":{"type":"string","title":"Auth Id","description":"Plivo Auth ID"},"auth_token":{"type":"string","title":"Auth Token","description":"Plivo Auth Token"},"application_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Id","description":"Plivo Application ID. The application's answer_url is updated when inbound workflows are attached to numbers on this account. If omitted, an application is auto-created on save and its id is stored on the configuration."},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of Plivo phone numbers"}},"type":"object","required":["auth_id","auth_token"],"title":"PlivoConfigurationRequest","description":"Request schema for Plivo configuration."},"PlivoConfigurationResponse":{"properties":{"provider":{"type":"string","const":"plivo","title":"Provider","default":"plivo"},"auth_id":{"type":"string","title":"Auth Id"},"auth_token":{"type":"string","title":"Auth Token"},"application_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Id"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["auth_id","auth_token","from_numbers"],"title":"PlivoConfigurationResponse","description":"Response schema for Plivo configuration with masked sensitive fields."},"PresetToolParameter":{"properties":{"name":{"type":"string","title":"Name","description":"Parameter name used as a key in the request body."},"type":{"type":"string","enum":["string","number","boolean","object","array"],"title":"Type","description":"JSON type for the resolved value.","llm_hint":"Allowed values are string, number, boolean, object, and array."},"value_template":{"type":"string","title":"Value Template","description":"Fixed value or template, e.g. {{initial_context.phone_number}}.","llm_hint":"Use {{initial_context.*}} for call-start context and {{gathered_context.*}} for values extracted during the call."},"required":{"type":"boolean","title":"Required","description":"Whether the parameter must resolve to a non-empty value.","default":true}},"type":"object","required":["name","type","value_template"],"title":"PresetToolParameter","description":"A parameter injected by Dograh at runtime."},"PresignedUploadUrlRequest":{"properties":{"file_name":{"type":"string","pattern":".*\\.csv$","title":"File Name","description":"CSV filename"},"file_size":{"type":"integer","maximum":10485760.0,"exclusiveMinimum":0.0,"title":"File Size","description":"File size in bytes (max 10MB)"},"content_type":{"type":"string","title":"Content Type","description":"File content type","default":"text/csv"}},"type":"object","required":["file_name","file_size"],"title":"PresignedUploadUrlRequest"},"PresignedUploadUrlResponse":{"properties":{"upload_url":{"type":"string","title":"Upload Url"},"file_key":{"type":"string","title":"File Key"},"expires_in":{"type":"integer","title":"Expires In"}},"type":"object","required":["upload_url","file_key","expires_in"],"title":"PresignedUploadUrlResponse"},"ProcessDocumentRequestSchema":{"properties":{"document_uuid":{"type":"string","title":"Document Uuid","description":"Document UUID to process"},"s3_key":{"type":"string","title":"S3 Key","description":"S3 key of the uploaded file"},"retrieval_mode":{"type":"string","title":"Retrieval Mode","description":"Retrieval mode: 'chunked' for vector search or 'full_document' for full text retrieval","default":"chunked"}},"type":"object","required":["document_uuid","s3_key"],"title":"ProcessDocumentRequestSchema","description":"Request schema for triggering document processing."},"PropertyOption":{"properties":{"value":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"boolean"},{"type":"number"}],"title":"Value"},"label":{"type":"string","title":"Label"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"additionalProperties":false,"type":"object","required":["value","label"],"title":"PropertyOption","description":"An option in an `options` or `multi_options` dropdown."},"PropertySpec":{"properties":{"name":{"type":"string","title":"Name"},"type":{"$ref":"#/components/schemas/PropertyType"},"display_name":{"type":"string","title":"Display Name"},"description":{"type":"string","minLength":1,"title":"Description","description":"Human-facing explanation shown in the UI."},"llm_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Hint","description":"LLM-only guidance; omitted from the UI."},"default":{"title":"Default"},"required":{"type":"boolean","title":"Required","default":false},"placeholder":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Placeholder"},"display_options":{"anyOf":[{"$ref":"#/components/schemas/DisplayOptions"},{"type":"null"}]},"options":{"anyOf":[{"items":{"$ref":"#/components/schemas/PropertyOption"},"type":"array"},{"type":"null"}],"title":"Options"},"properties":{"anyOf":[{"items":{"$ref":"#/components/schemas/PropertySpec"},"type":"array"},{"type":"null"}],"title":"Properties"},"min_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Value"},"max_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Value"},"min_length":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Length"},"max_length":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Length"},"pattern":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pattern"},"editor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Editor"},"extra":{"additionalProperties":true,"type":"object","title":"Extra"}},"additionalProperties":false,"type":"object","required":["name","type","display_name","description"],"title":"PropertySpec","description":"Single field on a node.\n\n`description` is HUMAN-FACING \u2014 shown under the field in the edit\ndialog. Keep it concise and explain what the field does.\n\n`llm_hint` is LLM-FACING \u2014 appears only in the `get_node_type` MCP\nresponse and in SDK schema output. Use it for catalog tool references\n(e.g., \"Use `list_recordings`\"), array shape, expected value idioms,\nor anything that would be noise in the UI. Optional; omit when the\n`description` already suffices for both audiences."},"PropertyType":{"type":"string","enum":["string","number","boolean","options","multi_options","fixed_collection","json","tool_refs","document_refs","recording_ref","credential_ref","mention_textarea","url"],"title":"PropertyType","description":"Bounded vocabulary of property types the renderer dispatches on.\n\nAdding a value here requires a matching arm in the frontend\n`` switch and (where relevant) the SDK codegen template."},"ProviderSyncStatus":{"properties":{"ok":{"type":"boolean","title":"Ok"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["ok"],"title":"ProviderSyncStatus","description":"Result of pushing a phone-number change to the upstream provider.\n\nReturned alongside create/update responses when the route attempted to\nsync inbound webhook configuration. ``ok=False`` is a warning, not a\nfatal error \u2014 the DB write succeeded."},"RecordingCreateRequestSchema":{"properties":{"recording_id":{"type":"string","title":"Recording Id","description":"Short recording ID from upload step"},"tts_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tts Provider","description":"TTS provider (e.g. elevenlabs)"},"tts_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tts Model","description":"TTS model name"},"tts_voice_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tts Voice Id","description":"TTS voice identifier"},"transcript":{"type":"string","title":"Transcript","description":"User-provided transcript of the recording"},"storage_key":{"type":"string","title":"Storage Key","description":"Storage key from upload step"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata","description":"Optional metadata (file_size, duration, etc.)"}},"type":"object","required":["recording_id","transcript","storage_key"],"title":"RecordingCreateRequestSchema","description":"Request schema for creating a recording record after upload."},"RecordingListResponseSchema":{"properties":{"recordings":{"items":{"$ref":"#/components/schemas/RecordingResponseSchema"},"type":"array","title":"Recordings"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["recordings","total"],"title":"RecordingListResponseSchema","description":"Response schema for list of recordings."},"RecordingResponseSchema":{"properties":{"id":{"type":"integer","title":"Id"},"recording_id":{"type":"string","title":"Recording Id"},"workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Workflow Id"},"organization_id":{"type":"integer","title":"Organization Id"},"tts_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tts Provider"},"tts_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tts Model"},"tts_voice_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tts Voice Id"},"transcript":{"type":"string","title":"Transcript"},"storage_key":{"type":"string","title":"Storage Key"},"storage_backend":{"type":"string","title":"Storage Backend"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_by":{"type":"integer","title":"Created By"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","recording_id","organization_id","transcript","storage_key","storage_backend","metadata","created_by","created_at","is_active"],"title":"RecordingResponseSchema","description":"Response schema for a single recording."},"RecordingUpdateRequestSchema":{"properties":{"recording_id":{"type":"string","maxLength":64,"minLength":1,"pattern":"^[a-zA-Z0-9_-]+$","title":"Recording Id","description":"New descriptive recording ID (letters, numbers, hyphens, underscores only)"}},"type":"object","required":["recording_id"],"title":"RecordingUpdateRequestSchema","description":"Request schema for updating a recording's ID."},"RecordingUploadResponseSchema":{"properties":{"upload_url":{"type":"string","title":"Upload Url","description":"Presigned URL for uploading the audio"},"recording_id":{"type":"string","title":"Recording Id","description":"Short unique recording ID"},"storage_key":{"type":"string","title":"Storage Key","description":"Storage key where file will be uploaded"}},"type":"object","required":["upload_url","recording_id","storage_key"],"title":"RecordingUploadResponseSchema","description":"Response schema with presigned upload URL."},"RedialCampaignRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name","description":"Name for the redial campaign"},"retry_on_voicemail":{"type":"boolean","title":"Retry On Voicemail","default":true},"retry_on_no_answer":{"type":"boolean","title":"Retry On No Answer","default":true},"retry_on_busy":{"type":"boolean","title":"Retry On Busy","default":true},"retry_config":{"anyOf":[{"$ref":"#/components/schemas/RetryConfigRequest"},{"type":"null"}]}},"type":"object","title":"RedialCampaignRequest"},"RetryConfigRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"max_retries":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"Max Retries","default":2},"retry_delay_seconds":{"type":"integer","maximum":3600.0,"minimum":30.0,"title":"Retry Delay Seconds","default":120},"retry_on_busy":{"type":"boolean","title":"Retry On Busy","default":true},"retry_on_no_answer":{"type":"boolean","title":"Retry On No Answer","default":true},"retry_on_voicemail":{"type":"boolean","title":"Retry On Voicemail","default":true}},"type":"object","title":"RetryConfigRequest"},"RetryConfigResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"max_retries":{"type":"integer","title":"Max Retries"},"retry_delay_seconds":{"type":"integer","title":"Retry Delay Seconds"},"retry_on_busy":{"type":"boolean","title":"Retry On Busy"},"retry_on_no_answer":{"type":"boolean","title":"Retry On No Answer"},"retry_on_voicemail":{"type":"boolean","title":"Retry On Voicemail"}},"type":"object","required":["enabled","max_retries","retry_delay_seconds","retry_on_busy","retry_on_no_answer","retry_on_voicemail"],"title":"RetryConfigResponse"},"RewindTextChatSessionRequest":{"properties":{"cursor_turn_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor Turn Id"},"expected_revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Revision"}},"type":"object","title":"RewindTextChatSessionRequest"},"RimeTTSConfiguration":{"properties":{"provider":{"type":"string","const":"rime","title":"Provider","default":"rime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Rime TTS model.","default":"arcana","examples":["arcana","mistv3","mistv2","mist"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Rime voice ID.","default":"celeste"},"speed":{"type":"number","maximum":2.0,"minimum":0.5,"title":"Speed","description":"Speech speed multiplier.","default":1.0},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code.","default":"en","examples":["en","de","fr","es","hi"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Rime"},"S3SignedUrlResponse":{"properties":{"url":{"type":"string","title":"Url"},"expires_in":{"type":"integer","title":"Expires In"}},"type":"object","required":["url","expires_in"],"title":"S3SignedUrlResponse"},"SarvamLLMConfiguration":{"properties":{"provider":{"type":"string","const":"sarvam","title":"Provider","default":"sarvam"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Sarvam chat model. Use sarvam-30b for low-latency voice agents; sarvam-105b for complex multi-step reasoning.","default":"sarvam-30b","examples":["sarvam-30b","sarvam-105b"],"allow_custom_input":true},"temperature":{"type":"number","maximum":2.0,"minimum":0.0,"title":"Temperature","description":"Sampling temperature. Sarvam recommends 0.5 for balanced conversational responses.","default":0.5}},"type":"object","required":["api_key"],"title":"Sarvam"},"SarvamSTTConfiguration":{"properties":{"provider":{"type":"string","const":"sarvam","title":"Provider","default":"sarvam"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Sarvam STT model. saarika:v2.5 transcribes in the spoken language; saaras:v3 is the recommended model with flexible output modes.","default":"saarika:v2.5","examples":["saarika:v2.5","saaras:v3"]},"language":{"type":"string","title":"Language","description":"BCP-47 language code. Use unknown for automatic language detection.","default":"unknown","examples":["unknown","hi-IN","bn-IN","gu-IN","kn-IN","ml-IN","mr-IN","od-IN","pa-IN","ta-IN","te-IN","en-IN"],"model_options":{"saaras:v3":["unknown","hi-IN","bn-IN","gu-IN","kn-IN","ml-IN","mr-IN","od-IN","pa-IN","ta-IN","te-IN","en-IN","as-IN","ur-IN","ne-IN","kok-IN","ks-IN","sd-IN","sa-IN","sat-IN","mni-IN","brx-IN","mai-IN","doi-IN"],"saarika:v2.5":["unknown","hi-IN","bn-IN","gu-IN","kn-IN","ml-IN","mr-IN","od-IN","pa-IN","ta-IN","te-IN","en-IN"]}}},"type":"object","required":["api_key"],"title":"Sarvam"},"SarvamTTSConfiguration":{"properties":{"provider":{"type":"string","const":"sarvam","title":"Provider","default":"sarvam"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Sarvam TTS model (voice list depends on this).","default":"bulbul:v2","examples":["bulbul:v2","bulbul:v3"]},"voice":{"type":"string","title":"Voice","description":"Sarvam voice name; must match the selected model's voice list.","default":"anushka","examples":["anushka","manisha","vidya","arya","abhilash","karun","hitesh"],"model_options":{"bulbul:v2":["anushka","manisha","vidya","arya","abhilash","karun","hitesh"],"bulbul:v3":["shubh","aditya","ritu","priya","neha","rahul","pooja","rohan","simran","kavya","amit","dev","ishita","shreya","ratan","varun","manan","sumit","roopa","kabir","aayan","ashutosh","advait","amelia","sophia","anand","tanya","tarun","sunny","mani","gokul","vijay","shruti","suhani","mohit","kavitha","rehan","soham","rupali"]}},"language":{"type":"string","title":"Language","description":"BCP-47 Indian-language code (e.g. hi-IN, en-IN).","default":"hi-IN","examples":["bn-IN","en-IN","gu-IN","hi-IN","kn-IN","ml-IN","mr-IN","od-IN","pa-IN","ta-IN","te-IN","as-IN"]}},"type":"object","required":["api_key"],"title":"Sarvam"},"ScheduleConfigRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"timezone":{"type":"string","title":"Timezone","default":"UTC"},"slots":{"items":{"$ref":"#/components/schemas/TimeSlotRequest"},"type":"array","maxItems":50,"minItems":1,"title":"Slots"}},"type":"object","required":["slots"],"title":"ScheduleConfigRequest"},"ScheduleConfigResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"timezone":{"type":"string","title":"Timezone"},"slots":{"items":{"$ref":"#/components/schemas/TimeSlotResponse"},"type":"array","title":"Slots"}},"type":"object","required":["enabled","timezone","slots"],"title":"ScheduleConfigResponse"},"ServiceKeyResponse":{"properties":{"name":{"type":"string","title":"Name"},"id":{"type":"integer","title":"Id"},"key_prefix":{"type":"string","title":"Key Prefix"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"archived_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Archived At"},"created_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By"}},"type":"object","required":["name","id","key_prefix","is_active","created_at"],"title":"ServiceKeyResponse"},"SignupRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},"type":"object","required":["email","password"],"title":"SignupRequest"},"SpeachesLLMConfiguration":{"properties":{"provider":{"type":"string","const":"speaches","title":"Provider","default":"speaches"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Usually not required for self-hosted endpoints. Leave blank unless your server enforces one."},"model":{"type":"string","title":"Model","description":"Model name as exposed by your OpenAI-compatible server.","default":"llama3","examples":["llama3","mistral","phi3","qwen2","gemma2","deepseek-r1"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"OpenAI-compatible endpoint (Ollama, vLLM, etc.).","default":"http://localhost:11434/v1"}},"type":"object","title":"Local Models (Speaches)","description":"Self-hosted OpenAI-compatible local models. See the Speaches project for setup and supported backends.","provider_docs_url":"https://github.com/speaches-ai/speaches"},"SpeachesSTTConfiguration":{"properties":{"provider":{"type":"string","const":"speaches","title":"Provider","default":"speaches"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Usually not required for self-hosted STT. Leave blank unless enforced."},"model":{"type":"string","title":"Model","description":"Whisper model identifier as served by your STT endpoint.","default":"Systran/faster-distil-whisper-small.en","examples":["Systran/faster-distil-whisper-small.en","Systran/faster-whisper-large-v3"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code.","default":"en","examples":["en","ar","nl","fr","de","hi","it","pt","es"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"OpenAI-compatible STT endpoint (Speaches, etc.).","default":"http://localhost:8000/v1"}},"type":"object","title":"Local Models (Speaches)","description":"Self-hosted OpenAI-compatible local models. See the Speaches project for setup and supported backends.","provider_docs_url":"https://github.com/speaches-ai/speaches"},"SpeachesTTSConfiguration":{"properties":{"provider":{"type":"string","const":"speaches","title":"Provider","default":"speaches"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Usually not required for self-hosted TTS. Leave blank unless enforced."},"model":{"type":"string","title":"Model","description":"Model name as served by your TTS endpoint (e.g. Kokoro-FastAPI).","default":"kokoro","examples":["hexgrad/Kokoro-82M"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Voice ID for the TTS engine.","default":"af_heart","allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"OpenAI-compatible TTS endpoint (Kokoro-FastAPI, etc.).","default":"http://localhost:8000/v1"},"speed":{"type":"number","maximum":4.0,"minimum":0.25,"title":"Speed","description":"Speech speed (0.25 to 4.0).","default":1.0}},"type":"object","title":"Local Models (Speaches)","description":"Self-hosted OpenAI-compatible local models. See the Speaches project for setup and supported backends.","provider_docs_url":"https://github.com/speaches-ai/speaches"},"SpeechmaticsSTTConfiguration":{"properties":{"provider":{"type":"string","const":"speechmatics","title":"Provider","default":"speechmatics"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Speechmatics operating point: 'standard' or 'enhanced'.","default":"enhanced"},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code.","default":"en","examples":["ar","ar_en","ba","eu","be","bn","bg","yue","ca","hr","cs","da","nl","en","eo","et","fi","fr","gl","de","el","he","hi","hu","id","ia","ga","it","ja","ko","lv","lt","ms","en_ms","mt","cmn","cmn_en","cmn_en_ms_ta","mr","mn","no","fa","pl","pt","ro","ru","sk","sl","es","sw","sv","tl","ta","en_ta","th","tr","uk","ur","ug","vi","cy"]}},"type":"object","required":["api_key"],"title":"Speechmatics"},"SuperuserWorkflowRunResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"workflow_id":{"type":"integer","title":"Workflow Id"},"workflow_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workflow Name"},"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"},"organization_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Organization Id"},"organization_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organization Name"},"mode":{"type":"string","title":"Mode"},"is_completed":{"type":"boolean","title":"Is Completed"},"recording_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recording Url"},"transcript_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript Url"},"usage_info":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Usage Info"},"cost_info":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Cost Info"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"},"gathered_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Gathered Context"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","workflow_id","workflow_name","user_id","organization_id","organization_name","mode","is_completed","recording_url","transcript_url","usage_info","cost_info","initial_context","gathered_context","created_at"],"title":"SuperuserWorkflowRunResponse"},"SuperuserWorkflowRunsListResponse":{"properties":{"workflow_runs":{"items":{"$ref":"#/components/schemas/SuperuserWorkflowRunResponse"},"type":"array","title":"Workflow Runs"},"total_count":{"type":"integer","title":"Total Count"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["workflow_runs","total_count","page","limit","total_pages"],"title":"SuperuserWorkflowRunsListResponse"},"TelephonyConfigWarningsResponse":{"properties":{"telnyx_missing_webhook_public_key_count":{"type":"integer","title":"Telnyx Missing Webhook Public Key Count"}},"type":"object","required":["telnyx_missing_webhook_public_key_count"],"title":"TelephonyConfigWarningsResponse","description":"Aggregated telephony-configuration warning counts for the user's org.\n\nDrives the page banner and nav badge that nudge customers to finish\noptional-but-recommended configuration steps. Shape is a flat dict so\nnew warning types can be added without breaking the client."},"TelephonyConfigurationCreateRequest":{"properties":{"name":{"type":"string","maxLength":64,"minLength":1,"title":"Name"},"is_default_outbound":{"type":"boolean","title":"Is Default Outbound","default":false},"config":{"oneOf":[{"$ref":"#/components/schemas/ARIConfigurationRequest"},{"$ref":"#/components/schemas/CloudonixConfigurationRequest"},{"$ref":"#/components/schemas/PlivoConfigurationRequest"},{"$ref":"#/components/schemas/TelnyxConfigurationRequest"},{"$ref":"#/components/schemas/TwilioConfigurationRequest"},{"$ref":"#/components/schemas/VobizConfigurationRequest"},{"$ref":"#/components/schemas/VonageConfigurationRequest"}],"title":"Config","discriminator":{"propertyName":"provider","mapping":{"ari":"#/components/schemas/ARIConfigurationRequest","cloudonix":"#/components/schemas/CloudonixConfigurationRequest","plivo":"#/components/schemas/PlivoConfigurationRequest","telnyx":"#/components/schemas/TelnyxConfigurationRequest","twilio":"#/components/schemas/TwilioConfigurationRequest","vobiz":"#/components/schemas/VobizConfigurationRequest","vonage":"#/components/schemas/VonageConfigurationRequest"}}}},"type":"object","required":["name","config"],"title":"TelephonyConfigurationCreateRequest","description":"Body for ``POST /telephony-configs``.\n\n``config`` carries the provider-specific credential fields (the same\ndiscriminated union used by the legacy single-config endpoint). Any\n``from_numbers`` on the inner config are ignored \u2014 phone numbers are\nmanaged via the dedicated phone-numbers endpoints."},"TelephonyConfigurationDetail":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"provider":{"type":"string","title":"Provider"},"is_default_outbound":{"type":"boolean","title":"Is Default Outbound"},"credentials":{"additionalProperties":true,"type":"object","title":"Credentials"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","provider","is_default_outbound","credentials","created_at","updated_at"],"title":"TelephonyConfigurationDetail","description":"Body of ``GET /telephony-configs/{id}`` \u2014 credentials are masked."},"TelephonyConfigurationListItem":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"provider":{"type":"string","title":"Provider"},"is_default_outbound":{"type":"boolean","title":"Is Default Outbound"},"phone_number_count":{"type":"integer","title":"Phone Number Count","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","provider","is_default_outbound","created_at","updated_at"],"title":"TelephonyConfigurationListItem","description":"One row in ``GET /telephony-configs``."},"TelephonyConfigurationListResponse":{"properties":{"configurations":{"items":{"$ref":"#/components/schemas/TelephonyConfigurationListItem"},"type":"array","title":"Configurations"}},"type":"object","required":["configurations"],"title":"TelephonyConfigurationListResponse"},"TelephonyConfigurationResponse":{"properties":{"twilio":{"anyOf":[{"$ref":"#/components/schemas/TwilioConfigurationResponse"},{"type":"null"}]},"plivo":{"anyOf":[{"$ref":"#/components/schemas/PlivoConfigurationResponse"},{"type":"null"}]},"vonage":{"anyOf":[{"$ref":"#/components/schemas/VonageConfigurationResponse"},{"type":"null"}]},"vobiz":{"anyOf":[{"$ref":"#/components/schemas/VobizConfigurationResponse"},{"type":"null"}]},"cloudonix":{"anyOf":[{"$ref":"#/components/schemas/CloudonixConfigurationResponse"},{"type":"null"}]},"ari":{"anyOf":[{"$ref":"#/components/schemas/ARIConfigurationResponse"},{"type":"null"}]},"telnyx":{"anyOf":[{"$ref":"#/components/schemas/TelnyxConfigurationResponse"},{"type":"null"}]}},"type":"object","title":"TelephonyConfigurationResponse","description":"Top-level telephony configuration response.\n\nKeeps the per-provider field shape that the UI client depends on. When\nthe UI moves to metadata-driven forms, this can be replaced with a\nflat discriminated union."},"TelephonyConfigurationUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":64,"minLength":1},{"type":"null"}],"title":"Name"},"config":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/ARIConfigurationRequest"},{"$ref":"#/components/schemas/CloudonixConfigurationRequest"},{"$ref":"#/components/schemas/PlivoConfigurationRequest"},{"$ref":"#/components/schemas/TelnyxConfigurationRequest"},{"$ref":"#/components/schemas/TwilioConfigurationRequest"},{"$ref":"#/components/schemas/VobizConfigurationRequest"},{"$ref":"#/components/schemas/VonageConfigurationRequest"}],"discriminator":{"propertyName":"provider","mapping":{"ari":"#/components/schemas/ARIConfigurationRequest","cloudonix":"#/components/schemas/CloudonixConfigurationRequest","plivo":"#/components/schemas/PlivoConfigurationRequest","telnyx":"#/components/schemas/TelnyxConfigurationRequest","twilio":"#/components/schemas/TwilioConfigurationRequest","vobiz":"#/components/schemas/VobizConfigurationRequest","vonage":"#/components/schemas/VonageConfigurationRequest"}}},{"type":"null"}],"title":"Config"}},"type":"object","title":"TelephonyConfigurationUpdateRequest","description":"Body for ``PUT /telephony-configs/{id}``. Partial update."},"TelephonyProviderMetadata":{"properties":{"provider":{"type":"string","title":"Provider"},"display_name":{"type":"string","title":"Display Name"},"fields":{"items":{"$ref":"#/components/schemas/TelephonyProviderUIField"},"type":"array","title":"Fields"},"docs_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Docs Url"}},"type":"object","required":["provider","display_name","fields"],"title":"TelephonyProviderMetadata","description":"UI form metadata for a single telephony provider."},"TelephonyProviderUIField":{"properties":{"name":{"type":"string","title":"Name"},"label":{"type":"string","title":"Label"},"type":{"type":"string","title":"Type"},"required":{"type":"boolean","title":"Required"},"sensitive":{"type":"boolean","title":"Sensitive"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"placeholder":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Placeholder"}},"type":"object","required":["name","label","type","required","sensitive"],"title":"TelephonyProviderUIField","description":"One form field on a telephony provider's configuration UI."},"TelephonyProvidersMetadataResponse":{"properties":{"providers":{"items":{"$ref":"#/components/schemas/TelephonyProviderMetadata"},"type":"array","title":"Providers"}},"type":"object","required":["providers"],"title":"TelephonyProvidersMetadataResponse","description":"List of UI form definitions used by the telephony-config screen."},"TelnyxConfigurationRequest":{"properties":{"provider":{"type":"string","const":"telnyx","title":"Provider","default":"telnyx"},"api_key":{"type":"string","title":"Api Key","description":"Telnyx API Key"},"connection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connection Id","description":"Telnyx Call Control Application ID (connection_id). If omitted, a Call Control Application is auto-created on save and its id is stored on the configuration."},"webhook_public_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Public Key","description":"Webhook public key from Mission Control Portal \u2192 Keys & Credentials \u2192 Public Key. Used to verify Telnyx webhook signatures."},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of Telnyx phone numbers"}},"type":"object","required":["api_key"],"title":"TelnyxConfigurationRequest","description":"Request schema for Telnyx configuration."},"TelnyxConfigurationResponse":{"properties":{"provider":{"type":"string","const":"telnyx","title":"Provider","default":"telnyx"},"api_key":{"type":"string","title":"Api Key"},"connection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connection Id"},"webhook_public_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Public Key"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["api_key","from_numbers"],"title":"TelnyxConfigurationResponse","description":"Response schema for Telnyx configuration with masked sensitive fields."},"TimeSlotRequest":{"properties":{"day_of_week":{"type":"integer","maximum":6.0,"minimum":0.0,"title":"Day Of Week"},"start_time":{"type":"string","pattern":"^\\d{2}:\\d{2}$","title":"Start Time"},"end_time":{"type":"string","pattern":"^\\d{2}:\\d{2}$","title":"End Time"}},"type":"object","required":["day_of_week","start_time","end_time"],"title":"TimeSlotRequest"},"TimeSlotResponse":{"properties":{"day_of_week":{"type":"integer","title":"Day Of Week"},"start_time":{"type":"string","title":"Start Time"},"end_time":{"type":"string","title":"End Time"}},"type":"object","required":["day_of_week","start_time","end_time"],"title":"TimeSlotResponse"},"ToolParameter":{"properties":{"name":{"type":"string","title":"Name","description":"Parameter name used as a key in the tool request body.","llm_hint":"Use a stable snake_case name the agent can naturally fill."},"type":{"type":"string","enum":["string","number","boolean","object","array"],"title":"Type","description":"JSON type for the parameter value.","llm_hint":"Allowed values are string, number, boolean, object, and array."},"description":{"type":"string","title":"Description","description":"Description shown to the model for this parameter.","llm_hint":"Write this as an instruction to the agent: what value to provide and when."},"required":{"type":"boolean","title":"Required","description":"Whether this parameter is required when the tool is called.","default":true}},"type":"object","required":["name","type","description"],"title":"ToolParameter","description":"A parameter that the tool accepts from the model at call time."},"ToolResponse":{"properties":{"id":{"type":"integer","title":"Id"},"tool_uuid":{"type":"string","title":"Tool Uuid"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"category":{"type":"string","title":"Category"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"icon_color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon Color"},"status":{"type":"string","title":"Status"},"definition":{"additionalProperties":true,"type":"object","title":"Definition"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"created_by":{"anyOf":[{"$ref":"#/components/schemas/CreatedByResponse"},{"type":"null"}]}},"type":"object","required":["id","tool_uuid","name","description","category","icon","icon_color","status","definition","created_at","updated_at"],"title":"ToolResponse","description":"Response schema for a reusable tool."},"TransferCallConfig":{"properties":{"destination":{"type":"string","title":"Destination","description":"Phone number or SIP endpoint to transfer the call to, e.g. +1234567890 or PJSIP/1234."},"messageType":{"type":"string","enum":["none","custom","audio"],"title":"Messagetype","description":"Type of message to play before transfer.","default":"none"},"customMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custommessage","description":"Custom message to play before transferring."},"audioRecordingId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Audiorecordingid","description":"Recording ID for audio message before transfer."},"timeout":{"type":"integer","maximum":120.0,"minimum":5.0,"title":"Timeout","description":"Maximum seconds to wait for the destination to answer.","default":30}},"type":"object","required":["destination"],"title":"TransferCallConfig","description":"Configuration for Transfer Call tools."},"TransferCallToolDefinition":{"properties":{"schema_version":{"type":"integer","title":"Schema Version","description":"Schema version.","default":1},"type":{"type":"string","const":"transfer_call","title":"Type","description":"Tool type."},"config":{"$ref":"#/components/schemas/TransferCallConfig","description":"Transfer Call configuration."}},"type":"object","required":["type","config"],"title":"TransferCallToolDefinition","description":"Tool definition for Transfer Call tools."},"TriggerCallRequest":{"properties":{"phone_number":{"type":"string","title":"Phone Number"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"},"telephony_configuration_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Telephony Configuration Id"}},"type":"object","required":["phone_number"],"title":"TriggerCallRequest","description":"Request model for triggering a call via API"},"TriggerCallResponse":{"properties":{"status":{"type":"string","title":"Status"},"workflow_run_id":{"type":"integer","title":"Workflow Run Id"},"workflow_run_name":{"type":"string","title":"Workflow Run Name"}},"type":"object","required":["status","workflow_run_id","workflow_run_name"],"title":"TriggerCallResponse","description":"Response model for successful call initiation"},"TurnCredentialsResponse":{"properties":{"username":{"type":"string","title":"Username"},"password":{"type":"string","title":"Password"},"ttl":{"type":"integer","title":"Ttl"},"uris":{"items":{"type":"string"},"type":"array","title":"Uris"}},"type":"object","required":["username","password","ttl","uris"],"title":"TurnCredentialsResponse","description":"Response model for TURN credentials."},"TwilioConfigurationRequest":{"properties":{"provider":{"type":"string","const":"twilio","title":"Provider","default":"twilio"},"account_sid":{"type":"string","title":"Account Sid","description":"Twilio Account SID"},"auth_token":{"type":"string","title":"Auth Token","description":"Twilio Auth Token"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of Twilio phone numbers"}},"type":"object","required":["account_sid","auth_token"],"title":"TwilioConfigurationRequest","description":"Request schema for Twilio configuration."},"TwilioConfigurationResponse":{"properties":{"provider":{"type":"string","const":"twilio","title":"Provider","default":"twilio"},"account_sid":{"type":"string","title":"Account Sid"},"auth_token":{"type":"string","title":"Auth Token"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["account_sid","auth_token","from_numbers"],"title":"TwilioConfigurationResponse","description":"Response schema for Twilio configuration with masked sensitive fields."},"UltravoxRealtimeLLMConfiguration":{"properties":{"provider":{"type":"string","const":"ultravox_realtime","title":"Provider","default":"ultravox_realtime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Ultravox realtime voice-agent model.","default":"ultravox-v0.7","examples":["ultravox-v0.7","fixie-ai/ultravox"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Ultravox voice name or voice ID.","default":"Mark"}},"type":"object","required":["api_key"],"title":"Ultravox Realtime"},"UpdateCampaignRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name"},"retry_config":{"anyOf":[{"$ref":"#/components/schemas/RetryConfigRequest"},{"type":"null"}]},"max_concurrency":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":1.0},{"type":"null"}],"title":"Max Concurrency"},"schedule_config":{"anyOf":[{"$ref":"#/components/schemas/ScheduleConfigRequest"},{"type":"null"}]},"circuit_breaker":{"anyOf":[{"$ref":"#/components/schemas/CircuitBreakerConfigRequest"},{"type":"null"}]}},"type":"object","title":"UpdateCampaignRequest"},"UpdateCredentialRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"credential_type":{"anyOf":[{"$ref":"#/components/schemas/WebhookCredentialType"},{"type":"null"}]},"credential_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Credential Data"}},"type":"object","title":"UpdateCredentialRequest","description":"Request schema for updating a webhook credential."},"UpdateFolderRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"}},"type":"object","required":["name"],"title":"UpdateFolderRequest"},"UpdateToolRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"icon":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Icon"},"icon_color":{"anyOf":[{"type":"string","maxLength":7},{"type":"null"}],"title":"Icon Color"},"definition":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/HttpApiToolDefinition"},{"$ref":"#/components/schemas/EndCallToolDefinition"},{"$ref":"#/components/schemas/TransferCallToolDefinition"},{"$ref":"#/components/schemas/CalculatorToolDefinition"},{"$ref":"#/components/schemas/McpToolDefinition"}],"discriminator":{"propertyName":"type","mapping":{"calculator":"#/components/schemas/CalculatorToolDefinition","end_call":"#/components/schemas/EndCallToolDefinition","http_api":"#/components/schemas/HttpApiToolDefinition","mcp":"#/components/schemas/McpToolDefinition","transfer_call":"#/components/schemas/TransferCallToolDefinition"}}},{"type":"null"}],"title":"Definition"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},"type":"object","title":"UpdateToolRequest","description":"Request schema for updating a reusable tool."},"UpdateWorkflowRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"workflow_definition":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Workflow Definition"},"template_context_variables":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Template Context Variables"},"workflow_configurations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Workflow Configurations"}},"type":"object","title":"UpdateWorkflowRequest"},"UpdateWorkflowStatusRequest":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"UpdateWorkflowStatusRequest"},"UsageHistoryResponse":{"properties":{"runs":{"items":{"$ref":"#/components/schemas/WorkflowRunUsageResponse"},"type":"array","title":"Runs"},"total_dograh_tokens":{"type":"number","title":"Total Dograh Tokens"},"total_duration_seconds":{"type":"integer","title":"Total Duration Seconds"},"total_count":{"type":"integer","title":"Total Count"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["runs","total_dograh_tokens","total_duration_seconds","total_count","page","limit","total_pages"],"title":"UsageHistoryResponse"},"UserConfigurationRequestResponseSchema":{"properties":{"llm":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Llm"},"tts":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Tts"},"stt":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Stt"},"embeddings":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Embeddings"},"realtime":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Realtime"},"is_realtime":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Realtime"},"test_phone_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Phone Number"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timezone"},"organization_pricing":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},"type":"object"},{"type":"null"}],"title":"Organization Pricing"}},"type":"object","title":"UserConfigurationRequestResponseSchema"},"UserResponse":{"properties":{"id":{"type":"integer","title":"Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"organization_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Organization Id"},"provider_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Id"}},"type":"object","required":["id","email"],"title":"UserResponse"},"ValidateWorkflowResponse":{"properties":{"is_valid":{"type":"boolean","title":"Is Valid"},"errors":{"items":{"$ref":"#/components/schemas/WorkflowError"},"type":"array","title":"Errors"}},"type":"object","required":["is_valid","errors"],"title":"ValidateWorkflowResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VobizConfigurationRequest":{"properties":{"provider":{"type":"string","const":"vobiz","title":"Provider","default":"vobiz"},"auth_id":{"type":"string","title":"Auth Id","description":"Vobiz Account ID (e.g., MA_SYQRLN1K)"},"auth_token":{"type":"string","title":"Auth Token","description":"Vobiz Auth Token"},"application_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Id","description":"Vobiz Application ID. The application's answer_url is updated when inbound workflows are attached to numbers on this account. If omitted, an application is auto-created on save and its id is stored on the configuration."},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of Vobiz phone numbers (E.164 without + prefix)"}},"type":"object","required":["auth_id","auth_token"],"title":"VobizConfigurationRequest","description":"Request schema for Vobiz configuration."},"VobizConfigurationResponse":{"properties":{"provider":{"type":"string","const":"vobiz","title":"Provider","default":"vobiz"},"auth_id":{"type":"string","title":"Auth Id"},"auth_token":{"type":"string","title":"Auth Token"},"application_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Id"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["auth_id","auth_token","from_numbers"],"title":"VobizConfigurationResponse","description":"Response schema for Vobiz configuration with masked sensitive fields."},"VoiceInfo":{"properties":{"voice_id":{"type":"string","title":"Voice Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"accent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accent"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"preview_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview Url"}},"type":"object","required":["voice_id","name"],"title":"VoiceInfo"},"VoicesResponse":{"properties":{"provider":{"type":"string","title":"Provider"},"voices":{"items":{"$ref":"#/components/schemas/VoiceInfo"},"type":"array","title":"Voices"}},"type":"object","required":["provider","voices"],"title":"VoicesResponse"},"VonageConfigurationRequest":{"properties":{"provider":{"type":"string","const":"vonage","title":"Provider","default":"vonage"},"api_key":{"type":"string","title":"Api Key","description":"Vonage API Key"},"api_secret":{"type":"string","title":"Api Secret","description":"Vonage API Secret"},"application_id":{"type":"string","title":"Application Id","description":"Vonage Application ID"},"private_key":{"type":"string","title":"Private Key","description":"Private key for JWT generation"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of Vonage phone numbers (without + prefix)"}},"type":"object","required":["api_key","api_secret","application_id","private_key"],"title":"VonageConfigurationRequest","description":"Request schema for Vonage configuration."},"VonageConfigurationResponse":{"properties":{"provider":{"type":"string","const":"vonage","title":"Provider","default":"vonage"},"application_id":{"type":"string","title":"Application Id"},"api_key":{"type":"string","title":"Api Key"},"api_secret":{"type":"string","title":"Api Secret"},"private_key":{"type":"string","title":"Private Key"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["application_id","api_key","api_secret","private_key","from_numbers"],"title":"VonageConfigurationResponse","description":"Response schema for Vonage configuration with masked sensitive fields."},"WebhookCredentialType":{"type":"string","enum":["none","api_key","bearer_token","basic_auth","custom_header"],"title":"WebhookCredentialType","description":"Webhook credential authentication types"},"WorkflowCountResponse":{"properties":{"total":{"type":"integer","title":"Total"},"active":{"type":"integer","title":"Active"},"archived":{"type":"integer","title":"Archived"}},"type":"object","required":["total","active","archived"],"title":"WorkflowCountResponse","description":"Response for workflow count endpoint."},"WorkflowError":{"properties":{"kind":{"$ref":"#/components/schemas/ItemKind"},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"field":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Field"},"message":{"type":"string","title":"Message"}},"type":"object","required":["kind","id","field","message"],"title":"WorkflowError"},"WorkflowListResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"total_runs":{"type":"integer","title":"Total Runs"},"folder_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Folder Id"},"workflow_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workflow Uuid"}},"type":"object","required":["id","name","status","created_at","total_runs"],"title":"WorkflowListResponse","description":"Lightweight response for workflow listings (excludes large fields)."},"WorkflowOption":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"WorkflowOption"},"WorkflowResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"workflow_definition":{"additionalProperties":true,"type":"object","title":"Workflow Definition"},"current_definition_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Current Definition Id"},"template_context_variables":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Template Context Variables"},"call_disposition_codes":{"anyOf":[{"$ref":"#/components/schemas/CallDispositionCodes"},{"type":"null"}]},"total_runs":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Runs"},"workflow_configurations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Workflow Configurations"},"version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Version Number"},"version_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version Status"},"workflow_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workflow Uuid"}},"type":"object","required":["id","name","status","created_at","workflow_definition","current_definition_id"],"title":"WorkflowResponse"},"WorkflowRunDetail":{"properties":{"phone_number":{"type":"string","title":"Phone Number"},"disposition":{"type":"string","title":"Disposition"},"duration_seconds":{"type":"number","title":"Duration Seconds"},"workflow_id":{"type":"integer","title":"Workflow Id"},"run_id":{"type":"integer","title":"Run Id"},"workflow_name":{"type":"string","title":"Workflow Name"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["phone_number","disposition","duration_seconds","workflow_id","run_id","workflow_name","created_at"],"title":"WorkflowRunDetail"},"WorkflowRunResponseSchema":{"properties":{"id":{"type":"integer","title":"Id"},"workflow_id":{"type":"integer","title":"Workflow Id"},"name":{"type":"string","title":"Name"},"mode":{"type":"string","title":"Mode"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"is_completed":{"type":"boolean","title":"Is Completed"},"transcript_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript Url"},"recording_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recording Url"},"transcript_public_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript Public Url"},"recording_public_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recording Public Url"},"public_access_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Public Access Token"},"cost_info":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Cost Info"},"usage_info":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Usage Info"},"definition_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Definition Id"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"},"gathered_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Gathered Context"},"call_type":{"$ref":"#/components/schemas/CallType"},"logs":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Logs"},"annotations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Annotations"}},"type":"object","required":["id","workflow_id","name","mode","created_at","is_completed","transcript_url","recording_url","cost_info","definition_id","call_type"],"title":"WorkflowRunResponseSchema"},"WorkflowRunTextSessionResponse":{"properties":{"workflow_run_id":{"type":"integer","title":"Workflow Run Id"},"workflow_id":{"type":"integer","title":"Workflow Id"},"name":{"type":"string","title":"Name"},"mode":{"type":"string","title":"Mode"},"state":{"type":"string","title":"State"},"is_completed":{"type":"boolean","title":"Is Completed"},"revision":{"type":"integer","title":"Revision"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"},"gathered_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Gathered Context"},"annotations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Annotations"},"session_data":{"additionalProperties":true,"type":"object","title":"Session Data"},"checkpoint":{"additionalProperties":true,"type":"object","title":"Checkpoint"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["workflow_run_id","workflow_id","name","mode","state","is_completed","revision","session_data","checkpoint","created_at"],"title":"WorkflowRunTextSessionResponse"},"WorkflowRunUsageResponse":{"properties":{"id":{"type":"integer","title":"Id"},"workflow_id":{"type":"integer","title":"Workflow Id"},"workflow_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workflow Name"},"name":{"type":"string","title":"Name"},"created_at":{"type":"string","title":"Created At"},"dograh_token_usage":{"type":"number","title":"Dograh Token Usage"},"call_duration_seconds":{"type":"integer","title":"Call Duration Seconds"},"recording_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recording Url"},"transcript_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript Url"},"recording_public_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recording Public Url"},"transcript_public_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript Public Url"},"public_access_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Public Access Token"},"phone_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone Number","description":"Deprecated. Use caller_number and called_number instead.","deprecated":true},"caller_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Caller Number"},"called_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Called Number"},"call_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Call Type"},"mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mode"},"disposition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Disposition"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"},"gathered_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Gathered Context"},"charge_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Charge Usd"}},"type":"object","required":["id","workflow_id","workflow_name","name","created_at","dograh_token_usage","call_duration_seconds"],"title":"WorkflowRunUsageResponse"},"WorkflowRunsResponse":{"properties":{"runs":{"items":{"$ref":"#/components/schemas/WorkflowRunResponseSchema"},"type":"array","title":"Runs"},"total_count":{"type":"integer","title":"Total Count"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"total_pages":{"type":"integer","title":"Total Pages"},"applied_filters":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Applied Filters"}},"type":"object","required":["runs","total_count","page","limit","total_pages"],"title":"WorkflowRunsResponse"},"WorkflowSummaryResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"WorkflowSummaryResponse"},"WorkflowTemplateResponse":{"properties":{"id":{"type":"integer","title":"Id"},"template_name":{"type":"string","title":"Template Name"},"template_description":{"type":"string","title":"Template Description"},"template_json":{"additionalProperties":true,"type":"object","title":"Template Json"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","template_name","template_description","template_json","created_at"],"title":"WorkflowTemplateResponse"},"WorkflowVersionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"version_number":{"type":"integer","title":"Version Number"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"workflow_json":{"additionalProperties":true,"type":"object","title":"Workflow Json"},"workflow_configurations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Workflow Configurations"},"template_context_variables":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Template Context Variables"}},"type":"object","required":["id","version_number","status","created_at","workflow_json"],"title":"WorkflowVersionResponse"}}}} \ No newline at end of file +{"openapi":"3.1.0","info":{"title":"Dograh API","description":"API for the Dograh app","version":"1.0.0"},"servers":[{"url":"https://app.dograh.com","description":"Production"},{"url":"http://localhost:8000","description":"Local development"}],"paths":{"/api/v1/telephony/initiate-call":{"post":{"tags":["main"],"summary":"Initiate Call","description":"Initiate a call using the configured telephony provider from web browser. This is\nsupposed to be a test call method for the draft version of the agent.","operationId":"initiate_call_api_v1_telephony_initiate_call_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitiateCallRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"test_phone_call","x-sdk-description":"Place a test call from a workflow to a phone number."}},"/api/v1/telephony/inbound/run":{"post":{"tags":["main"],"summary":"Handle Inbound Run","description":"Workflow-agnostic inbound dispatcher.\n\nAll providers can point a single webhook at this endpoint instead of one\nURL per workflow. The dispatcher resolves the org from the webhook's\naccount_id and the workflow from the called number's\n``inbound_workflow_id``. This is what ``configure_inbound`` writes into\neach provider's resource so per-workflow webhook bookkeeping disappears.\n\nProvider-specific signature/timestamp headers are not enumerated here \u2014\neach provider's ``verify_inbound_signature`` reads its own headers from\nthe dict, so adding a new provider doesn't require changes to this route.","operationId":"handle_inbound_run_api_v1_telephony_inbound_run_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"}}}},"/api/v1/telephony/inbound/fallback":{"post":{"tags":["main"],"summary":"Handle Inbound Fallback","description":"Fallback endpoint that returns audio message when calls cannot be processed.","operationId":"handle_inbound_fallback_api_v1_telephony_inbound_fallback_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"}}}},"/api/v1/telephony/inbound/{workflow_id}":{"post":{"tags":["main"],"summary":"Handle Inbound Telephony","description":"[LEGACY] Per-workflow inbound webhook.\n\nSuperseded by ``POST /inbound/run``, which resolves the workflow from\nthe called number's ``inbound_workflow_id`` and lets a single webhook\nURL serve every workflow in the org. New integrations should point\ntheir provider at ``/inbound/run``; this route is kept only for\nexisting provider configurations that still encode ``workflow_id``\nin the URL.","operationId":"handle_inbound_telephony_api_v1_telephony_inbound__workflow_id__post","deprecated":true,"parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/transfer-result/{transfer_id}":{"post":{"tags":["main"],"summary":"Complete Transfer Function Call","description":"Webhook endpoint to complete the function call with transfer result.\n\nCalled by Twilio's StatusCallback when the transfer call status changes.","operationId":"complete_transfer_function_call_api_v1_telephony_transfer_result__transfer_id__post","parameters":[{"name":"transfer_id","in":"path","required":true,"schema":{"type":"string","title":"Transfer Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/cloudonix/status-callback/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Cloudonix Status Callback","description":"Handle Cloudonix-specific status callbacks.\n\nCloudonix sends call status updates to the callback URL specified during call initiation.","operationId":"handle_cloudonix_status_callback_api_v1_telephony_cloudonix_status_callback__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/cloudonix/cdr":{"post":{"tags":["main"],"summary":"Handle Cloudonix Cdr","description":"Handle Cloudonix CDR (Call Detail Record) webhooks.\n\nCloudonix sends CDR records when calls complete. The CDR contains:\n- domain: Used to identify the organization\n- call_id: Used to find the workflow run\n- disposition: Call termination status (ANSWER, BUSY, CANCEL, FAILED, CONGESTION, NOANSWER)\n- duration/billsec: Call duration information","operationId":"handle_cloudonix_cdr_api_v1_telephony_cloudonix_cdr_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"}}}},"/api/v1/telephony/plivo/hangup-callback/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Plivo Hangup Callback","description":"Handle Plivo hangup callbacks.","operationId":"handle_plivo_hangup_callback_api_v1_telephony_plivo_hangup_callback__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/plivo/ring-callback/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Plivo Ring Callback","description":"Handle Plivo ring callbacks.","operationId":"handle_plivo_ring_callback_api_v1_telephony_plivo_ring_callback__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/telnyx/events/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Telnyx Events","description":"Handle Telnyx Call Control webhook events.\n\nTelnyx sends all call lifecycle events (call.initiated, call.answered,\ncall.hangup, streaming.started, streaming.stopped) as JSON POST requests.","operationId":"handle_telnyx_events_api_v1_telephony_telnyx_events__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/telnyx/transfer-result/{transfer_id}":{"post":{"tags":["main"],"summary":"Handle Telnyx Transfer Result","description":"Handle Telnyx Call Control events for the transfer destination leg.\n\nThe destination leg is dialed by :meth:`TelnyxProvider.transfer_call` with\nthis URL as ``webhook_url``. Telnyx sends every event for that leg here.\nOutcomes:\n\n- ``call.answered``: seed a conference with the destination's live\n ``call_control_id``, stamp ``conference_id`` onto the TransferContext,\n and publish ``DESTINATION_ANSWERED`` so ``transfer_call_handler`` can\n end the pipeline. ``TelnyxConferenceStrategy`` then joins the caller\n into this conference at pipeline teardown.\n- ``call.hangup`` pre-answer (no ``conference_id`` on the context):\n publish ``TRANSFER_FAILED`` so the LLM can recover.\n- ``call.hangup`` post-answer (``conference_id`` set): the destination\n left a bridged conference; hang up the caller's leg to tear down the\n empty bridge (Telnyx's create_conference doesn't accept\n ``end_conference_on_exit`` on the seed leg).\n\nEvent references:\n - call.answered: https://developers.telnyx.com/api-reference/callbacks/call-answered\n - call.hangup: https://developers.telnyx.com/api-reference/callbacks/call-hangup","operationId":"handle_telnyx_transfer_result_api_v1_telephony_telnyx_transfer_result__transfer_id__post","parameters":[{"name":"transfer_id","in":"path","required":true,"schema":{"type":"string","title":"Transfer Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/twilio/status-callback/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Twilio Status Callback","description":"Handle Twilio-specific status callbacks.","operationId":"handle_twilio_status_callback_api_v1_telephony_twilio_status_callback__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/vobiz/hangup-callback/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Vobiz Hangup Callback","description":"Handle Vobiz hangup callback (sent when call ends).\n\nVobiz sends callbacks to hangup_url when the call terminates.\nThis includes call duration, status, and billing information.","operationId":"handle_vobiz_hangup_callback_api_v1_telephony_vobiz_hangup_callback__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/vobiz/ring-callback/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Vobiz Ring Callback","description":"Handle Vobiz ring callback (sent when call starts ringing).\n\nVobiz can send callbacks to ring_url when the call starts ringing.\nThis is optional and used for tracking ringing status.","operationId":"handle_vobiz_ring_callback_api_v1_telephony_vobiz_ring_callback__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/vobiz/hangup-callback/workflow/{workflow_id}":{"post":{"tags":["main"],"summary":"Handle Vobiz Hangup Callback By Workflow","description":"Handle Vobiz hangup callback with workflow_id - finds workflow run by call_id.","operationId":"handle_vobiz_hangup_callback_by_workflow_api_v1_telephony_vobiz_hangup_callback_workflow__workflow_id__post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/telephony/vonage/events/{workflow_run_id}":{"post":{"tags":["main"],"summary":"Handle Vonage Events","description":"Handle Vonage-specific event webhooks.\n\nVonage sends all call events to a single endpoint.\nEvents include: started, ringing, answered, complete, failed, etc.","operationId":"handle_vonage_events_api_v1_telephony_vonage_events__workflow_run_id__post","parameters":[{"name":"workflow_run_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/superuser/impersonate":{"post":{"tags":["main","superuser"],"summary":"Impersonate","description":"Impersonate a user as a super-admin.\nInternally, Stack Auth requires the **provider user ID** (a UUID-ish string)\nto create an impersonation session.","operationId":"impersonate_api_v1_superuser_impersonate_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImpersonateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImpersonateResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/superuser/workflow-runs":{"get":{"tags":["main","superuser"],"summary":"Get Workflow Runs","description":"Get paginated list of all workflow runs with organization information.\nRequires superuser privileges.\n\nFilters should be provided as a JSON-encoded array of filter criteria.\nExample: [{\"field\": \"id\", \"type\": \"number\", \"value\": {\"value\": 680}}]","operationId":"get_workflow_runs_api_v1_superuser_workflow_runs_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number (starts from 1)","default":1,"title":"Page"},"description":"Page number (starts from 1)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of items per page","default":50,"title":"Limit"},"description":"Number of items per page"},{"name":"filters","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-encoded filter criteria","title":"Filters"},"description":"JSON-encoded filter criteria"},{"name":"sort_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by (e.g., 'duration', 'created_at')","title":"Sort By"},"description":"Field to sort by (e.g., 'duration', 'created_at')"},{"name":"sort_order","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Sort order ('asc' or 'desc')","default":"desc","title":"Sort Order"},"description":"Sort order ('asc' or 'desc')"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuperuserWorkflowRunsListResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/validate":{"post":{"tags":["main"],"summary":"Validate Workflow","description":"Validate all nodes in a workflow to ensure they have required fields.\n\nArgs:\n workflow_id: The ID of the workflow to validate\n user: The authenticated user\n\nReturns:\n Object indicating if workflow is valid and any invalid nodes/edges","operationId":"validate_workflow_api_v1_workflow__workflow_id__validate_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateWorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/create/definition":{"post":{"tags":["main"],"summary":"Create Workflow","description":"Create a new workflow from the client\n\nArgs:\n request: The create workflow request\n user: The user to create the workflow for","operationId":"create_workflow_api_v1_workflow_create_definition_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkflowRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"create_workflow","x-sdk-description":"Create a new workflow from a workflow definition."}},"/api/v1/workflow/create/template":{"post":{"tags":["main"],"summary":"Create Workflow From Template","description":"Create a new workflow from a natural language template request.\n\nThis endpoint:\n1. Uses mps_service_key_client to call MPS workflow API\n2. Passes organization ID (authenticated mode) or created_by (OSS mode)\n3. Creates the workflow in the database\n\nArgs:\n request: The template creation request with call_type, use_case, and activity_description\n user: The authenticated user\n\nReturns:\n The created workflow\n\nRaises:\n HTTPException: If MPS API call fails","operationId":"create_workflow_from_template_api_v1_workflow_create_template_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkflowTemplateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/count":{"get":{"tags":["main"],"summary":"Get Workflow Count","description":"Get workflow counts for the authenticated user's organization.\n\nThis is a lightweight endpoint for checking if the user has workflows,\nuseful for redirect logic without fetching full workflow data.","operationId":"get_workflow_count_api_v1_workflow_count_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowCountResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/fetch":{"get":{"tags":["main"],"summary":"Get Workflows","description":"Get all workflows for the authenticated user's organization.\n\nReturns a lightweight response with only essential fields for listing.\nUse GET /workflow/fetch/{workflow_id} to get full workflow details.","operationId":"get_workflows_api_v1_workflow_fetch_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status - can be single value (active/archived) or comma-separated (active,archived)","title":"Status"},"description":"Filter by status - can be single value (active/archived) or comma-separated (active,archived)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowListResponse"},"title":"Response Get Workflows Api V1 Workflow Fetch Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"list_workflows","x-sdk-description":"List all workflows in the authenticated organization."}},"/api/v1/workflow/fetch/{workflow_id}":{"get":{"tags":["main"],"summary":"Get Workflow","description":"Get a single workflow by ID.\n\nIf a draft version exists, returns the draft content for editing.\nOtherwise returns the published version's content.","operationId":"get_workflow_api_v1_workflow_fetch__workflow_id__get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"get_workflow","x-sdk-description":"Get a single workflow by ID (returns draft if one exists, else published)."}},"/api/v1/workflow/{workflow_id}/versions":{"get":{"tags":["main"],"summary":"Get Workflow Versions","description":"List versions for a workflow, newest first.\n\nPass `limit`/`offset` to page through long histories. With no `limit`,\nreturns every version (legacy behavior).","operationId":"get_workflow_versions_api_v1_workflow__workflow_id__versions_get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":100,"minimum":1},{"type":"null"}],"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowVersionResponse"},"title":"Response Get Workflow Versions Api V1 Workflow Workflow Id Versions Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/publish":{"post":{"tags":["main"],"summary":"Publish Workflow","description":"Publish the current draft version of a workflow.\n\nDrafts are allowed to be incomplete (so the editor can save mid-edit),\nbut a published version is what runtime executes \u2014 so this is the gate\nwhere the full DTO + graph + trigger-conflict checks must pass.","operationId":"publish_workflow_api_v1_workflow__workflow_id__publish_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/create-draft":{"post":{"tags":["main"],"summary":"Create Workflow Draft","description":"Create a draft version from the current published version.\n\nIf a draft already exists, returns the existing draft.","operationId":"create_workflow_draft_api_v1_workflow__workflow_id__create_draft_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowVersionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/summary":{"get":{"tags":["main"],"summary":"Get Workflows Summary","description":"Get minimal workflow information (id and name only) for all workflows","operationId":"get_workflows_summary_api_v1_workflow_summary_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status (e.g. 'active' or 'archived'). Omit to return all.","title":"Status"},"description":"Filter by status (e.g. 'active' or 'archived'). Omit to return all."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowSummaryResponse"},"title":"Response Get Workflows Summary Api V1 Workflow Summary Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/status":{"put":{"tags":["main"],"summary":"Update Workflow Status","description":"Update the status of a workflow (e.g., archive/unarchive).\n\nArgs:\n workflow_id: The ID of the workflow to update\n request: The status update request\n\nReturns:\n The updated workflow","operationId":"update_workflow_status_api_v1_workflow__workflow_id__status_put","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkflowStatusRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/folder":{"put":{"tags":["main"],"summary":"Move Workflow To Folder","description":"Move a workflow into a folder, or to \"Uncategorized\" (folder_id=null).\n\nValidates that the target folder belongs to the caller's organization \u2014\nthe FK alone proves the folder exists, not that the caller may use it.","operationId":"move_workflow_to_folder_api_v1_workflow__workflow_id__folder_put","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveWorkflowToFolderRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowListResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}":{"put":{"tags":["main"],"summary":"Update Workflow","description":"Update an existing workflow.\n\nArgs:\n workflow_id: The ID of the workflow to update\n request: The update request containing the new name and workflow definition\n\nReturns:\n The updated workflow\n\nRaises:\n HTTPException: If the workflow is not found or if there's a database error","operationId":"update_workflow_api_v1_workflow__workflow_id__put","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkflowRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"update_workflow","x-sdk-description":"Update a workflow's name and/or definition. Saves as a new draft."}},"/api/v1/workflow/{workflow_id}/duplicate":{"post":{"tags":["main"],"summary":"Duplicate Workflow Endpoint","description":"Duplicate a workflow including its definition, configuration, recordings, and triggers.","operationId":"duplicate_workflow_endpoint_api_v1_workflow__workflow_id__duplicate_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/runs":{"post":{"tags":["main"],"summary":"Create Workflow Run","description":"Create a new workflow run when the user decides to execute the workflow via chat or voice\n\nArgs:\n workflow_id: The ID of the workflow to run\n request: The create workflow run request\n user: The user to create the workflow run for","operationId":"create_workflow_run_api_v1_workflow__workflow_id__runs_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkflowRunRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkflowRunResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["main"],"summary":"Get Workflow Runs","description":"Get workflow runs with optional filtering and sorting.\n\nFilters should be provided as a JSON-encoded array of filter criteria.\nExample: [{\"attribute\": \"dateRange\", \"value\": {\"from\": \"2024-01-01\", \"to\": \"2024-01-31\"}}]","operationId":"get_workflow_runs_api_v1_workflow__workflow_id__runs_get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"filters","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-encoded filter criteria","title":"Filters"},"description":"JSON-encoded filter criteria"},{"name":"sort_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by (e.g., 'duration', 'created_at')","title":"Sort By"},"description":"Field to sort by (e.g., 'duration', 'created_at')"},{"name":"sort_order","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Sort order ('asc' or 'desc')","default":"desc","title":"Sort Order"},"description":"Sort order ('asc' or 'desc')"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/runs/{run_id}":{"get":{"tags":["main"],"summary":"Get Workflow Run","operationId":"get_workflow_run_api_v1_workflow__workflow_id__runs__run_id__get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"integer","title":"Run Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/report":{"get":{"tags":["main"],"summary":"Download Workflow Report","description":"Download a CSV report of completed runs for a workflow.","operationId":"download_workflow_report_api_v1_workflow__workflow_id__report_get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Filter runs created on or after this datetime (ISO 8601)","title":"Start Date"},"description":"Filter runs created on or after this datetime (ISO 8601)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Filter runs created on or before this datetime (ISO 8601)","title":"End Date"},"description":"Filter runs created on or before this datetime (ISO 8601)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/templates":{"get":{"tags":["main"],"summary":"Get Workflow Templates","description":"Get all available workflow templates.\n\nReturns:\n List of workflow templates","operationId":"get_workflow_templates_api_v1_workflow_templates_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/WorkflowTemplateResponse"},"type":"array","title":"Response Get Workflow Templates Api V1 Workflow Templates Get"}}}},"404":{"description":"Not found"}}}},"/api/v1/workflow/templates/duplicate":{"post":{"tags":["main"],"summary":"Duplicate Workflow Template","description":"Duplicate a workflow template to create a new workflow for the user.\n\nArgs:\n request: The duplicate template request\n user: The authenticated user\n\nReturns:\n The newly created workflow","operationId":"duplicate_workflow_template_api_v1_workflow_templates_duplicate_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DuplicateTemplateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/ambient-noise/upload-url":{"post":{"tags":["main"],"summary":"Get a presigned URL to upload a custom ambient noise audio file","description":"Generate a presigned PUT URL for uploading a custom ambient noise file.","operationId":"get_ambient_noise_upload_url_api_v1_workflow_ambient_noise_upload_url_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AmbientNoiseUploadRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AmbientNoiseUploadResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/text-chat/sessions":{"post":{"tags":["main","workflow-text-chat"],"summary":"Create Text Chat Session","operationId":"create_text_chat_session_api_v1_workflow__workflow_id__text_chat_sessions_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTextChatSessionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunTextSessionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/text-chat/sessions/{run_id}":{"get":{"tags":["main","workflow-text-chat"],"summary":"Get Text Chat Session","operationId":"get_text_chat_session_api_v1_workflow__workflow_id__text_chat_sessions__run_id__get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"integer","title":"Run Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunTextSessionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/text-chat/sessions/{run_id}/messages":{"post":{"tags":["main","workflow-text-chat"],"summary":"Append Text Chat Message","operationId":"append_text_chat_message_api_v1_workflow__workflow_id__text_chat_sessions__run_id__messages_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"integer","title":"Run Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppendTextChatMessageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunTextSessionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/text-chat/sessions/{run_id}/rewind":{"post":{"tags":["main","workflow-text-chat"],"summary":"Rewind Text Chat Session","operationId":"rewind_text_chat_session_api_v1_workflow__workflow_id__text_chat_sessions__run_id__rewind_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"integer","title":"Run Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewindTextChatSessionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowRunTextSessionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/configurations/defaults":{"get":{"tags":["main"],"summary":"Get Default Configurations","operationId":"get_default_configurations_api_v1_user_configurations_defaults_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DefaultConfigurationsResponse"}}}},"404":{"description":"Not found"}}}},"/api/v1/user/auth/user":{"get":{"tags":["main"],"summary":"Get Auth User","operationId":"get_auth_user_api_v1_user_auth_user_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthUserResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/configurations/user":{"get":{"tags":["main"],"summary":"Get User Configurations","operationId":"get_user_configurations_api_v1_user_configurations_user_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConfigurationRequestResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main"],"summary":"Update User Configurations","operationId":"update_user_configurations_api_v1_user_configurations_user_put","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConfigurationRequestResponseSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserConfigurationRequestResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/onboarding-state":{"get":{"tags":["main"],"summary":"Get User Onboarding State","operationId":"get_user_onboarding_state_api_v1_user_onboarding_state_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingState"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main"],"summary":"Update User Onboarding State","operationId":"update_user_onboarding_state_api_v1_user_onboarding_state_put","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStateUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingState"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/configurations/user/validate":{"get":{"tags":["main"],"summary":"Validate User Configurations","operationId":"validate_user_configurations_api_v1_user_configurations_user_validate_get","parameters":[{"name":"validity_ttl_seconds","in":"query","required":false,"schema":{"type":"integer","maximum":86400,"minimum":0,"default":60,"title":"Validity Ttl Seconds"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIKeyStatusResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/api-keys":{"get":{"tags":["main"],"summary":"Get Api Keys","description":"Get all API keys for the user's selected organization.","operationId":"get_api_keys_api_v1_user_api_keys_get","parameters":[{"name":"include_archived","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Archived"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/APIKeyResponse"},"title":"Response Get Api Keys Api V1 User Api Keys Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main"],"summary":"Create Api Key","description":"Create a new API key for the user's selected organization.","operationId":"create_api_key_api_v1_user_api_keys_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAPIKeyResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/api-keys/{api_key_id}":{"delete":{"tags":["main"],"summary":"Archive Api Key","description":"Archive an API key (soft delete).","operationId":"archive_api_key_api_v1_user_api_keys__api_key_id__delete","parameters":[{"name":"api_key_id","in":"path","required":true,"schema":{"type":"integer","title":"Api Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Archive Api Key Api V1 User Api Keys Api Key Id Delete"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/api-keys/{api_key_id}/reactivate":{"put":{"tags":["main"],"summary":"Reactivate Api Key","description":"Reactivate an archived API key.","operationId":"reactivate_api_key_api_v1_user_api_keys__api_key_id__reactivate_put","parameters":[{"name":"api_key_id","in":"path","required":true,"schema":{"type":"integer","title":"Api Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Reactivate Api Key Api V1 User Api Keys Api Key Id Reactivate Put"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/configurations/voices/{provider}":{"get":{"tags":["main"],"summary":"Get Voices","description":"Get available voices for a TTS provider.","operationId":"get_voices_api_v1_user_configurations_voices__provider__get","parameters":[{"name":"provider","in":"path","required":true,"schema":{"enum":["elevenlabs","deepgram","sarvam","cartesia","dograh","rime"],"type":"string","title":"Provider"}},{"name":"model","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"}},{"name":"language","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoicesResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/create":{"post":{"tags":["main"],"summary":"Create Campaign","description":"Create a new campaign","operationId":"create_campaign_api_v1_campaign_create_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCampaignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/":{"get":{"tags":["main"],"summary":"Get Campaigns","description":"Get campaigns for user's organization","operationId":"get_campaigns_api_v1_campaign__get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}":{"get":{"tags":["main"],"summary":"Get Campaign","description":"Get campaign details","operationId":"get_campaign_api_v1_campaign__campaign_id__get","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["main"],"summary":"Update Campaign","description":"Update campaign settings (name, retry config, max concurrency, schedule)","operationId":"update_campaign_api_v1_campaign__campaign_id__patch","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCampaignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/start":{"post":{"tags":["main"],"summary":"Start Campaign","description":"Start campaign execution","operationId":"start_campaign_api_v1_campaign__campaign_id__start_post","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/pause":{"post":{"tags":["main"],"summary":"Pause Campaign","description":"Pause campaign execution","operationId":"pause_campaign_api_v1_campaign__campaign_id__pause_post","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/runs":{"get":{"tags":["main"],"summary":"Get Campaign Runs","description":"Get campaign workflow runs with pagination, filters and sorting","operationId":"get_campaign_runs_api_v1_campaign__campaign_id__runs_get","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"filters","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-encoded filter criteria","title":"Filters"},"description":"JSON-encoded filter criteria"},{"name":"sort_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Field to sort by (e.g., 'duration', 'created_at')","title":"Sort By"},"description":"Field to sort by (e.g., 'duration', 'created_at')"},{"name":"sort_order","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Sort order ('asc' or 'desc')","default":"desc","title":"Sort Order"},"description":"Sort order ('asc' or 'desc')"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRunsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/redial":{"post":{"tags":["main"],"summary":"Redial Campaign","description":"Create a new campaign that re-dials unique subscribers from a completed\ncampaign whose latest call resulted in voicemail, no-answer, or busy.\n\nThe new campaign is created in 'created' state with queued_runs pre-seeded\nfrom the parent's original initial contexts. A campaign can be redialed at\nmost once.","operationId":"redial_campaign_api_v1_campaign__campaign_id__redial_post","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedialCampaignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/resume":{"post":{"tags":["main"],"summary":"Resume Campaign","description":"Resume a paused campaign","operationId":"resume_campaign_api_v1_campaign__campaign_id__resume_post","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/progress":{"get":{"tags":["main"],"summary":"Get Campaign Progress","description":"Get current campaign progress and statistics","operationId":"get_campaign_progress_api_v1_campaign__campaign_id__progress_get","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignProgressResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/source-download-url":{"get":{"tags":["main"],"summary":"Get Campaign Source Download Url","description":"Get presigned download URL for campaign CSV source file\nValidates that the campaign belongs to the user's organization for security.","operationId":"get_campaign_source_download_url_api_v1_campaign__campaign_id__source_download_url_get","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSourceDownloadResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/campaign/{campaign_id}/report":{"get":{"tags":["main"],"summary":"Download Campaign Report","description":"Download a CSV report of completed campaign runs.","operationId":"download_campaign_report_api_v1_campaign__campaign_id__report_get","parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"integer","title":"Campaign Id"}},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Filter runs created on or after this datetime (ISO 8601)","title":"Start Date"},"description":"Filter runs created on or after this datetime (ISO 8601)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Filter runs created on or before this datetime (ISO 8601)","title":"End Date"},"description":"Filter runs created on or before this datetime (ISO 8601)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/credentials/":{"get":{"tags":["main"],"summary":"List Credentials","description":"List all webhook credentials for the user's organization.\n\nReturns:\n List of credentials (without sensitive data)","operationId":"list_credentials_api_v1_credentials__get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CredentialResponse"},"title":"Response List Credentials Api V1 Credentials Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"list_credentials","x-sdk-description":"List webhook credentials available to the authenticated organization."},"post":{"tags":["main"],"summary":"Create Credential","description":"Create a new webhook credential.\n\nArgs:\n request: The credential creation request\n\nReturns:\n The created credential (without sensitive data)","operationId":"create_credential_api_v1_credentials__post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCredentialRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CredentialResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/credentials/{credential_uuid}":{"get":{"tags":["main"],"summary":"Get Credential","description":"Get a specific webhook credential by UUID.\n\nArgs:\n credential_uuid: The UUID of the credential\n\nReturns:\n The credential (without sensitive data)","operationId":"get_credential_api_v1_credentials__credential_uuid__get","parameters":[{"name":"credential_uuid","in":"path","required":true,"schema":{"type":"string","title":"Credential Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CredentialResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main"],"summary":"Update Credential","description":"Update a webhook credential.\n\nArgs:\n credential_uuid: The UUID of the credential to update\n request: The update request\n\nReturns:\n The updated credential (without sensitive data)","operationId":"update_credential_api_v1_credentials__credential_uuid__put","parameters":[{"name":"credential_uuid","in":"path","required":true,"schema":{"type":"string","title":"Credential Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCredentialRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CredentialResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main"],"summary":"Delete Credential","description":"Delete (soft delete) a webhook credential.\n\nArgs:\n credential_uuid: The UUID of the credential to delete\n\nReturns:\n Success message","operationId":"delete_credential_api_v1_credentials__credential_uuid__delete","parameters":[{"name":"credential_uuid","in":"path","required":true,"schema":{"type":"string","title":"Credential Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Credential Api V1 Credentials Credential Uuid Delete"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/":{"get":{"tags":["main"],"summary":"List Tools","description":"List all tools for the user's organization.\n\nArgs:\n status: Optional filter by status (active, archived, draft)\n category: Optional filter by category (http_api, native, integration)\n\nReturns:\n List of tools","operationId":"list_tools_api_v1_tools__get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ToolResponse"},"title":"Response List Tools Api V1 Tools Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"list_tools","x-sdk-description":"List tools available to the authenticated organization."},"post":{"tags":["main"],"summary":"Create Tool","description":"Create a new tool.\n\nArgs:\n request: The tool creation request\n\nReturns:\n The created tool","operationId":"create_tool_api_v1_tools__post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateToolRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"create_tool","x-sdk-description":"Create a reusable tool for the authenticated organization."}},"/api/v1/tools/{tool_uuid}":{"get":{"tags":["main"],"summary":"Get Tool","description":"Get a specific tool by UUID.\n\nArgs:\n tool_uuid: The UUID of the tool\n\nReturns:\n The tool","operationId":"get_tool_api_v1_tools__tool_uuid__get","parameters":[{"name":"tool_uuid","in":"path","required":true,"schema":{"type":"string","title":"Tool Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main"],"summary":"Update Tool","description":"Update a tool.\n\nArgs:\n tool_uuid: The UUID of the tool to update\n request: The update request\n\nReturns:\n The updated tool","operationId":"update_tool_api_v1_tools__tool_uuid__put","parameters":[{"name":"tool_uuid","in":"path","required":true,"schema":{"type":"string","title":"Tool Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateToolRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main"],"summary":"Delete Tool","description":"Archive (soft delete) a tool.\n\nArgs:\n tool_uuid: The UUID of the tool to delete\n\nReturns:\n Success message","operationId":"delete_tool_api_v1_tools__tool_uuid__delete","parameters":[{"name":"tool_uuid","in":"path","required":true,"schema":{"type":"string","title":"Tool Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Tool Api V1 Tools Tool Uuid Delete"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/{tool_uuid}/mcp/refresh":{"post":{"tags":["main"],"summary":"Refresh Mcp Tools","description":"Re-discover an MCP tool's server catalog and overwrite the cached\n``definition.config.discovered_tools``. Server down \u2192 200 with error\n(cache not overwritten on transient failure).","operationId":"refresh_mcp_tools_api_v1_tools__tool_uuid__mcp_refresh_post","parameters":[{"name":"tool_uuid","in":"path","required":true,"schema":{"type":"string","title":"Tool Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpRefreshResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/{tool_uuid}/unarchive":{"post":{"tags":["main"],"summary":"Unarchive Tool","description":"Unarchive a tool (restore from archived state).\n\nArgs:\n tool_uuid: The UUID of the tool to unarchive\n\nReturns:\n The unarchived tool","operationId":"unarchive_tool_api_v1_tools__tool_uuid__unarchive_post","parameters":[{"name":"tool_uuid","in":"path","required":true,"schema":{"type":"string","title":"Tool Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/context":{"get":{"tags":["main","organizations"],"summary":"Get Current Organization Context","description":"Return organization-scoped configuration signals owned by Dograh.","operationId":"get_current_organization_context_api_v1_organizations_context_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationContextResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-providers/metadata":{"get":{"tags":["main","organizations"],"summary":"Get Telephony Providers Metadata","description":"Return the list of available telephony providers and their form schemas.\n\nThe UI uses this to render the configuration form generically instead of\nhard-coding fields per provider. Adding a new provider only requires\ndeclaring its ui_metadata in providers//__init__.py.","operationId":"get_telephony_providers_metadata_api_v1_organizations_telephony_providers_metadata_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyProvidersMetadataResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-config-warnings":{"get":{"tags":["main","organizations"],"summary":"Get Telephony Config Warnings","description":"Return aggregated warning counts for the current org's telephony configs.\n\nToday this surfaces only Telnyx configs missing ``webhook_public_key``;\nadditional warning types should be added as new fields on the response.","operationId":"get_telephony_config_warnings_api_v1_organizations_telephony_config_warnings_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigWarningsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/model-configurations/v2/defaults":{"get":{"tags":["main","organizations"],"summary":"Get Model Configuration V2 Defaults","operationId":"get_model_configuration_v2_defaults_api_v1_organizations_model_configurations_v2_defaults_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/model-configurations/v2":{"get":{"tags":["main","organizations"],"summary":"Get Model Configuration V2","operationId":"get_model_configuration_v2_api_v1_organizations_model_configurations_v2_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationAIModelConfigurationResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main","organizations"],"summary":"Save Model Configuration V2","operationId":"save_model_configuration_v2_api_v1_organizations_model_configurations_v2_put","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationAIModelConfigurationV2"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationAIModelConfigurationResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/model-configurations/v2/migration-preview":{"get":{"tags":["main","organizations"],"summary":"Preview Model Configuration V2 Migration","operationId":"preview_model_configuration_v2_migration_api_v1_organizations_model_configurations_v2_migration_preview_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/model-configurations/v2/migrate":{"post":{"tags":["main","organizations"],"summary":"Migrate Model Configuration V2","operationId":"migrate_model_configuration_v2_api_v1_organizations_model_configurations_v2_migrate_post","parameters":[{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationAIModelConfigurationResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/preferences":{"get":{"tags":["main","organizations"],"summary":"Get Preferences","operationId":"get_preferences_api_v1_organizations_preferences_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationPreferences"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main","organizations"],"summary":"Save Preferences","operationId":"save_preferences_api_v1_organizations_preferences_put","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationPreferences"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationPreferences"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-configs":{"get":{"tags":["main","organizations"],"summary":"List Telephony Configurations","description":"List the org's telephony configurations with phone-number counts.","operationId":"list_telephony_configurations_api_v1_organizations_telephony_configs_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationListResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main","organizations"],"summary":"Create Telephony Configuration","description":"Create a new telephony configuration for the org.","operationId":"create_telephony_configuration_api_v1_organizations_telephony_configs_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationCreateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationDetail"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-configs/{config_id}":{"get":{"tags":["main","organizations"],"summary":"Get Telephony Configuration By Id","operationId":"get_telephony_configuration_by_id_api_v1_organizations_telephony_configs__config_id__get","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationDetail"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main","organizations"],"summary":"Update Telephony Configuration","operationId":"update_telephony_configuration_api_v1_organizations_telephony_configs__config_id__put","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationDetail"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main","organizations"],"summary":"Delete Telephony Configuration","operationId":"delete_telephony_configuration_api_v1_organizations_telephony_configs__config_id__delete","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-configs/{config_id}/set-default-outbound":{"post":{"tags":["main","organizations"],"summary":"Set Default Outbound","operationId":"set_default_outbound_api_v1_organizations_telephony_configs__config_id__set_default_outbound_post","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationDetail"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-configs/{config_id}/phone-numbers":{"get":{"tags":["main","organizations"],"summary":"List Phone Numbers","operationId":"list_phone_numbers_api_v1_organizations_telephony_configs__config_id__phone_numbers_get","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberListResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main","organizations"],"summary":"Create Phone Number","operationId":"create_phone_number_api_v1_organizations_telephony_configs__config_id__phone_numbers_post","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberCreateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-configs/{config_id}/phone-numbers/{phone_number_id}":{"get":{"tags":["main","organizations"],"summary":"Get Phone Number","operationId":"get_phone_number_api_v1_organizations_telephony_configs__config_id__phone_numbers__phone_number_id__get","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"phone_number_id","in":"path","required":true,"schema":{"type":"integer","title":"Phone Number Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["main","organizations"],"summary":"Update Phone Number","operationId":"update_phone_number_api_v1_organizations_telephony_configs__config_id__phone_numbers__phone_number_id__put","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"phone_number_id","in":"path","required":true,"schema":{"type":"integer","title":"Phone Number Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main","organizations"],"summary":"Delete Phone Number","operationId":"delete_phone_number_api_v1_organizations_telephony_configs__config_id__phone_numbers__phone_number_id__delete","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"phone_number_id","in":"path","required":true,"schema":{"type":"integer","title":"Phone Number Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-configs/{config_id}/phone-numbers/{phone_number_id}/set-default-caller":{"post":{"tags":["main","organizations"],"summary":"Set Default Caller Id","operationId":"set_default_caller_id_api_v1_organizations_telephony_configs__config_id__phone_numbers__phone_number_id__set_default_caller_post","parameters":[{"name":"config_id","in":"path","required":true,"schema":{"type":"integer","title":"Config Id"}},{"name":"phone_number_id","in":"path","required":true,"schema":{"type":"integer","title":"Phone Number Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneNumberResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/telephony-config":{"get":{"tags":["main","organizations"],"summary":"Get Telephony Configuration","description":"Legacy: returns the org's default config in the original per-provider\nresponse shape so the existing single-form UI keeps working. Prefer the\nmulti-config endpoints (``/telephony-configs``) for new clients.","operationId":"get_telephony_configuration_api_v1_organizations_telephony_config_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelephonyConfigurationResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main","organizations"],"summary":"Save Telephony Configuration","description":"Legacy: upserts the org's default config (and its phone numbers) in the\noriginal payload shape so existing UI clients keep working. Prefer the\nmulti-config + phone-number endpoints for new clients.","operationId":"save_telephony_configuration_api_v1_organizations_telephony_config_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ARIConfigurationRequest"},{"$ref":"#/components/schemas/CloudonixConfigurationRequest"},{"$ref":"#/components/schemas/PlivoConfigurationRequest"},{"$ref":"#/components/schemas/TelnyxConfigurationRequest"},{"$ref":"#/components/schemas/TwilioConfigurationRequest"},{"$ref":"#/components/schemas/VobizConfigurationRequest"},{"$ref":"#/components/schemas/VonageConfigurationRequest"}],"discriminator":{"propertyName":"provider","mapping":{"ari":"#/components/schemas/ARIConfigurationRequest","cloudonix":"#/components/schemas/CloudonixConfigurationRequest","plivo":"#/components/schemas/PlivoConfigurationRequest","telnyx":"#/components/schemas/TelnyxConfigurationRequest","twilio":"#/components/schemas/TwilioConfigurationRequest","vobiz":"#/components/schemas/VobizConfigurationRequest","vonage":"#/components/schemas/VonageConfigurationRequest"}},"title":"Request"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/langfuse-credentials":{"get":{"tags":["main","organizations"],"summary":"Get Langfuse Credentials","description":"Get Langfuse credentials for the user's organization with masked sensitive fields.","operationId":"get_langfuse_credentials_api_v1_organizations_langfuse_credentials_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LangfuseCredentialsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main","organizations"],"summary":"Save Langfuse Credentials","description":"Save Langfuse credentials for the user's organization.","operationId":"save_langfuse_credentials_api_v1_organizations_langfuse_credentials_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LangfuseCredentialsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main","organizations"],"summary":"Delete Langfuse Credentials","description":"Delete Langfuse credentials for the user's organization.","operationId":"delete_langfuse_credentials_api_v1_organizations_langfuse_credentials_delete","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/campaign-defaults":{"get":{"tags":["main","organizations"],"summary":"Get Campaign Defaults","description":"Get campaign limits for the user's organization.\n\nReturns the organization's concurrent call limit and default retry configuration.","operationId":"get_campaign_defaults_api_v1_organizations_campaign_defaults_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignDefaultsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/s3/signed-url":{"get":{"tags":["main","s3"],"summary":"Generate a signed S3 URL","description":"Return a short-lived signed URL for a file stored on S3 / MinIO.\n\nAccess Control:\n* Known org-scoped keys (for example ``campaigns/{org_id}/...`` and\n ``knowledge_base/{org_id}/...``) are authorized by matching the org_id\n against the requesting user's organization.\n* Legacy keys (``recordings/{run_id}.wav``, ``transcripts/{run_id}.txt``)\n are authorized via the workflow run they belong to.\n* Superusers can request any key.","operationId":"get_signed_url_api_v1_s3_signed_url_get","parameters":[{"name":"key","in":"query","required":true,"schema":{"type":"string","description":"S3 object key","title":"Key"},"description":"S3 object key"},{"name":"expires_in","in":"query","required":false,"schema":{"type":"integer","default":3600,"title":"Expires In"}},{"name":"inline","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Inline"}},{"name":"storage_backend","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Storage backend to use (e.g. 'minio', 's3'). When omitted the backend is inferred from the resource.","title":"Storage Backend"},"description":"Storage backend to use (e.g. 'minio', 's3'). When omitted the backend is inferred from the resource."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/S3SignedUrlResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/s3/file-metadata":{"get":{"tags":["main","s3"],"summary":"Get file metadata for debugging","description":"Get file metadata including creation timestamp for debugging.\n\nAccess Control:\n* Superusers can request any key.\n* Regular users can only request resources belonging to **their** workflow runs.","operationId":"get_file_metadata_api_v1_s3_file_metadata_get","parameters":[{"name":"key","in":"query","required":true,"schema":{"type":"string","description":"S3 object key","title":"Key"},"description":"S3 object key"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileMetadataResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/s3/presigned-upload-url":{"post":{"tags":["main","s3"],"summary":"Generate a presigned URL for direct CSV upload","description":"Generate a presigned PUT URL for direct CSV file upload to S3/MinIO.\n\nThis endpoint enables browser-to-storage uploads without passing through the backend\n\nAccess Control:\n* All authenticated users can upload CSV files scoped to their organization.\n* Files are stored with organization-scoped keys for multi-tenancy.\n\nReturns:\n* upload_url: Presigned URL (valid for 15 minutes) for PUT request\n* file_key: Unique storage key to use as source_id in campaign creation\n* expires_in: URL expiration time in seconds","operationId":"get_presigned_upload_url_api_v1_s3_presigned_upload_url_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignedUploadUrlRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignedUploadUrlResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/service-keys":{"get":{"tags":["main"],"summary":"Get Service Keys","description":"Get all service keys for the user's organization.","operationId":"get_service_keys_api_v1_user_service_keys_get","parameters":[{"name":"include_archived","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Archived"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ServiceKeyResponse"},"title":"Response Get Service Keys Api V1 User Service Keys Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main"],"summary":"Create Service Key","description":"Create a new service key for the user's organization.","operationId":"create_service_key_api_v1_user_service_keys_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateServiceKeyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateServiceKeyResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/service-keys/{service_key_id}":{"delete":{"tags":["main"],"summary":"Archive Service Key","description":"Archive a service key.","operationId":"archive_service_key_api_v1_user_service_keys__service_key_id__delete","parameters":[{"name":"service_key_id","in":"path","required":true,"schema":{"type":"string","title":"Service Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/service-keys/{service_key_id}/reactivate":{"put":{"tags":["main"],"summary":"Reactivate Service Key","description":"Reactivate an archived service key.\n\nNote: This endpoint is provided for API compatibility but service key\nreactivation is not supported by MPS. Once archived, a service key\ncannot be reactivated and a new key must be created instead.","operationId":"reactivate_service_key_api_v1_user_service_keys__service_key_id__reactivate_put","parameters":[{"name":"service_key_id","in":"path","required":true,"schema":{"type":"string","title":"Service Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/usage/current-period":{"get":{"tags":["main"],"summary":"Get Current Period Usage","description":"Get current reporting-period usage for the user's organization.","operationId":"get_current_period_usage_api_v1_organizations_usage_current_period_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentUsageResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/usage/mps-credits":{"get":{"tags":["main"],"summary":"Get Mps Credits","description":"Get aggregated usage and quota from MPS.\n\nOSS users: queries by provider_id (created_by).\nHosted users: queries by organization_id.","operationId":"get_mps_credits_api_v1_organizations_usage_mps_credits_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MPSCreditsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/billing/credits":{"get":{"tags":["main"],"summary":"Get Billing Credits","description":"Return legacy MPS credits or paginated v2 billing ledger details for the org.","operationId":"get_billing_credits_api_v1_organizations_billing_credits_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MPSBillingCreditsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/usage/mps-credits/purchase-url":{"post":{"tags":["main"],"summary":"Create Mps Credit Purchase Url","description":"Create a checkout URL for organizations using Dograh-managed MPS v2.","operationId":"create_mps_credit_purchase_url_api_v1_organizations_usage_mps_credits_purchase_url_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MPSCreditPurchaseUrlResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/usage/runs":{"get":{"tags":["main"],"summary":"Get Usage History","description":"Get paginated workflow runs with usage for the organization.","operationId":"get_usage_history_api_v1_organizations_usage_runs_get","parameters":[{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 date-time string (UTC). Lower bound (inclusive) on `created_at`.","examples":["2026-04-01T00:00:00Z"],"title":"Start Date"},"description":"ISO 8601 date-time string (UTC). Lower bound (inclusive) on `created_at`."},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 date-time string (UTC). Upper bound (inclusive) on `created_at`.","examples":["2026-05-01T00:00:00Z"],"title":"End Date"},"description":"ISO 8601 date-time string (UTC). Upper bound (inclusive) on `created_at`."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"filters","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-encoded array of filter objects. Each object has the shape:\n\n```json\n{ \"attribute\": \"\", \"type\": \"\", \"value\": }\n```\n\nSupported `attribute` / `type` / `value` combinations:\n\n| attribute | type | value shape | matches |\n|-----------------|---------------|----------------------------------------------|------------------------------------------------------|\n| `runId` | `number` | `{ \"value\": 12345 }` | exact run id |\n| `workflowId` | `number` | `{ \"value\": 42 }` | exact agent (workflow) id |\n| `campaignId` | `number` | `{ \"value\": 7 }` | exact campaign id |\n| `callerNumber` | `text` | `{ \"value\": \"415555\" }` | substring match on `initial_context.caller_number` |\n| `calledNumber` | `text` | `{ \"value\": \"9911848\" }` | substring match on `initial_context.called_number` |\n| `dispositionCode` | `multiSelect` | `{ \"codes\": [\"XFER\", \"DNC\"] }` | any of the codes in `gathered_context.mapped_call_disposition` |\n| `duration` | `numberRange` | `{ \"min\": 60, \"max\": 300 }` | call duration (seconds), inclusive bounds |\n\nUnknown attributes and unsupported `type` values are silently ignored.\n\nDate filtering on this endpoint is done via the dedicated `start_date` / `end_date` query params, not via a `dateRange` filter object.\n","examples":["[{\"attribute\":\"callerNumber\",\"type\":\"text\",\"value\":{\"value\":\"415555\"}}]","[{\"attribute\":\"campaignId\",\"type\":\"number\",\"value\":{\"value\":7}},{\"attribute\":\"duration\",\"type\":\"numberRange\",\"value\":{\"min\":60,\"max\":300}}]","[{\"attribute\":\"dispositionCode\",\"type\":\"multiSelect\",\"value\":{\"codes\":[\"XFER\",\"DNC\"]}}]"],"title":"Filters"},"description":"JSON-encoded array of filter objects. Each object has the shape:\n\n```json\n{ \"attribute\": \"\", \"type\": \"\", \"value\": }\n```\n\nSupported `attribute` / `type` / `value` combinations:\n\n| attribute | type | value shape | matches |\n|-----------------|---------------|----------------------------------------------|------------------------------------------------------|\n| `runId` | `number` | `{ \"value\": 12345 }` | exact run id |\n| `workflowId` | `number` | `{ \"value\": 42 }` | exact agent (workflow) id |\n| `campaignId` | `number` | `{ \"value\": 7 }` | exact campaign id |\n| `callerNumber` | `text` | `{ \"value\": \"415555\" }` | substring match on `initial_context.caller_number` |\n| `calledNumber` | `text` | `{ \"value\": \"9911848\" }` | substring match on `initial_context.called_number` |\n| `dispositionCode` | `multiSelect` | `{ \"codes\": [\"XFER\", \"DNC\"] }` | any of the codes in `gathered_context.mapped_call_disposition` |\n| `duration` | `numberRange` | `{ \"min\": 60, \"max\": 300 }` | call duration (seconds), inclusive bounds |\n\nUnknown attributes and unsupported `type` values are silently ignored.\n\nDate filtering on this endpoint is done via the dedicated `start_date` / `end_date` query params, not via a `dateRange` filter object.\n"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageHistoryResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/usage/runs/report":{"get":{"tags":["main"],"summary":"Download Usage Runs Report","description":"Download a CSV of runs matching the same filters as `/usage/runs`.","operationId":"download_usage_runs_report_api_v1_organizations_usage_runs_report_get","parameters":[{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 date-time string (UTC). Lower bound (inclusive) on `created_at`.","title":"Start Date"},"description":"ISO 8601 date-time string (UTC). Lower bound (inclusive) on `created_at`."},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 date-time string (UTC). Upper bound (inclusive) on `created_at`.","title":"End Date"},"description":"ISO 8601 date-time string (UTC). Upper bound (inclusive) on `created_at`."},{"name":"filters","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-encoded array of filter objects. Each object has the shape:\n\n```json\n{ \"attribute\": \"\", \"type\": \"\", \"value\": }\n```\n\nSupported `attribute` / `type` / `value` combinations:\n\n| attribute | type | value shape | matches |\n|-----------------|---------------|----------------------------------------------|------------------------------------------------------|\n| `runId` | `number` | `{ \"value\": 12345 }` | exact run id |\n| `workflowId` | `number` | `{ \"value\": 42 }` | exact agent (workflow) id |\n| `campaignId` | `number` | `{ \"value\": 7 }` | exact campaign id |\n| `callerNumber` | `text` | `{ \"value\": \"415555\" }` | substring match on `initial_context.caller_number` |\n| `calledNumber` | `text` | `{ \"value\": \"9911848\" }` | substring match on `initial_context.called_number` |\n| `dispositionCode` | `multiSelect` | `{ \"codes\": [\"XFER\", \"DNC\"] }` | any of the codes in `gathered_context.mapped_call_disposition` |\n| `duration` | `numberRange` | `{ \"min\": 60, \"max\": 300 }` | call duration (seconds), inclusive bounds |\n\nUnknown attributes and unsupported `type` values are silently ignored.\n\nDate filtering on this endpoint is done via the dedicated `start_date` / `end_date` query params, not via a `dateRange` filter object.\n","title":"Filters"},"description":"JSON-encoded array of filter objects. Each object has the shape:\n\n```json\n{ \"attribute\": \"\", \"type\": \"\", \"value\": }\n```\n\nSupported `attribute` / `type` / `value` combinations:\n\n| attribute | type | value shape | matches |\n|-----------------|---------------|----------------------------------------------|------------------------------------------------------|\n| `runId` | `number` | `{ \"value\": 12345 }` | exact run id |\n| `workflowId` | `number` | `{ \"value\": 42 }` | exact agent (workflow) id |\n| `campaignId` | `number` | `{ \"value\": 7 }` | exact campaign id |\n| `callerNumber` | `text` | `{ \"value\": \"415555\" }` | substring match on `initial_context.caller_number` |\n| `calledNumber` | `text` | `{ \"value\": \"9911848\" }` | substring match on `initial_context.called_number` |\n| `dispositionCode` | `multiSelect` | `{ \"codes\": [\"XFER\", \"DNC\"] }` | any of the codes in `gathered_context.mapped_call_disposition` |\n| `duration` | `numberRange` | `{ \"min\": 60, \"max\": 300 }` | call duration (seconds), inclusive bounds |\n\nUnknown attributes and unsupported `type` values are silently ignored.\n\nDate filtering on this endpoint is done via the dedicated `start_date` / `end_date` query params, not via a `dateRange` filter object.\n"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/usage/daily-breakdown":{"get":{"tags":["main"],"summary":"Get Daily Usage Breakdown","description":"Get daily usage breakdown for the last N days. Only available for organizations with pricing.","operationId":"get_daily_usage_breakdown_api_v1_organizations_usage_daily_breakdown_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":30,"minimum":1,"description":"Number of days to include","default":7,"title":"Days"},"description":"Number of days to include"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DailyUsageBreakdownResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/reports/daily":{"get":{"tags":["main"],"summary":"Get Daily Report","description":"Get daily report for the specified date and timezone.\nIf workflow_id is provided, filters results to that specific workflow.\nIf workflow_id is None, includes all workflows for the organization.","operationId":"get_daily_report_api_v1_organizations_reports_daily_get","parameters":[{"name":"date","in":"query","required":true,"schema":{"type":"string","description":"Date in YYYY-MM-DD format","title":"Date"},"description":"Date in YYYY-MM-DD format"},{"name":"timezone","in":"query","required":true,"schema":{"type":"string","description":"IANA timezone (e.g., 'America/New_York')","title":"Timezone"},"description":"IANA timezone (e.g., 'America/New_York')"},{"name":"workflow_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Optional workflow ID to filter by","title":"Workflow Id"},"description":"Optional workflow ID to filter by"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DailyReportResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/reports/workflows":{"get":{"tags":["main"],"summary":"Get Workflow Options","description":"Get all workflows for the user's organization.\nUsed to populate the workflow selector dropdown in the reports page.","operationId":"get_workflow_options_api_v1_organizations_reports_workflows_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowOption"},"title":"Response Get Workflow Options Api V1 Organizations Reports Workflows Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/organizations/reports/daily/runs":{"get":{"tags":["main"],"summary":"Get Daily Runs Detail","description":"Get detailed workflow runs for the specified date.\nUsed for CSV export functionality.","operationId":"get_daily_runs_detail_api_v1_organizations_reports_daily_runs_get","parameters":[{"name":"date","in":"query","required":true,"schema":{"type":"string","description":"Date in YYYY-MM-DD format","title":"Date"},"description":"Date in YYYY-MM-DD format"},{"name":"timezone","in":"query","required":true,"schema":{"type":"string","description":"IANA timezone (e.g., 'America/New_York')","title":"Timezone"},"description":"IANA timezone (e.g., 'America/New_York')"},{"name":"workflow_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Optional workflow ID to filter by","title":"Workflow Id"},"description":"Optional workflow ID to filter by"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowRunDetail"},"title":"Response Get Daily Runs Detail Api V1 Organizations Reports Daily Runs Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/turn/credentials":{"get":{"tags":["main","turn"],"summary":"Get Turn Credentials","description":"Get time-limited TURN credentials for WebRTC connections.\n\nThis endpoint generates ephemeral TURN credentials that are:\n- Valid for the configured TTL (default: 24 hours)\n- Cryptographically bound to the user via HMAC\n- Compatible with coturn's use-auth-secret mode\n\nReturns:\n TurnCredentialsResponse with username, password, ttl, and TURN URIs","operationId":"get_turn_credentials_api_v1_turn_credentials_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TurnCredentialsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/embed/init":{"post":{"tags":["main"],"summary":"Initialize Embed Session","description":"Initialize an embed session with token validation and domain checking.\n\nThis endpoint:\n1. Validates the embed token\n2. Checks domain whitelist\n3. Creates a workflow run\n4. Generates a temporary session token\n5. Returns configuration for the widget","operationId":"initialize_embed_session_api_v1_public_embed_init_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitEmbedRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitEmbedResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"options":{"tags":["main"],"summary":"Options Init","description":"Fallback OPTIONS handler for init endpoint.","operationId":"options_init_api_v1_public_embed_init_options","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"}}}},"/api/v1/public/embed/config/{token}":{"options":{"tags":["main"],"summary":"Options Embed Config","description":"Fallback OPTIONS handler for the embed config endpoint.\n\nBrowser preflights include Access-Control-Request-Method and are handled by\nPublicEmbedCORSMiddleware before global CORS. This keeps non-conformant\nOPTIONS requests on the same validation path.","operationId":"options_embed_config_api_v1_public_embed_config__token__options","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["main"],"summary":"Get Embed Config","description":"Get embed configuration without creating a session.\n\nThis endpoint is used to fetch widget configuration for display purposes\nwithout actually starting a call session.","operationId":"get_embed_config_api_v1_public_embed_config__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbedConfigResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/embed/turn-credentials/{session_token}":{"get":{"tags":["main"],"summary":"Get Public Turn Credentials","description":"Get TURN credentials for an embed session.\n\nThis endpoint allows embedded widgets to obtain TURN server credentials\nfor WebRTC connections without requiring authentication.\n\nArgs:\n session_token: The session token from embed initialization\n\nReturns:\n TurnCredentialsResponse with username, password, ttl, and TURN URIs","operationId":"get_public_turn_credentials_api_v1_public_embed_turn_credentials__session_token__get","parameters":[{"name":"session_token","in":"path","required":true,"schema":{"type":"string","title":"Session Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TurnCredentialsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"options":{"tags":["main"],"summary":"Options Turn Credentials","description":"Fallback OPTIONS handler for TURN credentials endpoint.","operationId":"options_turn_credentials_api_v1_public_embed_turn_credentials__session_token__options","parameters":[{"name":"session_token","in":"path","required":true,"schema":{"type":"string","title":"Session Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/agent/{uuid}":{"post":{"tags":["main"],"summary":"Initiate Call","description":"Initiate a phone call against the published agent.\n\nExecutes the workflow's currently released definition.","operationId":"initiate_call_api_v1_public_agent__uuid__post","parameters":[{"name":"uuid","in":"path","required":true,"schema":{"type":"string","title":"Uuid"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/agent/test/{uuid}":{"post":{"tags":["main"],"summary":"Initiate Call Test","description":"Initiate a phone call against the latest draft of the agent.\n\nUseful for verifying changes before publishing. Falls back to the\npublished definition when no draft exists.","operationId":"initiate_call_test_api_v1_public_agent_test__uuid__post","parameters":[{"name":"uuid","in":"path","required":true,"schema":{"type":"string","title":"Uuid"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/agent/workflow/{workflow_uuid}":{"post":{"tags":["main"],"summary":"Initiate Call By Workflow Uuid","description":"Initiate a phone call against the published workflow identified by UUID.","operationId":"initiate_call_by_workflow_uuid_api_v1_public_agent_workflow__workflow_uuid__post","parameters":[{"name":"workflow_uuid","in":"path","required":true,"schema":{"type":"string","title":"Workflow Uuid"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/agent/test/workflow/{workflow_uuid}":{"post":{"tags":["main"],"summary":"Initiate Call Test By Workflow Uuid","description":"Initiate a phone call against the latest draft of the workflow by UUID.","operationId":"initiate_call_test_by_workflow_uuid_api_v1_public_agent_test_workflow__workflow_uuid__post","parameters":[{"name":"workflow_uuid","in":"path","required":true,"schema":{"type":"string","title":"Workflow Uuid"}},{"name":"X-API-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerCallResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/public/download/workflow/{token}/{artifact_type}":{"get":{"tags":["main"],"summary":"Download Workflow Artifact","description":"Download a workflow recording or transcript via public access token.\n\nThis endpoint:\n1. Validates the public access token\n2. Looks up the corresponding workflow run\n3. Generates a signed URL for the requested artifact\n4. Redirects to the signed URL\n\nArgs:\n token: The public access token (UUID format)\n artifact_type: Type of artifact - \"recording\", \"transcript\",\n \"user_recording\", or \"bot_recording\"\n inline: If true, sets Content-Disposition to inline for browser preview\n\nReturns:\n RedirectResponse to the signed URL (302 redirect)\n\nRaises:\n HTTPException 400: If artifact type is unsupported\n HTTPException 404: If token is invalid or artifact not found","operationId":"download_workflow_artifact_api_v1_public_download_workflow__token___artifact_type__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"artifact_type","in":"path","required":true,"schema":{"type":"string","title":"Artifact Type"}},{"name":"inline","in":"query","required":false,"schema":{"type":"boolean","description":"Display inline in browser instead of download","default":false,"title":"Inline"},"description":"Display inline in browser instead of download"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow/{workflow_id}/embed-token":{"post":{"tags":["main"],"summary":"Create Or Update Embed Token","description":"Create or update an embed token for a workflow.\nEach workflow can have only one active embed token.","operationId":"create_or_update_embed_token_api_v1_workflow__workflow_id__embed_token_post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbedTokenRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbedTokenResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["main"],"summary":"Get Embed Token","description":"Get the embed token for a workflow if it exists.","operationId":"get_embed_token_api_v1_workflow__workflow_id__embed_token_get","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/EmbedTokenResponse"},{"type":"null"}],"title":"Response Get Embed Token Api V1 Workflow Workflow Id Embed Token Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main"],"summary":"Deactivate Embed Token","description":"Deactivate the embed token for a workflow.","operationId":"deactivate_embed_token_api_v1_workflow__workflow_id__embed_token_delete","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Deactivate Embed Token Api V1 Workflow Workflow Id Embed Token Delete"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/knowledge-base/upload-url":{"post":{"tags":["main","knowledge-base"],"summary":"Get presigned URL for document upload","description":"Generate a presigned PUT URL for uploading a document.\n\nThis endpoint:\n1. Generates a unique document UUID for organizing the S3 key\n2. Generates a presigned S3/MinIO URL for uploading the file\n3. Returns the upload URL and document metadata\n\nAfter uploading to the returned URL, call /process-document to create\nthe document record and trigger processing.\n\nAccess Control:\n* All authenticated users can upload documents scoped to their organization.","operationId":"get_upload_url_api_v1_knowledge_base_upload_url_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentUploadRequestSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentUploadResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/knowledge-base/process-document":{"post":{"tags":["main","knowledge-base"],"summary":"Trigger document processing","description":"Trigger asynchronous processing of an uploaded document.\n\nThis endpoint should be called after successfully uploading a file to the presigned URL.\nIt will:\n1. Create a document record in the database with the specified UUID\n2. Enqueue a background task to process the document (chunking and embedding)\n\nThe document status will be updated from 'pending' -> 'processing' -> 'completed' or 'failed'.\n\nEmbedding:\nUses OpenAI text-embedding-3-small (1536-dimensional embeddings, requires API key configured in Model Configurations).\n\nAccess Control:\n* Users can only process documents in their organization.","operationId":"process_document_api_v1_knowledge_base_process_document_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProcessDocumentRequestSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/knowledge-base/documents":{"get":{"tags":["main","knowledge-base"],"summary":"List documents","description":"List all documents for the user's organization.\n\nAccess Control:\n* Users can only see documents from their organization.","operationId":"list_documents_api_v1_knowledge_base_documents_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by processing status","title":"Status"},"description":"Filter by processing status"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentListResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"list_documents","x-sdk-description":"List knowledge base documents available to the authenticated organization."}},"/api/v1/knowledge-base/documents/{document_uuid}":{"get":{"tags":["main","knowledge-base"],"summary":"Get document details","description":"Get details of a specific document.\n\nAccess Control:\n* Users can only access documents from their organization.","operationId":"get_document_api_v1_knowledge_base_documents__document_uuid__get","parameters":[{"name":"document_uuid","in":"path","required":true,"schema":{"type":"string","title":"Document Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main","knowledge-base"],"summary":"Delete document","description":"Soft delete a document and its chunks.\n\nAccess Control:\n* Users can only delete documents from their organization.","operationId":"delete_document_api_v1_knowledge_base_documents__document_uuid__delete","parameters":[{"name":"document_uuid","in":"path","required":true,"schema":{"type":"string","title":"Document Uuid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/knowledge-base/search":{"post":{"tags":["main","knowledge-base"],"summary":"Search for similar chunks","description":"Search for document chunks similar to the query.\n\nThis endpoint uses vector similarity search to find relevant chunks.\nResults are returned without threshold filtering - apply similarity\nthresholds at the application layer after optional reranking.\n\nAccess Control:\n* Users can only search documents from their organization.","operationId":"search_chunks_api_v1_knowledge_base_search_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkSearchRequestSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkSearchResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow-recordings/upload-url":{"post":{"tags":["main","workflow-recordings"],"summary":"Get presigned URLs for recording uploads","description":"Generate presigned PUT URLs for uploading one or more audio recordings.","operationId":"get_upload_urls_api_v1_workflow_recordings_upload_url_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRecordingUploadRequestSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRecordingUploadResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow-recordings/":{"post":{"tags":["main","workflow-recordings"],"summary":"Create recording records after upload","description":"Create one or more recording records after audio files have been uploaded.","operationId":"create_recordings_api_v1_workflow_recordings__post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRecordingCreateRequestSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRecordingCreateResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["main","workflow-recordings"],"summary":"List recordings","description":"List recordings for the organization, optionally filtered.","operationId":"list_recordings_api_v1_workflow_recordings__get","parameters":[{"name":"workflow_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filter by workflow ID","title":"Workflow Id"},"description":"Filter by workflow ID"},{"name":"tts_provider","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by TTS provider","title":"Tts Provider"},"description":"Filter by TTS provider"},{"name":"tts_model","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by TTS model","title":"Tts Model"},"description":"Filter by TTS model"},{"name":"tts_voice_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by TTS voice ID","title":"Tts Voice Id"},"description":"Filter by TTS voice ID"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingListResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"list_recordings","x-sdk-description":"List workflow recordings available to the authenticated organization."}},"/api/v1/workflow-recordings/{recording_id}":{"delete":{"tags":["main","workflow-recordings"],"summary":"Delete a recording","description":"Soft delete a recording.","operationId":"delete_recording_api_v1_workflow_recordings__recording_id__delete","parameters":[{"name":"recording_id","in":"path","required":true,"schema":{"type":"string","title":"Recording Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow-recordings/{id}":{"patch":{"tags":["main","workflow-recordings"],"summary":"Update a recording's Recording ID","description":"Update the recording_id (descriptive name) of a recording.","operationId":"update_recording_api_v1_workflow_recordings__id__patch","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingUpdateRequestSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingResponseSchema"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workflow-recordings/transcribe":{"post":{"tags":["main","workflow-recordings"],"summary":"Transcribe an audio file","description":"Transcribe an uploaded audio file using MPS STT.","operationId":"transcribe_audio_api_v1_workflow_recordings_transcribe_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_transcribe_audio_api_v1_workflow_recordings_transcribe_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folder/":{"get":{"tags":["main"],"summary":"List Folders","description":"List all folders in the authenticated user's organization.","operationId":"list_folders_api_v1_folder__get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FolderResponse"},"title":"Response List Folders Api V1 Folder Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["main"],"summary":"Create Folder","description":"Create a new folder in the authenticated user's organization.","operationId":"create_folder_api_v1_folder__post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFolderRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/folder/{folder_id}":{"put":{"tags":["main"],"summary":"Rename Folder","description":"Rename a folder owned by the authenticated user's organization.","operationId":"rename_folder_api_v1_folder__folder_id__put","parameters":[{"name":"folder_id","in":"path","required":true,"schema":{"type":"integer","title":"Folder Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFolderRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["main"],"summary":"Delete Folder","description":"Delete a folder. Member agents are moved to \"Uncategorized\", not deleted.","operationId":"delete_folder_api_v1_folder__folder_id__delete","parameters":[{"name":"folder_id","in":"path","required":true,"schema":{"type":"integer","title":"Folder Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"boolean"},"title":"Response Delete Folder Api V1 Folder Folder Id Delete"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/signup":{"post":{"tags":["main","auth"],"summary":"Signup","operationId":"signup_api_v1_auth_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["main","auth"],"summary":"Login","operationId":"login_api_v1_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/me":{"get":{"tags":["main","auth"],"summary":"Get Current User","operationId":"get_current_user_api_v1_auth_me_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/node-types":{"get":{"tags":["main"],"summary":"List Node Types","description":"List every registered NodeSpec.\n\nSDK clients should pin to `spec_version` and warn if the server reports\na higher version than what they were generated against.","operationId":"list_node_types_api_v1_node_types_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NodeTypesResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"list_node_types","x-sdk-description":"List every registered node type with its spec. Pinned to spec_version."}},"/api/v1/node-types/{name}":{"get":{"tags":["main"],"summary":"Get Node Type","operationId":"get_node_type_api_v1_node_types__name__get","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NodeSpec"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-sdk-method":"get_node_type","x-sdk-description":"Fetch a single node spec by name."}},"/api/v1/health":{"get":{"tags":["main"],"summary":"Health","operationId":"health_api_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"404":{"description":"Not found"}}}}},"components":{"schemas":{"APIKeyResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"key_prefix":{"type":"string","title":"Key Prefix"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"archived_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Archived At"}},"type":"object","required":["id","name","key_prefix","is_active","created_at"],"title":"APIKeyResponse"},"APIKeyStatus":{"properties":{"model":{"type":"string","title":"Model"},"message":{"type":"string","title":"Message"}},"type":"object","required":["model","message"],"title":"APIKeyStatus"},"APIKeyStatusResponse":{"properties":{"status":{"items":{"$ref":"#/components/schemas/APIKeyStatus"},"type":"array","title":"Status"}},"type":"object","required":["status"],"title":"APIKeyStatusResponse"},"ARIConfigurationRequest":{"properties":{"provider":{"type":"string","const":"ari","title":"Provider","default":"ari"},"ari_endpoint":{"type":"string","title":"Ari Endpoint","description":"ARI base URL (e.g., http://asterisk.example.com:8088)"},"app_name":{"type":"string","title":"App Name","description":"Stasis application name registered in Asterisk"},"app_password":{"type":"string","title":"App Password","description":"ARI user password"},"ws_client_name":{"type":"string","title":"Ws Client Name","description":"websocket_client.conf connection name for externalMedia (e.g., dograh_staging)","default":""},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of SIP extensions/numbers for outbound calls (optional)"}},"type":"object","required":["ari_endpoint","app_name","app_password"],"title":"ARIConfigurationRequest","description":"Request schema for Asterisk ARI configuration."},"ARIConfigurationResponse":{"properties":{"provider":{"type":"string","const":"ari","title":"Provider","default":"ari"},"ari_endpoint":{"type":"string","title":"Ari Endpoint"},"app_name":{"type":"string","title":"App Name"},"app_password":{"type":"string","title":"App Password"},"ws_client_name":{"type":"string","title":"Ws Client Name","default":""},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["ari_endpoint","app_name","app_password","from_numbers"],"title":"ARIConfigurationResponse","description":"Response schema for ARI configuration with masked sensitive fields."},"AWSBedrockLLMConfiguration":{"properties":{"provider":{"type":"string","const":"aws_bedrock","title":"Provider","default":"aws_bedrock"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Not used for Bedrock \u2014 authentication is via the AWS credentials above. Leave blank."},"model":{"type":"string","title":"Model","description":"Bedrock model ID \u2014 include the region inference-profile prefix (e.g. 'us.').","default":"us.amazon.nova-pro-v1:0","examples":["us.amazon.nova-pro-v1:0","us.amazon.nova-lite-v1:0","us.amazon.nova-micro-v1:0","us.anthropic.claude-sonnet-4-20250514-v1:0","us.anthropic.claude-3-5-sonnet-20241022-v2:0","us.anthropic.claude-haiku-4-5-20251001-v1:0"],"allow_custom_input":true},"aws_access_key":{"type":"string","title":"Aws Access Key","description":"AWS access key ID with bedrock:InvokeModel permission.","default":""},"aws_secret_key":{"type":"string","title":"Aws Secret Key","description":"AWS secret access key paired with the access key ID.","default":""},"aws_region":{"type":"string","title":"Aws Region","description":"AWS region where the Bedrock model is available.","default":"us-east-1"}},"type":"object","title":"AWS Bedrock"},"AmbientNoiseUploadRequest":{"properties":{"workflow_id":{"type":"integer","title":"Workflow Id"},"filename":{"type":"string","title":"Filename"},"mime_type":{"type":"string","title":"Mime Type","default":"audio/wav"},"file_size":{"type":"integer","maximum":10485760.0,"exclusiveMinimum":0.0,"title":"File Size","description":"Max 10MB"}},"type":"object","required":["workflow_id","filename","file_size"],"title":"AmbientNoiseUploadRequest"},"AmbientNoiseUploadResponse":{"properties":{"upload_url":{"type":"string","title":"Upload Url"},"storage_key":{"type":"string","title":"Storage Key"},"storage_backend":{"type":"string","title":"Storage Backend"}},"type":"object","required":["upload_url","storage_key","storage_backend"],"title":"AmbientNoiseUploadResponse"},"AppendTextChatMessageRequest":{"properties":{"text":{"type":"string","minLength":1,"title":"Text"},"expected_revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Revision"}},"type":"object","required":["text"],"title":"AppendTextChatMessageRequest"},"AssemblyAISTTConfiguration":{"properties":{"provider":{"type":"string","const":"assemblyai","title":"Provider","default":"assemblyai"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"AssemblyAI realtime STT model.","default":"u3-rt-pro","examples":["u3-rt-pro"]},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code.","default":"en","examples":["en","es","de","fr","pt","it"]}},"type":"object","required":["api_key"],"title":"AssemblyAI"},"AuthResponse":{"properties":{"token":{"type":"string","title":"Token"},"user":{"$ref":"#/components/schemas/UserResponse"}},"type":"object","required":["token","user"],"title":"AuthResponse"},"AuthUserResponse":{"properties":{"id":{"type":"integer","title":"Id"},"is_superuser":{"type":"boolean","title":"Is Superuser"}},"type":"object","required":["id","is_superuser"],"title":"AuthUserResponse"},"AzureLLMService":{"properties":{"provider":{"type":"string","const":"azure","title":"Provider","default":"azure"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Azure deployment name (not the upstream OpenAI model id).","default":"gpt-4.1-mini","examples":["gpt-4.1-mini"],"allow_custom_input":true},"endpoint":{"type":"string","title":"Endpoint","description":"Azure OpenAI resource endpoint (e.g. https://.openai.azure.com)."}},"type":"object","required":["api_key","endpoint"],"title":"Azure OpenAI"},"AzureOpenAIEmbeddingsConfiguration":{"properties":{"provider":{"type":"string","const":"azure","title":"Provider","default":"azure"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Azure OpenAI embedding deployment name. The deployment must return 1536-dimensional embeddings.","default":"text-embedding-3-small","examples":["text-embedding-3-small","text-embedding-ada-002"],"allow_custom_input":true},"endpoint":{"type":"string","title":"Endpoint","description":"Azure OpenAI resource endpoint (e.g. https://.openai.azure.com)."},"api_version":{"type":"string","title":"Api Version","description":"Azure OpenAI API version for embeddings.","default":"2024-02-15-preview"}},"type":"object","required":["api_key","endpoint"],"title":"Azure OpenAI"},"AzureRealtimeLLMConfiguration":{"properties":{"provider":{"type":"string","const":"azure_realtime","title":"Provider","default":"azure_realtime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Azure OpenAI realtime deployment name.","default":"gpt-4o-realtime-preview","examples":["gpt-4o-realtime-preview"],"allow_custom_input":true},"endpoint":{"type":"string","title":"Endpoint","description":"Azure OpenAI resource endpoint (e.g. https://.openai.azure.com)."},"voice":{"type":"string","title":"Voice","description":"Voice the model speaks in.","default":"alloy","examples":["alloy","ash","ballad","coral","echo","sage","shimmer","verse"],"allow_custom_input":true},"api_version":{"type":"string","title":"Api Version","description":"Azure OpenAI API version.","default":"2025-04-01-preview","examples":["2025-04-01-preview","2024-10-01-preview","2024-12-17"]}},"type":"object","required":["api_key","endpoint"],"title":"Azure OpenAI Realtime","description":"Azure OpenAI Realtime API \u2014 low-latency speech-to-speech conversations.","provider_docs_url":"https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/realtime-audio-quickstart"},"AzureSpeechSTTConfiguration":{"properties":{"provider":{"type":"string","const":"azure_speech","title":"Provider","default":"azure_speech"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Azure Speech recognition model (use 'latest_long' for continuous recognition).","default":"latest_long","examples":["latest_long","latest_short"]},"region":{"type":"string","title":"Region","description":"Azure region for Speech Services (e.g. 'eastus', 'westeurope').","default":"eastus","examples":["eastus","eastus2","westus","westus2","westus3","centralus","northcentralus","southcentralus","westcentralus","westeurope","northeurope","uksouth","ukwest","francecentral","switzerlandnorth","germanywestcentral","norwayeast","australiaeast","eastasia","southeastasia","japaneast","japanwest","koreacentral","centralindia","southindia","brazilsouth"]},"language":{"type":"string","title":"Language","description":"BCP-47 language code for recognition.","default":"en-US","examples":["en-US","en-GB","en-AU","en-CA","en-IN","es-ES","es-MX","fr-FR","fr-CA","de-DE","it-IT","ja-JP","ko-KR","zh-CN","pt-BR","pt-PT","ru-RU","ar-SA","nl-NL","pl-PL","hi-IN"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Azure Speech Services","description":"Azure Cognitive Services Speech \u2014 TTS and STT via the Azure Speech SDK.","provider_docs_url":"https://learn.microsoft.com/en-us/azure/ai-services/speech-service/"},"AzureSpeechTTSConfiguration":{"properties":{"provider":{"type":"string","const":"azure_speech","title":"Provider","default":"azure_speech"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Azure Speech synthesis engine (neural voices only).","default":"neural","examples":["neural"]},"region":{"type":"string","title":"Region","description":"Azure region for Speech Services (e.g. 'eastus', 'westeurope').","default":"eastus","examples":["eastus","eastus2","westus","westus2","westus3","centralus","northcentralus","southcentralus","westcentralus","westeurope","northeurope","uksouth","ukwest","francecentral","switzerlandnorth","germanywestcentral","norwayeast","australiaeast","eastasia","southeastasia","japaneast","japanwest","koreacentral","centralindia","southindia","brazilsouth"]},"voice":{"type":"string","title":"Voice","description":"Azure Neural voice name (e.g. 'en-US-AriaNeural').","default":"en-US-AriaNeural","examples":["en-US-AriaNeural","en-US-GuyNeural","en-US-JennyNeural","en-US-DavisNeural","en-US-AmberNeural","en-US-AnaNeural","en-US-AshleyNeural","en-US-BrandonNeural","en-US-ChristopherNeural","en-US-ElizabethNeural","en-US-EricNeural","en-US-JacobNeural","en-US-MichelleNeural","en-US-MonicaNeural","en-US-NancyNeural","en-US-RogerNeural","en-US-SaraNeural","en-US-SteffanNeural","en-US-TonyNeural"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"BCP-47 language code for synthesis.","default":"en-US","examples":["en-US","en-GB","en-AU","en-CA","en-IN","es-ES","es-MX","fr-FR","fr-CA","de-DE","it-IT","ja-JP","ko-KR","zh-CN","zh-HK","zh-TW","pt-BR","pt-PT","ru-RU","ar-SA","nl-NL","pl-PL","sv-SE","hi-IN"],"allow_custom_input":true},"speed":{"type":"number","maximum":2.0,"minimum":0.5,"title":"Speed","description":"Speech speed multiplier (0.5 to 2.0).","default":1.0}},"type":"object","required":["api_key"],"title":"Azure Speech Services","description":"Azure Cognitive Services Speech \u2014 TTS and STT via the Azure Speech SDK.","provider_docs_url":"https://learn.microsoft.com/en-us/azure/ai-services/speech-service/"},"BYOKAIModelConfiguration":{"properties":{"mode":{"type":"string","enum":["pipeline","realtime"],"title":"Mode"},"pipeline":{"anyOf":[{"$ref":"#/components/schemas/BYOKPipelineAIModelConfiguration"},{"type":"null"}]},"realtime":{"anyOf":[{"$ref":"#/components/schemas/BYOKRealtimeAIModelConfiguration"},{"type":"null"}]}},"type":"object","required":["mode"],"title":"BYOKAIModelConfiguration"},"BYOKPipelineAIModelConfiguration":{"properties":{"llm":{"oneOf":[{"$ref":"#/components/schemas/OpenAILLMService"},{"$ref":"#/components/schemas/GoogleVertexLLMConfiguration"},{"$ref":"#/components/schemas/GroqLLMService"},{"$ref":"#/components/schemas/OpenRouterLLMConfiguration"},{"$ref":"#/components/schemas/GoogleLLMService"},{"$ref":"#/components/schemas/AzureLLMService"},{"$ref":"#/components/schemas/DograhLLMService"},{"$ref":"#/components/schemas/AWSBedrockLLMConfiguration"},{"$ref":"#/components/schemas/SpeachesLLMConfiguration"},{"$ref":"#/components/schemas/HuggingFaceLLMConfiguration"},{"$ref":"#/components/schemas/MiniMaxLLMConfiguration"},{"$ref":"#/components/schemas/SarvamLLMConfiguration"}],"title":"Llm","discriminator":{"propertyName":"provider","mapping":{"aws_bedrock":"#/components/schemas/AWSBedrockLLMConfiguration","azure":"#/components/schemas/AzureLLMService","dograh":"#/components/schemas/DograhLLMService","google":"#/components/schemas/GoogleLLMService","google_vertex":"#/components/schemas/GoogleVertexLLMConfiguration","groq":"#/components/schemas/GroqLLMService","huggingface":"#/components/schemas/HuggingFaceLLMConfiguration","minimax":"#/components/schemas/MiniMaxLLMConfiguration","openai":"#/components/schemas/OpenAILLMService","openrouter":"#/components/schemas/OpenRouterLLMConfiguration","sarvam":"#/components/schemas/SarvamLLMConfiguration","speaches":"#/components/schemas/SpeachesLLMConfiguration"}}},"tts":{"oneOf":[{"$ref":"#/components/schemas/DeepgramTTSConfiguration"},{"$ref":"#/components/schemas/GoogleTTSConfiguration"},{"$ref":"#/components/schemas/OpenAITTSService"},{"$ref":"#/components/schemas/ElevenlabsTTSConfiguration"},{"$ref":"#/components/schemas/CartesiaTTSConfiguration"},{"$ref":"#/components/schemas/DograhTTSService"},{"$ref":"#/components/schemas/SarvamTTSConfiguration"},{"$ref":"#/components/schemas/CambTTSConfiguration"},{"$ref":"#/components/schemas/RimeTTSConfiguration"},{"$ref":"#/components/schemas/SpeachesTTSConfiguration"},{"$ref":"#/components/schemas/MiniMaxTTSConfiguration"},{"$ref":"#/components/schemas/AzureSpeechTTSConfiguration"},{"$ref":"#/components/schemas/SmallestAITTSConfiguration"}],"title":"Tts","discriminator":{"propertyName":"provider","mapping":{"azure_speech":"#/components/schemas/AzureSpeechTTSConfiguration","camb":"#/components/schemas/CambTTSConfiguration","cartesia":"#/components/schemas/CartesiaTTSConfiguration","deepgram":"#/components/schemas/DeepgramTTSConfiguration","dograh":"#/components/schemas/DograhTTSService","elevenlabs":"#/components/schemas/ElevenlabsTTSConfiguration","google":"#/components/schemas/GoogleTTSConfiguration","minimax":"#/components/schemas/MiniMaxTTSConfiguration","openai":"#/components/schemas/OpenAITTSService","rime":"#/components/schemas/RimeTTSConfiguration","sarvam":"#/components/schemas/SarvamTTSConfiguration","smallest":"#/components/schemas/SmallestAITTSConfiguration","speaches":"#/components/schemas/SpeachesTTSConfiguration"}}},"stt":{"oneOf":[{"$ref":"#/components/schemas/DeepgramSTTConfiguration"},{"$ref":"#/components/schemas/CartesiaSTTConfiguration"},{"$ref":"#/components/schemas/OpenAISTTConfiguration"},{"$ref":"#/components/schemas/GoogleSTTConfiguration"},{"$ref":"#/components/schemas/DograhSTTService"},{"$ref":"#/components/schemas/SpeechmaticsSTTConfiguration"},{"$ref":"#/components/schemas/SarvamSTTConfiguration"},{"$ref":"#/components/schemas/SpeachesSTTConfiguration"},{"$ref":"#/components/schemas/HuggingFaceSTTConfiguration"},{"$ref":"#/components/schemas/AssemblyAISTTConfiguration"},{"$ref":"#/components/schemas/GladiaSTTConfiguration"},{"$ref":"#/components/schemas/AzureSpeechSTTConfiguration"},{"$ref":"#/components/schemas/SmallestAISTTConfiguration"}],"title":"Stt","discriminator":{"propertyName":"provider","mapping":{"assemblyai":"#/components/schemas/AssemblyAISTTConfiguration","azure_speech":"#/components/schemas/AzureSpeechSTTConfiguration","cartesia":"#/components/schemas/CartesiaSTTConfiguration","deepgram":"#/components/schemas/DeepgramSTTConfiguration","dograh":"#/components/schemas/DograhSTTService","gladia":"#/components/schemas/GladiaSTTConfiguration","google":"#/components/schemas/GoogleSTTConfiguration","huggingface":"#/components/schemas/HuggingFaceSTTConfiguration","openai":"#/components/schemas/OpenAISTTConfiguration","sarvam":"#/components/schemas/SarvamSTTConfiguration","smallest":"#/components/schemas/SmallestAISTTConfiguration","speaches":"#/components/schemas/SpeachesSTTConfiguration","speechmatics":"#/components/schemas/SpeechmaticsSTTConfiguration"}}},"embeddings":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/OpenAIEmbeddingsConfiguration"},{"$ref":"#/components/schemas/OpenRouterEmbeddingsConfiguration"},{"$ref":"#/components/schemas/AzureOpenAIEmbeddingsConfiguration"},{"$ref":"#/components/schemas/DograhEmbeddingsConfiguration"}],"discriminator":{"propertyName":"provider","mapping":{"azure":"#/components/schemas/AzureOpenAIEmbeddingsConfiguration","dograh":"#/components/schemas/DograhEmbeddingsConfiguration","openai":"#/components/schemas/OpenAIEmbeddingsConfiguration","openrouter":"#/components/schemas/OpenRouterEmbeddingsConfiguration"}}},{"type":"null"}],"title":"Embeddings"}},"type":"object","required":["llm","tts","stt"],"title":"BYOKPipelineAIModelConfiguration"},"BYOKRealtimeAIModelConfiguration":{"properties":{"realtime":{"oneOf":[{"$ref":"#/components/schemas/OpenAIRealtimeLLMConfiguration"},{"$ref":"#/components/schemas/GrokRealtimeLLMConfiguration"},{"$ref":"#/components/schemas/UltravoxRealtimeLLMConfiguration"},{"$ref":"#/components/schemas/GoogleRealtimeLLMConfiguration"},{"$ref":"#/components/schemas/GoogleVertexRealtimeLLMConfiguration"},{"$ref":"#/components/schemas/AzureRealtimeLLMConfiguration"}],"title":"Realtime","discriminator":{"propertyName":"provider","mapping":{"azure_realtime":"#/components/schemas/AzureRealtimeLLMConfiguration","google_realtime":"#/components/schemas/GoogleRealtimeLLMConfiguration","google_vertex_realtime":"#/components/schemas/GoogleVertexRealtimeLLMConfiguration","grok_realtime":"#/components/schemas/GrokRealtimeLLMConfiguration","openai_realtime":"#/components/schemas/OpenAIRealtimeLLMConfiguration","ultravox_realtime":"#/components/schemas/UltravoxRealtimeLLMConfiguration"}}},"llm":{"oneOf":[{"$ref":"#/components/schemas/OpenAILLMService"},{"$ref":"#/components/schemas/GoogleVertexLLMConfiguration"},{"$ref":"#/components/schemas/GroqLLMService"},{"$ref":"#/components/schemas/OpenRouterLLMConfiguration"},{"$ref":"#/components/schemas/GoogleLLMService"},{"$ref":"#/components/schemas/AzureLLMService"},{"$ref":"#/components/schemas/DograhLLMService"},{"$ref":"#/components/schemas/AWSBedrockLLMConfiguration"},{"$ref":"#/components/schemas/SpeachesLLMConfiguration"},{"$ref":"#/components/schemas/HuggingFaceLLMConfiguration"},{"$ref":"#/components/schemas/MiniMaxLLMConfiguration"},{"$ref":"#/components/schemas/SarvamLLMConfiguration"}],"title":"Llm","discriminator":{"propertyName":"provider","mapping":{"aws_bedrock":"#/components/schemas/AWSBedrockLLMConfiguration","azure":"#/components/schemas/AzureLLMService","dograh":"#/components/schemas/DograhLLMService","google":"#/components/schemas/GoogleLLMService","google_vertex":"#/components/schemas/GoogleVertexLLMConfiguration","groq":"#/components/schemas/GroqLLMService","huggingface":"#/components/schemas/HuggingFaceLLMConfiguration","minimax":"#/components/schemas/MiniMaxLLMConfiguration","openai":"#/components/schemas/OpenAILLMService","openrouter":"#/components/schemas/OpenRouterLLMConfiguration","sarvam":"#/components/schemas/SarvamLLMConfiguration","speaches":"#/components/schemas/SpeachesLLMConfiguration"}}},"embeddings":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/OpenAIEmbeddingsConfiguration"},{"$ref":"#/components/schemas/OpenRouterEmbeddingsConfiguration"},{"$ref":"#/components/schemas/AzureOpenAIEmbeddingsConfiguration"},{"$ref":"#/components/schemas/DograhEmbeddingsConfiguration"}],"discriminator":{"propertyName":"provider","mapping":{"azure":"#/components/schemas/AzureOpenAIEmbeddingsConfiguration","dograh":"#/components/schemas/DograhEmbeddingsConfiguration","openai":"#/components/schemas/OpenAIEmbeddingsConfiguration","openrouter":"#/components/schemas/OpenRouterEmbeddingsConfiguration"}}},{"type":"null"}],"title":"Embeddings"}},"type":"object","required":["realtime","llm"],"title":"BYOKRealtimeAIModelConfiguration"},"BatchRecordingCreateRequestSchema":{"properties":{"recordings":{"items":{"$ref":"#/components/schemas/RecordingCreateRequestSchema"},"type":"array","maxItems":20,"minItems":1,"title":"Recordings","description":"List of recordings to create"}},"type":"object","required":["recordings"],"title":"BatchRecordingCreateRequestSchema","description":"Request schema for creating one or more recording records after upload."},"BatchRecordingCreateResponseSchema":{"properties":{"recordings":{"items":{"$ref":"#/components/schemas/RecordingResponseSchema"},"type":"array","title":"Recordings","description":"Created recording records"}},"type":"object","required":["recordings"],"title":"BatchRecordingCreateResponseSchema","description":"Response schema for recording creation."},"BatchRecordingUploadRequestSchema":{"properties":{"files":{"items":{"$ref":"#/components/schemas/FileDescriptor"},"type":"array","maxItems":20,"minItems":1,"title":"Files","description":"List of files to upload"}},"type":"object","required":["files"],"title":"BatchRecordingUploadRequestSchema","description":"Request schema for getting presigned upload URLs for one or more files."},"BatchRecordingUploadResponseSchema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/RecordingUploadResponseSchema"},"type":"array","title":"Items","description":"Upload URLs for each file"}},"type":"object","required":["items"],"title":"BatchRecordingUploadResponseSchema","description":"Response schema with presigned upload URLs."},"Body_transcribe_audio_api_v1_workflow_recordings_transcribe_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"language":{"type":"string","title":"Language","default":"en"}},"type":"object","required":["file"],"title":"Body_transcribe_audio_api_v1_workflow_recordings_transcribe_post"},"CalculatorToolDefinition":{"properties":{"schema_version":{"type":"integer","title":"Schema Version","description":"Schema version.","default":1},"type":{"type":"string","const":"calculator","title":"Type","description":"Tool type."}},"type":"object","required":["type"],"title":"CalculatorToolDefinition","description":"Tool definition for Calculator tools."},"CallDispositionCodes":{"properties":{"disposition_codes":{"items":{"type":"string"},"type":"array","title":"Disposition Codes","default":[]}},"type":"object","title":"CallDispositionCodes"},"CallType":{"type":"string","enum":["inbound","outbound"],"title":"CallType"},"CambTTSConfiguration":{"properties":{"provider":{"type":"string","const":"camb","title":"Provider","default":"camb"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Camb.ai TTS model.","default":"mars-flash","examples":["mars-flash","mars-pro","mars-instruct"]},"voice":{"type":"string","title":"Voice","description":"Camb.ai voice ID.","default":"147320"},"language":{"type":"string","title":"Language","description":"BCP-47 language code.","default":"en-us"}},"type":"object","required":["api_key"],"title":"Camb.ai"},"CampaignDefaultsResponse":{"properties":{"concurrent_call_limit":{"type":"integer","title":"Concurrent Call Limit"},"from_numbers_count":{"type":"integer","title":"From Numbers Count"},"default_retry_config":{"$ref":"#/components/schemas/RetryConfigResponse"},"last_campaign_settings":{"anyOf":[{"$ref":"#/components/schemas/LastCampaignSettingsResponse"},{"type":"null"}]}},"type":"object","required":["concurrent_call_limit","from_numbers_count","default_retry_config"],"title":"CampaignDefaultsResponse"},"CampaignLogEntryResponse":{"properties":{"ts":{"type":"string","title":"Ts"},"level":{"type":"string","title":"Level"},"event":{"type":"string","title":"Event"},"message":{"type":"string","title":"Message"},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details"}},"type":"object","required":["ts","level","event","message"],"title":"CampaignLogEntryResponse","description":"A single timestamped entry from the campaign's append-only log.\n\nSurfaced in the UI so operators can see why a campaign moved to\npaused / failed without digging through server logs."},"CampaignProgressResponse":{"properties":{"campaign_id":{"type":"integer","title":"Campaign Id"},"state":{"type":"string","title":"State"},"total_rows":{"type":"integer","title":"Total Rows"},"processed_rows":{"type":"integer","title":"Processed Rows"},"failed_calls":{"type":"integer","title":"Failed Calls"},"progress_percentage":{"type":"number","title":"Progress Percentage"},"source_sync":{"additionalProperties":true,"type":"object","title":"Source Sync"},"rate_limit":{"type":"integer","title":"Rate Limit"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["campaign_id","state","total_rows","processed_rows","failed_calls","progress_percentage","source_sync","rate_limit","started_at","completed_at"],"title":"CampaignProgressResponse"},"CampaignResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"workflow_id":{"type":"integer","title":"Workflow Id"},"workflow_name":{"type":"string","title":"Workflow Name"},"state":{"type":"string","title":"State"},"source_type":{"type":"string","title":"Source Type"},"source_id":{"type":"string","title":"Source Id"},"total_rows":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Rows"},"processed_rows":{"type":"integer","title":"Processed Rows"},"failed_rows":{"type":"integer","title":"Failed Rows"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"retry_config":{"$ref":"#/components/schemas/RetryConfigResponse"},"max_concurrency":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Concurrency"},"schedule_config":{"anyOf":[{"$ref":"#/components/schemas/ScheduleConfigResponse"},{"type":"null"}]},"circuit_breaker":{"anyOf":[{"$ref":"#/components/schemas/CircuitBreakerConfigResponse"},{"type":"null"}]},"executed_count":{"type":"integer","title":"Executed Count","default":0},"total_queued_count":{"type":"integer","title":"Total Queued Count","default":0},"parent_campaign_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Parent Campaign Id"},"redialed_campaign_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Redialed Campaign Id"},"telephony_configuration_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Telephony Configuration Id"},"telephony_configuration_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Telephony Configuration Name"},"logs":{"items":{"$ref":"#/components/schemas/CampaignLogEntryResponse"},"type":"array","title":"Logs"}},"type":"object","required":["id","name","workflow_id","workflow_name","state","source_type","source_id","total_rows","processed_rows","failed_rows","created_at","started_at","completed_at","retry_config"],"title":"CampaignResponse"},"CampaignRunsResponse":{"properties":{"runs":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Runs"},"total_count":{"type":"integer","title":"Total Count"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["runs","total_count","page","limit","total_pages"],"title":"CampaignRunsResponse","description":"Paginated response for campaign workflow runs"},"CampaignSourceDownloadResponse":{"properties":{"download_url":{"type":"string","title":"Download Url"},"expires_in":{"type":"integer","title":"Expires In"}},"type":"object","required":["download_url","expires_in"],"title":"CampaignSourceDownloadResponse"},"CampaignsResponse":{"properties":{"campaigns":{"items":{"$ref":"#/components/schemas/CampaignResponse"},"type":"array","title":"Campaigns"}},"type":"object","required":["campaigns"],"title":"CampaignsResponse"},"CartesiaSTTConfiguration":{"properties":{"provider":{"type":"string","const":"cartesia","title":"Provider","default":"cartesia"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Cartesia STT model.","default":"ink-whisper","examples":["ink-whisper"]}},"type":"object","required":["api_key"],"title":"Cartesia"},"CartesiaTTSConfiguration":{"properties":{"provider":{"type":"string","const":"cartesia","title":"Provider","default":"cartesia"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Cartesia TTS model.","default":"sonic-3.5","examples":["sonic-3.5","sonic-3"]},"voice":{"type":"string","title":"Voice","description":"Cartesia voice UUID from your Cartesia dashboard.","default":"3faa81ae-d3d8-4ab1-9e44-e50e46d33c30"},"speed":{"type":"number","maximum":1.5,"minimum":0.6,"title":"Speed","description":"Speed of the voice.","default":1.0},"volume":{"type":"number","maximum":2.0,"minimum":0.5,"title":"Volume","description":"Volume multiplier for generated speech.","default":1.0}},"type":"object","required":["api_key"],"title":"Cartesia"},"ChunkResponseSchema":{"properties":{"id":{"type":"integer","title":"Id"},"document_id":{"type":"integer","title":"Document Id"},"chunk_text":{"type":"string","title":"Chunk Text"},"contextualized_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contextualized Text"},"chunk_index":{"type":"integer","title":"Chunk Index"},"chunk_metadata":{"additionalProperties":true,"type":"object","title":"Chunk Metadata"},"filename":{"type":"string","title":"Filename"},"document_uuid":{"type":"string","title":"Document Uuid"},"similarity":{"type":"number","title":"Similarity"}},"type":"object","required":["id","document_id","chunk_text","contextualized_text","chunk_index","chunk_metadata","filename","document_uuid","similarity"],"title":"ChunkResponseSchema","description":"Response schema for a document chunk."},"ChunkSearchRequestSchema":{"properties":{"query":{"type":"string","title":"Query","description":"Search query text"},"limit":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Limit","description":"Maximum number of results","default":5},"document_uuids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Document Uuids","description":"Filter by specific document UUIDs"},"min_similarity":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Min Similarity","description":"Minimum similarity threshold"}},"type":"object","required":["query"],"title":"ChunkSearchRequestSchema","description":"Request schema for searching similar chunks."},"ChunkSearchResponseSchema":{"properties":{"chunks":{"items":{"$ref":"#/components/schemas/ChunkResponseSchema"},"type":"array","title":"Chunks"},"query":{"type":"string","title":"Query"},"total_results":{"type":"integer","title":"Total Results"}},"type":"object","required":["chunks","query","total_results"],"title":"ChunkSearchResponseSchema","description":"Response schema for chunk search results."},"CircuitBreakerConfigRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"failure_threshold":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Failure Threshold","default":0.5},"window_seconds":{"type":"integer","maximum":600.0,"minimum":30.0,"title":"Window Seconds","default":120},"min_calls_in_window":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Min Calls In Window","default":5}},"type":"object","title":"CircuitBreakerConfigRequest"},"CircuitBreakerConfigResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":false},"failure_threshold":{"type":"number","title":"Failure Threshold","default":0.5},"window_seconds":{"type":"integer","title":"Window Seconds","default":120},"min_calls_in_window":{"type":"integer","title":"Min Calls In Window","default":5}},"type":"object","title":"CircuitBreakerConfigResponse"},"CloudonixConfigurationRequest":{"properties":{"provider":{"type":"string","const":"cloudonix","title":"Provider","default":"cloudonix"},"bearer_token":{"type":"string","title":"Bearer Token","description":"Cloudonix API Bearer Token"},"domain_id":{"type":"string","title":"Domain Id","description":"Cloudonix Domain ID"},"application_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Name","description":"Cloudonix Voice Application name. The application's url is updated when inbound workflows are attached to numbers on this domain. If omitted, an application is auto-created on save and its name is stored on the configuration."},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of Cloudonix phone numbers (optional)"}},"type":"object","required":["bearer_token","domain_id"],"title":"CloudonixConfigurationRequest","description":"Request schema for Cloudonix configuration."},"CloudonixConfigurationResponse":{"properties":{"provider":{"type":"string","const":"cloudonix","title":"Provider","default":"cloudonix"},"bearer_token":{"type":"string","title":"Bearer Token"},"domain_id":{"type":"string","title":"Domain Id"},"application_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Name"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["bearer_token","domain_id","from_numbers"],"title":"CloudonixConfigurationResponse","description":"Response schema for Cloudonix configuration with masked sensitive fields."},"CreateAPIKeyRequest":{"properties":{"name":{"type":"string","title":"Name"}},"type":"object","required":["name"],"title":"CreateAPIKeyRequest"},"CreateAPIKeyResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"key_prefix":{"type":"string","title":"Key Prefix"},"api_key":{"type":"string","title":"Api Key"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","key_prefix","api_key","created_at"],"title":"CreateAPIKeyResponse"},"CreateCampaignRequest":{"properties":{"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name"},"workflow_id":{"type":"integer","title":"Workflow Id"},"source_type":{"type":"string","pattern":"^csv$","title":"Source Type"},"source_id":{"type":"string","title":"Source Id"},"telephony_configuration_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Telephony Configuration Id"},"retry_config":{"anyOf":[{"$ref":"#/components/schemas/RetryConfigRequest"},{"type":"null"}]},"max_concurrency":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":1.0},{"type":"null"}],"title":"Max Concurrency"},"schedule_config":{"anyOf":[{"$ref":"#/components/schemas/ScheduleConfigRequest"},{"type":"null"}]},"circuit_breaker":{"anyOf":[{"$ref":"#/components/schemas/CircuitBreakerConfigRequest"},{"type":"null"}]}},"type":"object","required":["name","workflow_id","source_type","source_id"],"title":"CreateCampaignRequest"},"CreateCredentialRequest":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"credential_type":{"$ref":"#/components/schemas/WebhookCredentialType"},"credential_data":{"additionalProperties":true,"type":"object","title":"Credential Data"}},"type":"object","required":["name","credential_type","credential_data"],"title":"CreateCredentialRequest","description":"Request schema for creating a webhook credential."},"CreateFolderRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"}},"type":"object","required":["name"],"title":"CreateFolderRequest"},"CreateServiceKeyRequest":{"properties":{"name":{"type":"string","title":"Name"},"expires_in_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires In Days","default":90}},"type":"object","required":["name"],"title":"CreateServiceKeyRequest"},"CreateServiceKeyResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"service_key":{"type":"string","title":"Service Key"},"key_prefix":{"type":"string","title":"Key Prefix"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["id","name","service_key","key_prefix"],"title":"CreateServiceKeyResponse"},"CreateTextChatSessionRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"},"annotations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Annotations"}},"type":"object","title":"CreateTextChatSessionRequest"},"CreateToolRequest":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name","description":"Display name for the tool.","llm_hint":"Use a concise action-oriented name; this influences the function name shown to the agent."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Description shown to the agent when deciding whether to call it.","llm_hint":"State exactly when the agent should call the tool and what result it gets."},"category":{"type":"string","enum":["http_api","end_call","transfer_call","calculator","native","integration","mcp"],"title":"Category","description":"Tool category. Must match definition.type.","default":"http_api"},"icon":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Icon","description":"Lucide icon identifier.","default":"globe"},"icon_color":{"anyOf":[{"type":"string","maxLength":7},{"type":"null"}],"title":"Icon Color","description":"Hex color for the tool icon.","default":"#3B82F6"},"definition":{"oneOf":[{"$ref":"#/components/schemas/HttpApiToolDefinition"},{"$ref":"#/components/schemas/EndCallToolDefinition"},{"$ref":"#/components/schemas/TransferCallToolDefinition"},{"$ref":"#/components/schemas/CalculatorToolDefinition"},{"$ref":"#/components/schemas/McpToolDefinition"}],"title":"Definition","description":"Typed tool definition.","discriminator":{"propertyName":"type","mapping":{"calculator":"#/components/schemas/CalculatorToolDefinition","end_call":"#/components/schemas/EndCallToolDefinition","http_api":"#/components/schemas/HttpApiToolDefinition","mcp":"#/components/schemas/McpToolDefinition","transfer_call":"#/components/schemas/TransferCallToolDefinition"}}}},"type":"object","required":["name","definition"],"title":"CreateToolRequest","description":"Request schema for creating a reusable tool."},"CreateWorkflowRequest":{"properties":{"name":{"type":"string","title":"Name"},"workflow_definition":{"additionalProperties":true,"type":"object","title":"Workflow Definition"}},"type":"object","required":["name","workflow_definition"],"title":"CreateWorkflowRequest"},"CreateWorkflowRunRequest":{"properties":{"mode":{"type":"string","title":"Mode"},"name":{"type":"string","title":"Name"}},"type":"object","required":["mode","name"],"title":"CreateWorkflowRunRequest"},"CreateWorkflowRunResponse":{"properties":{"id":{"type":"integer","title":"Id"},"workflow_id":{"type":"integer","title":"Workflow Id"},"name":{"type":"string","title":"Name"},"mode":{"type":"string","title":"Mode"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"definition_id":{"type":"integer","title":"Definition Id"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"}},"type":"object","required":["id","workflow_id","name","mode","created_at","definition_id"],"title":"CreateWorkflowRunResponse"},"CreateWorkflowTemplateRequest":{"properties":{"call_type":{"type":"string","enum":["inbound","outbound"],"title":"Call Type"},"use_case":{"type":"string","title":"Use Case"},"activity_description":{"type":"string","title":"Activity Description"}},"type":"object","required":["call_type","use_case","activity_description"],"title":"CreateWorkflowTemplateRequest"},"CreatedByResponse":{"properties":{"id":{"type":"integer","title":"Id"},"provider_id":{"type":"string","title":"Provider Id"}},"type":"object","required":["id","provider_id"],"title":"CreatedByResponse","description":"Response schema for the user who created a tool."},"CredentialResponse":{"properties":{"uuid":{"type":"string","title":"Uuid"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"credential_type":{"type":"string","title":"Credential Type"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["uuid","name","description","credential_type","created_at","updated_at"],"title":"CredentialResponse","description":"Response schema for a webhook credential (never includes sensitive data)."},"CurrentUsageResponse":{"properties":{"period_start":{"type":"string","title":"Period Start"},"period_end":{"type":"string","title":"Period End"},"used_dograh_tokens":{"type":"number","title":"Used Dograh Tokens"},"total_duration_seconds":{"type":"integer","title":"Total Duration Seconds"},"used_amount_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Used Amount Usd"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"price_per_second_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Price Per Second Usd"}},"type":"object","required":["period_start","period_end","used_dograh_tokens","total_duration_seconds"],"title":"CurrentUsageResponse"},"DailyReportResponse":{"properties":{"date":{"type":"string","title":"Date"},"timezone":{"type":"string","title":"Timezone"},"workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Workflow Id"},"metrics":{"additionalProperties":{"type":"integer"},"type":"object","title":"Metrics"},"disposition_distribution":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Disposition Distribution"},"call_duration_distribution":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Call Duration Distribution"}},"type":"object","required":["date","timezone","workflow_id","metrics","disposition_distribution","call_duration_distribution"],"title":"DailyReportResponse"},"DailyUsageBreakdownResponse":{"properties":{"breakdown":{"items":{"$ref":"#/components/schemas/DailyUsageItem"},"type":"array","title":"Breakdown"},"total_minutes":{"type":"number","title":"Total Minutes"},"total_cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Cost Usd"},"total_dograh_tokens":{"type":"number","title":"Total Dograh Tokens"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"}},"type":"object","required":["breakdown","total_minutes","total_dograh_tokens"],"title":"DailyUsageBreakdownResponse"},"DailyUsageItem":{"properties":{"date":{"type":"string","title":"Date"},"minutes":{"type":"number","title":"Minutes"},"cost_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cost Usd"},"dograh_tokens":{"type":"number","title":"Dograh Tokens"},"call_count":{"type":"integer","title":"Call Count"}},"type":"object","required":["date","minutes","dograh_tokens","call_count"],"title":"DailyUsageItem"},"DeepgramSTTConfiguration":{"properties":{"provider":{"type":"string","const":"deepgram","title":"Provider","default":"deepgram"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Deepgram STT model.","default":"nova-3-general","examples":["nova-3-general","flux-general-en","flux-general-multi"]},"language":{"type":"string","title":"Language","description":"Language code; 'multi' enables auto-detect (Nova-3 only).","default":"multi","examples":["multi","ar","ar-AE","ar-SA","ar-QA","ar-KW","ar-SY","ar-LB","ar-PS","ar-JO","ar-EG","ar-SD","ar-TD","ar-MA","ar-DZ","ar-TN","ar-IQ","ar-IR","be","bn","bs","bg","ca","cs","da","da-DK","de","de-CH","el","en","en-US","en-AU","en-GB","en-IN","en-NZ","es","es-419","et","fa","fi","fr","fr-CA","he","hi","hr","hu","id","it","ja","kn","ko","ko-KR","lt","lv","mk","mr","ms","nl","nl-BE","no","pl","pt","pt-BR","pt-PT","ro","ru","sk","sl","sr","sv","sv-SE","ta","te","th","tl","tr","uk","ur","vi","zh-CN","zh-TW"],"model_options":{"flux-general-en":["en"],"nova-3-general":["multi","ar","ar-AE","ar-SA","ar-QA","ar-KW","ar-SY","ar-LB","ar-PS","ar-JO","ar-EG","ar-SD","ar-TD","ar-MA","ar-DZ","ar-TN","ar-IQ","ar-IR","be","bn","bs","bg","ca","cs","da","da-DK","de","de-CH","el","en","en-US","en-AU","en-GB","en-IN","en-NZ","es","es-419","et","fa","fi","fr","fr-CA","he","hi","hr","hu","id","it","ja","kn","ko","ko-KR","lt","lv","mk","mr","ms","nl","nl-BE","no","pl","pt","pt-BR","pt-PT","ro","ru","sk","sl","sr","sv","sv-SE","ta","te","th","tl","tr","uk","ur","vi","zh-CN","zh-TW"]}}},"type":"object","required":["api_key"],"title":"Deepgram"},"DeepgramTTSConfiguration":{"properties":{"provider":{"type":"string","const":"deepgram","title":"Provider","default":"deepgram"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"voice":{"type":"string","title":"Voice","description":"Deepgram voice ID (model is inferred from the 'aura-N' prefix).","default":"aura-2-helena-en"}},"type":"object","required":["api_key"],"title":"Deepgram"},"DefaultConfigurationsResponse":{"properties":{"llm":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Llm"},"tts":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Tts"},"stt":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Stt"},"embeddings":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Embeddings"},"realtime":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Realtime"},"default_providers":{"additionalProperties":{"type":"string"},"type":"object","title":"Default Providers"}},"type":"object","required":["llm","tts","stt","embeddings","realtime","default_providers"],"title":"DefaultConfigurationsResponse"},"DisplayOptions":{"properties":{"show":{"anyOf":[{"additionalProperties":{"items":{},"type":"array"},"type":"object"},{"type":"null"}],"title":"Show"},"hide":{"anyOf":[{"additionalProperties":{"items":{},"type":"array"},"type":"object"},{"type":"null"}],"title":"Hide"}},"additionalProperties":false,"type":"object","title":"DisplayOptions","description":"Conditional visibility rules.\n\n`show` keys are AND-combined: this property is visible only when EVERY\nreferenced field's value matches one of the listed values.\n\n`hide` keys are OR-combined: this property is hidden when ANY referenced\nfield's value matches one of the listed values.\n\nExample:\n DisplayOptions(show={\"extraction_enabled\": [True]})\n DisplayOptions(show={\"greeting_type\": [\"audio\"]})"},"DocumentListResponseSchema":{"properties":{"documents":{"items":{"$ref":"#/components/schemas/DocumentResponseSchema"},"type":"array","title":"Documents"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["documents","total","limit","offset"],"title":"DocumentListResponseSchema","description":"Response schema for list of documents."},"DocumentResponseSchema":{"properties":{"id":{"type":"integer","title":"Id"},"document_uuid":{"type":"string","title":"Document Uuid"},"filename":{"type":"string","title":"Filename"},"file_size_bytes":{"type":"integer","title":"File Size Bytes"},"file_hash":{"type":"string","title":"File Hash"},"mime_type":{"type":"string","title":"Mime Type"},"processing_status":{"type":"string","title":"Processing Status"},"processing_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Processing Error"},"total_chunks":{"type":"integer","title":"Total Chunks"},"retrieval_mode":{"type":"string","title":"Retrieval Mode","default":"chunked"},"custom_metadata":{"additionalProperties":true,"type":"object","title":"Custom Metadata"},"docling_metadata":{"additionalProperties":true,"type":"object","title":"Docling Metadata"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"organization_id":{"type":"integer","title":"Organization Id"},"created_by":{"type":"integer","title":"Created By"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","document_uuid","filename","file_size_bytes","file_hash","mime_type","processing_status","total_chunks","custom_metadata","docling_metadata","created_at","updated_at","organization_id","created_by","is_active"],"title":"DocumentResponseSchema","description":"Response schema for document metadata."},"DocumentUploadRequestSchema":{"properties":{"filename":{"type":"string","title":"Filename","description":"Name of the file to upload"},"mime_type":{"type":"string","title":"Mime Type","description":"MIME type of the file"},"custom_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Custom Metadata","description":"Optional custom metadata"}},"type":"object","required":["filename","mime_type"],"title":"DocumentUploadRequestSchema","description":"Request schema for initiating document upload."},"DocumentUploadResponseSchema":{"properties":{"upload_url":{"type":"string","title":"Upload Url","description":"Signed URL for uploading the file"},"document_uuid":{"type":"string","title":"Document Uuid","description":"Unique identifier for the document"},"s3_key":{"type":"string","title":"S3 Key","description":"S3 key where file should be uploaded"}},"type":"object","required":["upload_url","document_uuid","s3_key"],"title":"DocumentUploadResponseSchema","description":"Response schema containing upload URL and document metadata."},"DograhEmbeddingsConfiguration":{"properties":{"provider":{"type":"string","const":"dograh","title":"Provider","default":"dograh"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Dograh-managed embedding model.","default":"default","examples":["default"]}},"type":"object","required":["api_key"],"title":"Dograh"},"DograhLLMService":{"properties":{"provider":{"type":"string","const":"dograh","title":"Provider","default":"dograh"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Dograh-hosted model tier.","default":"default","examples":["default","accurate","fast","lite","zen"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Dograh"},"DograhManagedAIModelConfiguration":{"properties":{"api_key":{"type":"string","title":"Api Key"},"voice":{"type":"string","title":"Voice","default":"default"},"speed":{"type":"number","title":"Speed","default":1.0},"language":{"type":"string","title":"Language","default":"multi"}},"type":"object","required":["api_key"],"title":"DograhManagedAIModelConfiguration"},"DograhSTTService":{"properties":{"provider":{"type":"string","const":"dograh","title":"Provider","default":"dograh"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Dograh STT tier.","default":"default","examples":["default"]},"language":{"type":"string","title":"Language","description":"Language code; use 'multi' for auto-detect.","default":"multi","examples":["multi","ar","ar-AE","ar-SA","ar-QA","ar-KW","ar-SY","ar-LB","ar-PS","ar-JO","ar-EG","ar-SD","ar-TD","ar-MA","ar-DZ","ar-TN","ar-IQ","ar-IR","be","bn","bs","bg","ca","cs","da","da-DK","de","de-CH","el","en","en-US","en-AU","en-GB","en-IN","en-NZ","es","es-419","et","fa","fi","fr","fr-CA","he","hi","hr","hu","id","it","ja","kn","ko","ko-KR","lt","lv","mk","mr","ms","nl","nl-BE","no","pl","pt","pt-BR","pt-PT","ro","ru","sk","sl","sr","sv","sv-SE","ta","te","th","tl","tr","uk","ur","vi","zh-CN","zh-TW"]}},"type":"object","required":["api_key"],"title":"Dograh"},"DograhTTSService":{"properties":{"provider":{"type":"string","const":"dograh","title":"Provider","default":"dograh"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Dograh TTS tier.","default":"default","examples":["default"]},"voice":{"type":"string","title":"Voice","description":"Voice preset.","default":"default","allow_custom_input":true},"speed":{"type":"number","maximum":2.0,"minimum":0.5,"title":"Speed","description":"Speed of the voice.","default":1.0}},"type":"object","required":["api_key"],"title":"Dograh"},"DuplicateTemplateRequest":{"properties":{"template_id":{"type":"integer","title":"Template Id"},"workflow_name":{"type":"string","title":"Workflow Name"}},"type":"object","required":["template_id","workflow_name"],"title":"DuplicateTemplateRequest"},"ElevenlabsTTSConfiguration":{"properties":{"provider":{"type":"string","const":"elevenlabs","title":"Provider","default":"elevenlabs"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"voice":{"type":"string","title":"Voice","description":"ElevenLabs voice ID from your Voice Library.","default":"21m00Tcm4TlvDq8ikWAM"},"speed":{"type":"number","maximum":2.0,"minimum":0.1,"title":"Speed","description":"Speed of the voice.","default":1.0},"model":{"type":"string","title":"Model","description":"ElevenLabs TTS model.","default":"eleven_flash_v2_5","examples":["eleven_flash_v2_5"]},"base_url":{"type":"string","title":"Base Url","description":"ElevenLabs API base URL. Override to use a Data Residency endpoint (e.g. https://api.eu.residency.elevenlabs.io) for GDPR / HIPAA / regional compliance.","default":"https://api.elevenlabs.io"}},"type":"object","required":["api_key"],"title":"ElevenLabs"},"EmbedConfigResponse":{"properties":{"workflow_id":{"type":"integer","title":"Workflow Id"},"settings":{"additionalProperties":true,"type":"object","title":"Settings"},"theme":{"type":"string","title":"Theme"},"position":{"type":"string","title":"Position"},"button_text":{"type":"string","title":"Button Text"},"button_color":{"type":"string","title":"Button Color"},"size":{"type":"string","title":"Size"},"auto_start":{"type":"boolean","title":"Auto Start"}},"type":"object","required":["workflow_id","settings","theme","position","button_text","button_color","size","auto_start"],"title":"EmbedConfigResponse","description":"Response model for embed configuration"},"EmbedTokenRequest":{"properties":{"allowed_domains":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Domains"},"settings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Settings"},"usage_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Usage Limit"},"expires_in_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires In Days","default":30}},"type":"object","title":"EmbedTokenRequest"},"EmbedTokenResponse":{"properties":{"id":{"type":"integer","title":"Id"},"token":{"type":"string","title":"Token"},"allowed_domains":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Domains"},"settings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Settings"},"is_active":{"type":"boolean","title":"Is Active"},"usage_count":{"type":"integer","title":"Usage Count"},"usage_limit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Usage Limit"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"embed_script":{"type":"string","title":"Embed Script"}},"type":"object","required":["id","token","allowed_domains","settings","is_active","usage_count","usage_limit","expires_at","created_at","embed_script"],"title":"EmbedTokenResponse"},"EndCallConfig":{"properties":{"messageType":{"type":"string","enum":["none","custom","audio"],"title":"Messagetype","description":"Type of goodbye message.","default":"none"},"customMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custommessage","description":"Custom message to play before ending the call."},"audioRecordingId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Audiorecordingid","description":"Recording ID for audio goodbye message."},"endCallReason":{"type":"boolean","title":"Endcallreason","description":"When enabled, the model must provide a reason for ending the call. The reason is set as call disposition and added to call tags.","default":false},"endCallReasonDescription":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endcallreasondescription","description":"Description shown to the model for the reason parameter. Used only when endCallReason is enabled."}},"type":"object","title":"EndCallConfig","description":"Configuration for End Call tools."},"EndCallToolDefinition":{"properties":{"schema_version":{"type":"integer","title":"Schema Version","description":"Schema version.","default":1},"type":{"type":"string","const":"end_call","title":"Type","description":"Tool type."},"config":{"$ref":"#/components/schemas/EndCallConfig","description":"End Call configuration."}},"type":"object","required":["type","config"],"title":"EndCallToolDefinition","description":"Tool definition for End Call tools."},"FileDescriptor":{"properties":{"filename":{"type":"string","title":"Filename","description":"Original filename of the audio file"},"mime_type":{"type":"string","title":"Mime Type","description":"MIME type of the audio file","default":"audio/wav"},"file_size":{"type":"integer","maximum":5242880.0,"exclusiveMinimum":0.0,"title":"File Size","description":"File size in bytes (max 5MB)"}},"type":"object","required":["filename","file_size"],"title":"FileDescriptor","description":"Descriptor for a single file in a batch upload request."},"FileMetadataResponse":{"properties":{"key":{"type":"string","title":"Key"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","required":["key","metadata"],"title":"FileMetadataResponse"},"FolderResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","created_at"],"title":"FolderResponse"},"GladiaSTTConfiguration":{"properties":{"provider":{"type":"string","const":"gladia","title":"Provider","default":"gladia"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Gladia STT model.","default":"solaria-1","examples":["solaria-1"]},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code.","default":"en","examples":["af","am","ar","as","az","ba","be","bg","bn","bo","br","bs","ca","cs","cy","da","de","el","en","es","et","eu","fa","fi","fo","fr","gl","gu","ha","haw","he","hi","hr","ht","hu","hy","id","is","it","ja","jw","ka","kk","km","kn","ko","la","lb","ln","lo","lt","lv","mg","mi","mk","ml","mn","mr","ms","mt","my","ne","nl","nn","no","oc","pa","pl","ps","pt","ro","ru","sa","sd","si","sk","sl","sn","so","sq","sr","su","sv","sw","ta","te","tg","th","tk","tl","tr","tt","uk","ur","uz","vi","wo","yi","yo","zh"]}},"type":"object","required":["api_key"],"title":"Gladia"},"GoogleLLMService":{"properties":{"provider":{"type":"string","const":"google","title":"Provider","default":"google"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Gemini model on Google AI Studio (not Vertex).","default":"gemini-2.0-flash","examples":["gemini-2.0-flash","gemini-2.0-flash-lite","gemini-2.5-flash","gemini-2.5-flash-lite","gemini-3.5-flash","gemini-3.5-flash-lite"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Google"},"GoogleRealtimeLLMConfiguration":{"properties":{"provider":{"type":"string","const":"google_realtime","title":"Provider","default":"google_realtime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Gemini Live model on Google AI Studio (not Vertex).","default":"gemini-3.1-flash-live-preview","examples":["gemini-3.1-flash-live-preview"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Voice the model speaks in.","default":"Puck","examples":["Puck","Charon","Kore","Fenrir","Aoede"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code.","default":"en","examples":["ar","bn","de","en","es","fr","gu","hi","id","it","ja","kn","ko","ml","mr","nl","pl","pt","ru","ta","te","th","tr","vi","zh"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Google Realtime"},"GoogleSTTConfiguration":{"properties":{"provider":{"type":"string","const":"google","title":"Provider","default":"google"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Not used for Google Cloud STT. Leave blank."},"model":{"type":"string","title":"Model","description":"Google Cloud Speech-to-Text V2 recognition model.","default":"latest_long","examples":["latest_long","latest_short","chirp_3"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"Primary BCP-47 language code for recognition.","default":"en-US","examples":["af-ZA","am-ET","ar-AE","ar-BH","ar-DZ","ar-EG","ar-IL","ar-IQ","ar-JO","ar-KW","ar-LB","ar-MA","ar-MR","ar-OM","ar-PS","ar-QA","ar-SA","ar-SY","ar-TN","ar-XA","ar-YE","as-IN","ast-ES","az-AZ","be-BY","bg-BG","bn-BD","bn-IN","bs-BA","ca-ES","ceb-PH","ckb-IQ","cmn-Hans-CN","cmn-Hant-TW","cs-CZ","cy-GB","da-DK","de-AT","de-CH","de-DE","el-GR","en-AU","en-GB","en-HK","en-IE","en-IN","en-NZ","en-PH","en-PK","en-SG","en-US","es-419","es-AR","es-BO","es-CL","es-CO","es-CR","es-DO","es-EC","es-ES","es-GT","es-HN","es-MX","es-NI","es-PA","es-PE","es-PR","es-SV","es-US","es-UY","es-VE","et-EE","eu-ES","fa-IR","ff-SN","fi-FI","fil-PH","fr-BE","fr-CA","fr-CH","fr-FR","ga-IE","gl-ES","gu-IN","ha-NG","hi-IN","hr-HR","hu-HU","hy-AM","id-ID","ig-NG","is-IS","it-CH","it-IT","iw-IL","ja-JP","jv-ID","ka-GE","kam-KE","kea-CV","kk-KZ","km-KH","kn-IN","ko-KR","ky-KG","lb-LU","lg-UG","ln-CD","lo-LA","lt-LT","luo-KE","lv-LV","mi-NZ","mk-MK","ml-IN","mn-MN","mr-IN","ms-MY","mt-MT","my-MM","ne-NP","nl-BE","nl-NL","no-NO","nso-ZA","ny-MW","oc-FR","om-ET","or-IN","pa-Guru-IN","pl-PL","ps-AF","pt-BR","pt-PT","ro-RO","ru-RU","rup-BG","rw-RW","sd-IN","si-LK","sk-SK","sl-SI","sn-ZW","so-SO","sq-AL","sr-RS","ss-Latn-ZA","st-ZA","su-ID","sv-SE","sw","sw-KE","ta-IN","te-IN","tg-TJ","th-TH","tn-Latn-ZA","tr-TR","ts-ZA","uk-UA","umb-AO","ur-PK","uz-UZ","ve-ZA","vi-VN","wo-SN","xh-ZA","yo-NG","yue-Hant-HK","zu-ZA"],"allow_custom_input":true,"docs_url":"https://docs.cloud.google.com/speech-to-text/docs/speech-to-text-supported-languages"},"location":{"type":"string","title":"Location","description":"Google Cloud Speech-to-Text region (for example 'global' or 'us-central1').","default":"global"},"credentials":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credentials","description":"Paste the entire Google Cloud service-account JSON. If omitted, the server falls back to Application Default Credentials (ADC).","multiline":true}},"type":"object","title":"Google Cloud"},"GoogleTTSConfiguration":{"properties":{"provider":{"type":"string","const":"google","title":"Provider","default":"google"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Not used for Google Cloud TTS. Leave blank."},"model":{"type":"string","title":"Model","description":"Google Cloud low-latency TTS engine. Dograh maps this to Pipecat's streaming Google TTS service for Chirp 3 HD and Journey voices.","default":"chirp_3_hd","examples":["chirp_3_hd"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Google Cloud voice name. Use a Chirp 3 HD or Journey voice for streaming TTS.","default":"en-US-Chirp3-HD-Charon","examples":["en-US-Chirp3-HD-Charon"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"BCP-47 language code for synthesis.","default":"en-US","examples":["ar-XA","bn-IN","bg-BG","yue-HK","hr-HR","cs-CZ","da-DK","nl-BE","nl-NL","en-AU","en-IN","en-GB","en-US","et-EE","fi-FI","fr-CA","fr-FR","de-DE","el-GR","gu-IN","he-IL","hi-IN","hu-HU","id-ID","it-IT","ja-JP","kn-IN","ko-KR","lv-LV","lt-LT","ml-IN","cmn-CN","mr-IN","nb-NO","pl-PL","pt-BR","pa-IN","ro-RO","ru-RU","sr-RS","sk-SK","sl-SI","es-ES","es-US","sw-KE","sv-SE","ta-IN","te-IN","th-TH","tr-TR","uk-UA","ur-IN","vi-VN"],"allow_custom_input":true},"speed":{"type":"number","maximum":2.0,"minimum":0.25,"title":"Speed","description":"Speech speed multiplier for Google streaming TTS.","default":1.0},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location","description":"Optional Google Cloud regional Text-to-Speech endpoint (for example 'us-central1'). Leave blank to use the default endpoint."},"credentials":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credentials","description":"Paste the entire Google Cloud service-account JSON. If omitted, the server falls back to Application Default Credentials (ADC).","multiline":true}},"type":"object","title":"Google Cloud"},"GoogleVertexLLMConfiguration":{"properties":{"provider":{"type":"string","const":"google_vertex","title":"Provider","default":"google_vertex"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Not used for Vertex AI \u2014 authentication is via the service account in `credentials` (or ADC). Leave blank."},"model":{"type":"string","title":"Model","description":"Gemini model on Vertex AI.","default":"gemini-2.5-flash","examples":["gemini-2.5-flash","gemini-2.5-flash-lite","gemini-3.1-flash-lite","gemini-3.5-flash"],"allow_custom_input":true},"project_id":{"type":"string","title":"Project Id","description":"Google Cloud project ID for Vertex AI."},"location":{"type":"string","title":"Location","description":"GCP region for the Vertex AI endpoint (e.g. 'global').","default":"global"},"credentials":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credentials","description":"Paste the entire service-account JSON file contents. If omitted, falls back to Application Default Credentials (ADC).","multiline":true}},"type":"object","required":["project_id"],"title":"Google Vertex"},"GoogleVertexRealtimeLLMConfiguration":{"properties":{"provider":{"type":"string","const":"google_vertex_realtime","title":"Provider","default":"google_vertex_realtime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Not used for Vertex AI \u2014 authentication is via the service account in `credentials` (or ADC). Leave blank."},"model":{"type":"string","title":"Model","description":"Vertex AI publisher/model identifier.","default":"google/gemini-live-2.5-flash-native-audio","examples":["google/gemini-live-2.5-flash-native-audio"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Voice the model speaks in.","default":"Charon","examples":["Puck","Charon","Kore","Fenrir","Aoede"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"BCP-47 language code (e.g. 'en-US').","default":"en","examples":["ar","bn","de","en","es","fr","gu","hi","id","it","ja","kn","ko","ml","mr","nl","pl","pt","ru","ta","te","th","tr","vi","zh"],"allow_custom_input":true},"project_id":{"type":"string","title":"Project Id","description":"Google Cloud project ID for Vertex AI."},"location":{"type":"string","title":"Location","description":"GCP region for the Vertex AI endpoint (e.g. 'global').","default":"global"},"credentials":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credentials","description":"Paste the entire service-account JSON file contents. If omitted, falls back to Application Default Credentials (ADC).","multiline":true}},"type":"object","required":["project_id"],"title":"Google Vertex Realtime"},"GraphConstraints":{"properties":{"min_incoming":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Incoming"},"max_incoming":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Incoming"},"min_outgoing":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Outgoing"},"max_outgoing":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Outgoing"}},"additionalProperties":false,"type":"object","title":"GraphConstraints","description":"Per-node-type graph rules. WorkflowGraph enforces these at validation."},"GrokRealtimeLLMConfiguration":{"properties":{"provider":{"type":"string","const":"grok_realtime","title":"Provider","default":"grok_realtime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Grok realtime voice-agent model.","default":"grok-voice-think-fast-1.0","examples":["grok-voice-think-fast-1.0"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Voice the model speaks in.","default":"Ara","examples":["Ara","Rex","Sal","Eve","Leo"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Grok Realtime"},"GroqLLMService":{"properties":{"provider":{"type":"string","const":"groq","title":"Provider","default":"groq"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Groq-hosted model identifier.","default":"llama-3.3-70b-versatile","examples":["llama-3.3-70b-versatile","deepseek-r1-distill-llama-70b","qwen-qwq-32b","meta-llama/llama-4-scout-17b-16e-instruct","meta-llama/llama-4-maverick-17b-128e-instruct","gemma2-9b-it","llama-3.1-8b-instant","openai/gpt-oss-120b"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Groq"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status"},"version":{"type":"string","title":"Version"},"backend_api_endpoint":{"type":"string","title":"Backend Api Endpoint"},"deployment_mode":{"type":"string","title":"Deployment Mode"},"auth_provider":{"type":"string","title":"Auth Provider"},"turn_enabled":{"type":"boolean","title":"Turn Enabled"},"force_turn_relay":{"type":"boolean","title":"Force Turn Relay"}},"type":"object","required":["status","version","backend_api_endpoint","deployment_mode","auth_provider","turn_enabled","force_turn_relay"],"title":"HealthResponse"},"HttpApiConfig":{"properties":{"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"title":"Method","description":"HTTP method to use for the request.","llm_hint":"Use one of GET, POST, PUT, PATCH, DELETE."},"url":{"type":"string","title":"Url","description":"Target HTTP or HTTPS URL.","llm_hint":"Use the final endpoint URL. Authentication belongs in credential_uuid, not embedded in the URL."},"headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Headers","description":"Static headers to include with every request.","llm_hint":"Do not place secrets here. Store secrets in the UI credential manager and reference them with credential_uuid."},"credential_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credential Uuid","description":"Reference to an external credential for request authentication.","llm_hint":"Use a credential_uuid returned by list_credentials. The MCP flow does not create credential secrets."},"parameters":{"anyOf":[{"items":{"$ref":"#/components/schemas/ToolParameter"},"type":"array"},{"type":"null"}],"title":"Parameters","description":"Parameters the model must provide when calling this tool."},"preset_parameters":{"anyOf":[{"items":{"$ref":"#/components/schemas/PresetToolParameter"},"type":"array"},{"type":"null"}],"title":"Preset Parameters","description":"Parameters injected by Dograh from fixed values or workflow context templates."},"timeout_ms":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Timeout Ms","description":"Request timeout in milliseconds.","default":5000},"customMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custommessage","description":"Custom message to play after tool execution."},"customMessageType":{"anyOf":[{"type":"string","enum":["text","audio"]},{"type":"null"}],"title":"Custommessagetype","description":"Type of custom message."},"customMessageRecordingId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custommessagerecordingid","description":"Recording ID for an audio custom message."}},"type":"object","required":["method","url"],"title":"HttpApiConfig","description":"Configuration for HTTP API tools."},"HttpApiToolDefinition":{"properties":{"schema_version":{"type":"integer","title":"Schema Version","description":"Schema version.","default":1},"type":{"type":"string","const":"http_api","title":"Type","description":"Tool type."},"config":{"$ref":"#/components/schemas/HttpApiConfig","description":"HTTP API configuration."}},"type":"object","required":["type","config"],"title":"HttpApiToolDefinition","description":"Tool definition for HTTP API tools."},"HuggingFaceLLMConfiguration":{"properties":{"provider":{"type":"string","const":"huggingface","title":"Provider","default":"huggingface"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Hugging Face chat-completion model identifier, optionally with provider suffix.","default":"openai/gpt-oss-120b:cerebras","examples":["openai/gpt-oss-120b:cerebras","deepseek-ai/DeepSeek-R1:fastest","Qwen/Qwen3-Coder-480B-A35B-Instruct:fastest"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"Hugging Face OpenAI-compatible chat-completions router base URL.","default":"https://router.huggingface.co/v1"},"bill_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bill To","description":"Optional Hugging Face organization or user to bill using X-HF-Bill-To."}},"type":"object","required":["api_key"],"title":"Hugging Face","description":"Hosted Hugging Face Inference Providers API for usage-based inference.","provider_docs_url":"https://huggingface.co/docs/inference-providers/en/index"},"HuggingFaceSTTConfiguration":{"properties":{"provider":{"type":"string","const":"huggingface","title":"Provider","default":"huggingface"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Hugging Face ASR model identifier served through Inference Providers.","default":"openai/whisper-large-v3-turbo","examples":["openai/whisper-large-v3-turbo","openai/whisper-large-v3"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"Hugging Face Inference Providers router base URL.","default":"https://router.huggingface.co/hf-inference"},"bill_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bill To","description":"Optional Hugging Face organization or user to bill using X-HF-Bill-To."},"return_timestamps":{"type":"boolean","title":"Return Timestamps","description":"Request timestamp chunks when supported by the selected provider/model.","default":false}},"type":"object","required":["api_key"],"title":"Hugging Face","description":"Hosted Hugging Face Inference Providers API for usage-based inference.","provider_docs_url":"https://huggingface.co/docs/inference-providers/en/index"},"ImpersonateRequest":{"properties":{"provider_user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider User Id"},"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"}},"type":"object","title":"ImpersonateRequest","description":"Request payload for superadmin impersonation.\n\nEither ``provider_user_id`` **or** ``user_id`` must be supplied. If both are\nprovided, ``provider_user_id`` takes precedence."},"ImpersonateResponse":{"properties":{"refresh_token":{"type":"string","title":"Refresh Token"},"access_token":{"type":"string","title":"Access Token"}},"type":"object","required":["refresh_token","access_token"],"title":"ImpersonateResponse"},"InitEmbedRequest":{"properties":{"token":{"type":"string","title":"Token"},"context_variables":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Context Variables"}},"type":"object","required":["token"],"title":"InitEmbedRequest","description":"Request model for initializing an embed session"},"InitEmbedResponse":{"properties":{"session_token":{"type":"string","title":"Session Token"},"workflow_run_id":{"type":"integer","title":"Workflow Run Id"},"config":{"additionalProperties":true,"type":"object","title":"Config"}},"type":"object","required":["session_token","workflow_run_id","config"],"title":"InitEmbedResponse","description":"Response model for embed initialization"},"InitiateCallRequest":{"properties":{"workflow_id":{"type":"integer","title":"Workflow Id"},"workflow_run_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Workflow Run Id"},"phone_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone Number"},"telephony_configuration_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Telephony Configuration Id"},"from_phone_number_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"From Phone Number Id"}},"type":"object","required":["workflow_id"],"title":"InitiateCallRequest"},"ItemKind":{"type":"string","enum":["node","edge","workflow"],"title":"ItemKind"},"LangfuseCredentialsRequest":{"properties":{"host":{"type":"string","title":"Host"},"public_key":{"type":"string","title":"Public Key"},"secret_key":{"type":"string","title":"Secret Key"}},"type":"object","required":["host","public_key","secret_key"],"title":"LangfuseCredentialsRequest"},"LangfuseCredentialsResponse":{"properties":{"host":{"type":"string","title":"Host","default":""},"public_key":{"type":"string","title":"Public Key","default":""},"secret_key":{"type":"string","title":"Secret Key","default":""},"configured":{"type":"boolean","title":"Configured","default":false}},"type":"object","title":"LangfuseCredentialsResponse"},"LastCampaignSettingsResponse":{"properties":{"retry_config":{"anyOf":[{"$ref":"#/components/schemas/RetryConfigResponse"},{"type":"null"}]},"max_concurrency":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Concurrency"},"schedule_config":{"anyOf":[{"$ref":"#/components/schemas/ScheduleConfigResponse"},{"type":"null"}]},"circuit_breaker":{"anyOf":[{"$ref":"#/components/schemas/CircuitBreakerConfigResponse"},{"type":"null"}]}},"type":"object","title":"LastCampaignSettingsResponse"},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest"},"MPSBillingAccountResponse":{"properties":{"id":{"type":"integer","title":"Id"},"organization_id":{"type":"integer","title":"Organization Id"},"billing_mode":{"type":"string","title":"Billing Mode"},"cached_balance_credits":{"type":"number","title":"Cached Balance Credits"},"currency":{"type":"string","title":"Currency"}},"type":"object","required":["id","organization_id","billing_mode","cached_balance_credits","currency"],"title":"MPSBillingAccountResponse"},"MPSBillingCreditsResponse":{"properties":{"billing_version":{"type":"string","enum":["legacy","v2"],"title":"Billing Version"},"total_credits_used":{"type":"number","title":"Total Credits Used","default":0.0},"remaining_credits":{"type":"number","title":"Remaining Credits","default":0.0},"total_quota":{"type":"number","title":"Total Quota","default":0.0},"account":{"anyOf":[{"$ref":"#/components/schemas/MPSBillingAccountResponse"},{"type":"null"}]},"ledger_entries":{"items":{"$ref":"#/components/schemas/MPSCreditLedgerEntryResponse"},"type":"array","title":"Ledger Entries"},"total_count":{"type":"integer","title":"Total Count","default":0},"page":{"type":"integer","title":"Page","default":1},"limit":{"type":"integer","title":"Limit","default":50},"total_pages":{"type":"integer","title":"Total Pages","default":0}},"type":"object","required":["billing_version"],"title":"MPSBillingCreditsResponse"},"MPSCreditLedgerEntryResponse":{"properties":{"id":{"type":"integer","title":"Id"},"entry_type":{"type":"string","title":"Entry Type"},"origin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin"},"credits_delta":{"type":"number","title":"Credits Delta"},"balance_after":{"type":"number","title":"Balance After"},"amount_minor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Amount Minor"},"amount_currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Amount Currency"},"payment_order_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Payment Order Id"},"metric_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metric Code"},"correlation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Correlation Id"},"aggregation_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aggregation Key"},"usage_event_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Usage Event Id"},"workflow_run_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Workflow Run Id"},"workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Workflow Id"},"billable_quantity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Billable Quantity"},"quantity_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Quantity Unit"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","entry_type","credits_delta","balance_after","created_at"],"title":"MPSCreditLedgerEntryResponse"},"MPSCreditPurchaseUrlResponse":{"properties":{"checkout_url":{"type":"string","title":"Checkout Url"}},"type":"object","required":["checkout_url"],"title":"MPSCreditPurchaseUrlResponse"},"MPSCreditsResponse":{"properties":{"total_credits_used":{"type":"number","title":"Total Credits Used"},"remaining_credits":{"type":"number","title":"Remaining Credits"},"total_quota":{"type":"number","title":"Total Quota"}},"type":"object","required":["total_credits_used","remaining_credits","total_quota"],"title":"MPSCreditsResponse"},"McpRefreshResponse":{"properties":{"tool_uuid":{"type":"string","title":"Tool Uuid"},"discovered_tools":{"items":{},"type":"array","title":"Discovered Tools"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["tool_uuid"],"title":"McpRefreshResponse","description":"Result of re-discovering an MCP server's tool catalog."},"McpToolConfig":{"properties":{"transport":{"type":"string","const":"streamable_http","title":"Transport","description":"MCP transport protocol.","default":"streamable_http"},"url":{"type":"string","title":"Url","description":"MCP server URL. Must use http:// or https://.","llm_hint":"Use the server's streamable HTTP MCP endpoint."},"credential_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credential Uuid","description":"Reference to an external credential for MCP server auth.","llm_hint":"Use a credential_uuid returned by list_credentials. Credentials are created by the user in the UI."},"tools_filter":{"items":{"type":"string"},"type":"array","title":"Tools Filter","description":"Allowlist of MCP tool names to expose. Empty exposes all tools.","llm_hint":"Use exact MCP tool names from the remote server catalog when you need to restrict the exposed tools."},"timeout_secs":{"type":"integer","minimum":0.0,"title":"Timeout Secs","description":"Connection timeout in seconds.","default":30},"sse_read_timeout_secs":{"type":"integer","minimum":0.0,"title":"Sse Read Timeout Secs","description":"SSE read timeout in seconds.","default":300},"discovered_tools":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Discovered Tools","description":"Server-managed cache of the MCP server's tool catalog [{name, description}]. Populated best-effort by the backend.","llm_hint":"Do not author this field; the server fills it."}},"type":"object","required":["url"],"title":"McpToolConfig","description":"Configuration for a customer MCP server tool definition."},"McpToolDefinition":{"properties":{"schema_version":{"type":"integer","title":"Schema Version","description":"Schema version.","default":1},"type":{"type":"string","const":"mcp","title":"Type","description":"Tool type."},"config":{"$ref":"#/components/schemas/McpToolConfig","description":"MCP server configuration."}},"type":"object","required":["type","config"],"title":"McpToolDefinition","description":"Persisted MCP tool definition."},"MiniMaxLLMConfiguration":{"properties":{"provider":{"type":"string","const":"minimax","title":"Provider","default":"minimax"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"MiniMax chat model.","default":"MiniMax-M2.7","examples":["MiniMax-M2.7","MiniMax-M2.7-highspeed"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"MiniMax OpenAI-compatible API endpoint.","default":"https://api.minimax.io/v1"},"temperature":{"type":"number","maximum":2.0,"exclusiveMinimum":0.0,"title":"Temperature","description":"Sampling temperature. MiniMax requires > 0.","default":1.0}},"type":"object","required":["api_key"],"title":"MiniMaxLLMConfiguration"},"MiniMaxTTSConfiguration":{"properties":{"provider":{"type":"string","const":"minimax","title":"Provider","default":"minimax"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"MiniMax TTS model.","default":"speech-2.8-hd","examples":["speech-2.8-hd","speech-2.8-turbo"]},"voice":{"type":"string","title":"Voice","description":"MiniMax voice ID.","default":"English_Graceful_Lady","examples":["English_Graceful_Lady","English_Insightful_Speaker","English_radiant_girl","English_Persuasive_Man","English_Lucky_Robot","English_expressive_narrator"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"MiniMax TTS API endpoint (must include the /v1/t2a_v2 path). Defaults to the global endpoint; override with https://api.minimaxi.chat/v1/t2a_v2 (mainland China) or https://api-uw.minimax.io/v1/t2a_v2 (US-West).","default":"https://api.minimax.io/v1/t2a_v2"},"speed":{"type":"number","maximum":2.0,"minimum":0.5,"title":"Speed","description":"Speech speed (0.5 to 2.0).","default":1.0},"group_id":{"type":"string","title":"Group Id","description":"MiniMax Group ID (found in your MiniMax dashboard under Account \u2192 Group)."}},"type":"object","required":["api_key","group_id"],"title":"MiniMaxTTSConfiguration"},"MoveWorkflowToFolderRequest":{"properties":{"folder_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Folder Id"}},"type":"object","title":"MoveWorkflowToFolderRequest","description":"Move a workflow into a folder, or to \"Uncategorized\" when null."},"NodeCategory":{"type":"string","enum":["call_node","global_node","trigger","integration"],"title":"NodeCategory","description":"Drives grouping in the AddNodePanel UI."},"NodeExample":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"data":{"additionalProperties":true,"type":"object","title":"Data"}},"additionalProperties":false,"type":"object","required":["name","data"],"title":"NodeExample","description":"A worked example LLMs can pattern-match. Keep small and realistic."},"NodeSpec":{"properties":{"name":{"type":"string","title":"Name"},"display_name":{"type":"string","title":"Display Name"},"description":{"type":"string","minLength":1,"title":"Description","description":"Human-facing explanation shown in AddNodePanel."},"llm_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Hint","description":"LLM-only guidance; omitted from the UI."},"category":{"$ref":"#/components/schemas/NodeCategory"},"icon":{"type":"string","title":"Icon"},"version":{"type":"string","title":"Version","default":"1.0.0"},"properties":{"items":{"$ref":"#/components/schemas/PropertySpec"},"type":"array","title":"Properties"},"examples":{"items":{"$ref":"#/components/schemas/NodeExample"},"type":"array","title":"Examples"},"graph_constraints":{"anyOf":[{"$ref":"#/components/schemas/GraphConstraints"},{"type":"null"}]}},"additionalProperties":false,"type":"object","required":["name","display_name","description","category","icon","properties"],"title":"NodeSpec","description":"Single source of truth for a node type."},"NodeTypesResponse":{"properties":{"spec_version":{"type":"string","title":"Spec Version"},"node_types":{"items":{"$ref":"#/components/schemas/NodeSpec"},"type":"array","title":"Node Types"}},"type":"object","required":["spec_version","node_types"],"title":"NodeTypesResponse"},"OnboardingState":{"properties":{"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"skipped":{"type":"boolean","title":"Skipped","default":false},"seen_tooltips":{"items":{"type":"string"},"type":"array","title":"Seen Tooltips"},"completed_actions":{"items":{"type":"string"},"type":"array","title":"Completed Actions"}},"type":"object","title":"OnboardingState","description":"Per-user onboarding state, stored under UserConfigurationKey.ONBOARDING.\n\nServer-authoritative replacement for the browser-localStorage onboarding\nstore, so the post-signup gate and one-time tooltips hold across devices."},"OnboardingStateUpdate":{"properties":{"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"skipped":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Skipped"},"seen_tooltips":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Seen Tooltips"},"completed_actions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Completed Actions"}},"type":"object","title":"OnboardingStateUpdate","description":"Partial update merged into the stored state.\n\nScalars overwrite when supplied; list entries are unioned into the stored\nlists, so concurrent updates (e.g. two tabs marking different tooltips)\ndon't drop each other's items."},"OpenAIEmbeddingsConfiguration":{"properties":{"provider":{"type":"string","const":"openai","title":"Provider","default":"openai"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenAI embedding model.","default":"text-embedding-3-small","examples":["text-embedding-3-small"]}},"type":"object","required":["api_key"],"title":"OpenAI"},"OpenAILLMService":{"properties":{"provider":{"type":"string","const":"openai","title":"Provider","default":"openai"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenAI chat model to use.","default":"gpt-4.1","examples":["gpt-4.1","gpt-4.1-mini","gpt-4.1-nano","gpt-5","gpt-5-mini","gpt-5-nano","gpt-3.5-turbo"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"Override only if using an OpenAI-compatible API (e.g. local LLM, proxy).","default":"https://api.openai.com/v1"}},"type":"object","required":["api_key"],"title":"OpenAI"},"OpenAIRealtimeLLMConfiguration":{"properties":{"provider":{"type":"string","const":"openai_realtime","title":"Provider","default":"openai_realtime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenAI realtime (speech-to-speech) model.","default":"gpt-realtime-2","examples":["gpt-realtime-2"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Voice the model speaks in.","default":"alloy","examples":["alloy","ash","ballad","coral","echo","sage","shimmer","verse"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"OpenAI Realtime"},"OpenAISTTConfiguration":{"properties":{"provider":{"type":"string","const":"openai","title":"Provider","default":"openai"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenAI transcription model.","default":"gpt-4o-transcribe","examples":["gpt-4o-transcribe"]},"base_url":{"type":"string","title":"Base Url","description":"Override only if using an OpenAI-compatible API (e.g. local STT, proxy).","default":"https://api.openai.com/v1"}},"type":"object","required":["api_key"],"title":"OpenAI"},"OpenAITTSService":{"properties":{"provider":{"type":"string","const":"openai","title":"Provider","default":"openai"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenAI TTS model.","default":"gpt-4o-mini-tts","examples":["gpt-4o-mini-tts"]},"voice":{"type":"string","title":"Voice","description":"OpenAI TTS voice name.","default":"alloy"},"base_url":{"type":"string","title":"Base Url","description":"Override only if using an OpenAI-compatible API (e.g. local TTS, proxy).","default":"https://api.openai.com/v1"}},"type":"object","required":["api_key"],"title":"OpenAI"},"OpenRouterEmbeddingsConfiguration":{"properties":{"provider":{"type":"string","const":"openrouter","title":"Provider","default":"openrouter"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenRouter-hosted embedding model slug.","default":"openai/text-embedding-3-small","examples":["openai/text-embedding-3-small"]},"base_url":{"type":"string","title":"Base Url","description":"Override only if proxying OpenRouter through your own gateway.","default":"https://openrouter.ai/api/v1"}},"type":"object","required":["api_key"],"title":"Open Router"},"OpenRouterLLMConfiguration":{"properties":{"provider":{"type":"string","const":"openrouter","title":"Provider","default":"openrouter"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"OpenRouter model slug in 'vendor/model' form.","default":"openai/gpt-4.1","examples":["openai/gpt-4.1","openai/gpt-4.1-mini","anthropic/claude-sonnet-4","google/gemini-2.5-flash","google/gemini-2.0-flash","meta-llama/llama-3.3-70b-instruct","deepseek/deepseek-chat-v3-0324"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"Override only if proxying OpenRouter through your own gateway.","default":"https://openrouter.ai/api/v1"}},"type":"object","required":["api_key"],"title":"Open Router"},"OrganizationAIModelConfigurationResponse":{"properties":{"configuration":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Configuration"},"effective_configuration":{"additionalProperties":true,"type":"object","title":"Effective Configuration"},"source":{"type":"string","enum":["organization_v2","legacy_user_v1","empty"],"title":"Source"}},"type":"object","required":["configuration","effective_configuration","source"],"title":"OrganizationAIModelConfigurationResponse"},"OrganizationAIModelConfigurationV2":{"properties":{"version":{"type":"integer","const":2,"title":"Version","default":2},"mode":{"type":"string","enum":["dograh","byok"],"title":"Mode"},"dograh":{"anyOf":[{"$ref":"#/components/schemas/DograhManagedAIModelConfiguration"},{"type":"null"}]},"byok":{"anyOf":[{"$ref":"#/components/schemas/BYOKAIModelConfiguration"},{"type":"null"}]}},"type":"object","required":["mode"],"title":"OrganizationAIModelConfigurationV2"},"OrganizationContextResponse":{"properties":{"organization_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Organization Id"},"organization_provider_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organization Provider Id"},"model_services":{"$ref":"#/components/schemas/OrganizationModelServicesContext"}},"type":"object","required":["model_services"],"title":"OrganizationContextResponse"},"OrganizationModelServicesContext":{"properties":{"config_source":{"type":"string","enum":["organization_v2","legacy_user_v1","empty"],"title":"Config Source"},"has_model_configuration_v2":{"type":"boolean","title":"Has Model Configuration V2"},"managed_service_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Managed Service Version"},"uses_managed_service_v2":{"type":"boolean","title":"Uses Managed Service V2"}},"type":"object","required":["config_source","has_model_configuration_v2","uses_managed_service_v2"],"title":"OrganizationModelServicesContext"},"OrganizationPreferences":{"properties":{"test_phone_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Phone Number"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timezone"}},"type":"object","title":"OrganizationPreferences"},"PhoneNumberCreateRequest":{"properties":{"address":{"type":"string","maxLength":255,"minLength":1,"title":"Address"},"country_code":{"anyOf":[{"type":"string","maxLength":2,"minLength":2},{"type":"null"}],"title":"Country Code"},"label":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Label"},"inbound_workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inbound Workflow Id"},"is_active":{"type":"boolean","title":"Is Active","default":true},"is_default_caller_id":{"type":"boolean","title":"Is Default Caller Id","default":false},"extra_metadata":{"additionalProperties":true,"type":"object","title":"Extra Metadata"}},"type":"object","required":["address"],"title":"PhoneNumberCreateRequest","description":"Create a new phone number under a telephony configuration.\n\n``address_normalized`` and ``address_type`` are computed server-side from\n``address`` (and ``country_code`` if PSTN). ``address`` itself is stored\nverbatim for display."},"PhoneNumberListResponse":{"properties":{"phone_numbers":{"items":{"$ref":"#/components/schemas/PhoneNumberResponse"},"type":"array","title":"Phone Numbers"}},"type":"object","required":["phone_numbers"],"title":"PhoneNumberListResponse"},"PhoneNumberResponse":{"properties":{"id":{"type":"integer","title":"Id"},"telephony_configuration_id":{"type":"integer","title":"Telephony Configuration Id"},"address":{"type":"string","title":"Address"},"address_normalized":{"type":"string","title":"Address Normalized"},"address_type":{"type":"string","title":"Address Type"},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"inbound_workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inbound Workflow Id"},"inbound_workflow_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inbound Workflow Name"},"is_active":{"type":"boolean","title":"Is Active"},"is_default_caller_id":{"type":"boolean","title":"Is Default Caller Id"},"extra_metadata":{"additionalProperties":true,"type":"object","title":"Extra Metadata"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"provider_sync":{"anyOf":[{"$ref":"#/components/schemas/ProviderSyncStatus"},{"type":"null"}]}},"type":"object","required":["id","telephony_configuration_id","address","address_normalized","address_type","is_active","is_default_caller_id","extra_metadata","created_at","updated_at"],"title":"PhoneNumberResponse"},"PhoneNumberUpdateRequest":{"properties":{"label":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Label"},"inbound_workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inbound Workflow Id"},"clear_inbound_workflow":{"type":"boolean","title":"Clear Inbound Workflow","default":false},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"country_code":{"anyOf":[{"type":"string","maxLength":2,"minLength":2},{"type":"null"}],"title":"Country Code"},"extra_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extra Metadata"}},"type":"object","title":"PhoneNumberUpdateRequest","description":"Partial update. ``address`` is intentionally immutable \u2014 to change a\nnumber, delete the row and create a new one."},"PlivoConfigurationRequest":{"properties":{"provider":{"type":"string","const":"plivo","title":"Provider","default":"plivo"},"auth_id":{"type":"string","title":"Auth Id","description":"Plivo Auth ID"},"auth_token":{"type":"string","title":"Auth Token","description":"Plivo Auth Token"},"application_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Id","description":"Plivo Application ID. The application's answer_url is updated when inbound workflows are attached to numbers on this account. If omitted, an application is auto-created on save and its id is stored on the configuration."},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of Plivo phone numbers"}},"type":"object","required":["auth_id","auth_token"],"title":"PlivoConfigurationRequest","description":"Request schema for Plivo configuration."},"PlivoConfigurationResponse":{"properties":{"provider":{"type":"string","const":"plivo","title":"Provider","default":"plivo"},"auth_id":{"type":"string","title":"Auth Id"},"auth_token":{"type":"string","title":"Auth Token"},"application_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Id"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["auth_id","auth_token","from_numbers"],"title":"PlivoConfigurationResponse","description":"Response schema for Plivo configuration with masked sensitive fields."},"PresetToolParameter":{"properties":{"name":{"type":"string","title":"Name","description":"Parameter name used as a key in the request body."},"type":{"type":"string","enum":["string","number","boolean","object","array"],"title":"Type","description":"JSON type for the resolved value.","llm_hint":"Allowed values are string, number, boolean, object, and array."},"value_template":{"type":"string","title":"Value Template","description":"Fixed value or template, e.g. {{initial_context.phone_number}}.","llm_hint":"Use {{initial_context.*}} for call-start context and {{gathered_context.*}} for values extracted during the call."},"required":{"type":"boolean","title":"Required","description":"Whether the parameter must resolve to a non-empty value.","default":true}},"type":"object","required":["name","type","value_template"],"title":"PresetToolParameter","description":"A parameter injected by Dograh at runtime."},"PresignedUploadUrlRequest":{"properties":{"file_name":{"type":"string","pattern":".*\\.csv$","title":"File Name","description":"CSV filename"},"file_size":{"type":"integer","maximum":10485760.0,"exclusiveMinimum":0.0,"title":"File Size","description":"File size in bytes (max 10MB)"},"content_type":{"type":"string","title":"Content Type","description":"File content type","default":"text/csv"}},"type":"object","required":["file_name","file_size"],"title":"PresignedUploadUrlRequest"},"PresignedUploadUrlResponse":{"properties":{"upload_url":{"type":"string","title":"Upload Url"},"file_key":{"type":"string","title":"File Key"},"expires_in":{"type":"integer","title":"Expires In"}},"type":"object","required":["upload_url","file_key","expires_in"],"title":"PresignedUploadUrlResponse"},"ProcessDocumentRequestSchema":{"properties":{"document_uuid":{"type":"string","title":"Document Uuid","description":"Document UUID to process"},"s3_key":{"type":"string","title":"S3 Key","description":"S3 key of the uploaded file"},"retrieval_mode":{"type":"string","title":"Retrieval Mode","description":"Retrieval mode: 'chunked' for vector search or 'full_document' for full text retrieval","default":"chunked"}},"type":"object","required":["document_uuid","s3_key"],"title":"ProcessDocumentRequestSchema","description":"Request schema for triggering document processing."},"PropertyOption":{"properties":{"value":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"boolean"},{"type":"number"}],"title":"Value"},"label":{"type":"string","title":"Label"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"additionalProperties":false,"type":"object","required":["value","label"],"title":"PropertyOption","description":"An option in an `options` or `multi_options` dropdown."},"PropertySpec":{"properties":{"name":{"type":"string","title":"Name"},"type":{"$ref":"#/components/schemas/PropertyType"},"display_name":{"type":"string","title":"Display Name"},"description":{"type":"string","minLength":1,"title":"Description","description":"Human-facing explanation shown in the UI."},"llm_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Hint","description":"LLM-only guidance; omitted from the UI."},"default":{"title":"Default"},"required":{"type":"boolean","title":"Required","default":false},"placeholder":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Placeholder"},"display_options":{"anyOf":[{"$ref":"#/components/schemas/DisplayOptions"},{"type":"null"}]},"options":{"anyOf":[{"items":{"$ref":"#/components/schemas/PropertyOption"},"type":"array"},{"type":"null"}],"title":"Options"},"properties":{"anyOf":[{"items":{"$ref":"#/components/schemas/PropertySpec"},"type":"array"},{"type":"null"}],"title":"Properties"},"min_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Value"},"max_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Value"},"min_length":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Length"},"max_length":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Length"},"pattern":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pattern"},"editor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Editor"},"extra":{"additionalProperties":true,"type":"object","title":"Extra"}},"additionalProperties":false,"type":"object","required":["name","type","display_name","description"],"title":"PropertySpec","description":"Single field on a node.\n\n`description` is HUMAN-FACING \u2014 shown under the field in the edit\ndialog. Keep it concise and explain what the field does.\n\n`llm_hint` is LLM-FACING \u2014 appears only in the `get_node_type` MCP\nresponse and in SDK schema output. Use it for catalog tool references\n(e.g., \"Use `list_recordings`\"), array shape, expected value idioms,\nor anything that would be noise in the UI. Optional; omit when the\n`description` already suffices for both audiences."},"PropertyType":{"type":"string","enum":["string","number","boolean","options","multi_options","fixed_collection","json","tool_refs","document_refs","recording_ref","credential_ref","mention_textarea","url"],"title":"PropertyType","description":"Bounded vocabulary of property types the renderer dispatches on.\n\nAdding a value here requires a matching arm in the frontend\n`` switch and (where relevant) the SDK codegen template."},"ProviderSyncStatus":{"properties":{"ok":{"type":"boolean","title":"Ok"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["ok"],"title":"ProviderSyncStatus","description":"Result of pushing a phone-number change to the upstream provider.\n\nReturned alongside create/update responses when the route attempted to\nsync inbound webhook configuration. ``ok=False`` is a warning, not a\nfatal error \u2014 the DB write succeeded."},"RecordingCreateRequestSchema":{"properties":{"recording_id":{"type":"string","title":"Recording Id","description":"Short recording ID from upload step"},"tts_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tts Provider","description":"TTS provider (e.g. elevenlabs)"},"tts_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tts Model","description":"TTS model name"},"tts_voice_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tts Voice Id","description":"TTS voice identifier"},"transcript":{"type":"string","title":"Transcript","description":"User-provided transcript of the recording"},"storage_key":{"type":"string","title":"Storage Key","description":"Storage key from upload step"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata","description":"Optional metadata (file_size, duration, etc.)"}},"type":"object","required":["recording_id","transcript","storage_key"],"title":"RecordingCreateRequestSchema","description":"Request schema for creating a recording record after upload."},"RecordingListResponseSchema":{"properties":{"recordings":{"items":{"$ref":"#/components/schemas/RecordingResponseSchema"},"type":"array","title":"Recordings"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["recordings","total"],"title":"RecordingListResponseSchema","description":"Response schema for list of recordings."},"RecordingResponseSchema":{"properties":{"id":{"type":"integer","title":"Id"},"recording_id":{"type":"string","title":"Recording Id"},"workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Workflow Id"},"organization_id":{"type":"integer","title":"Organization Id"},"tts_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tts Provider"},"tts_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tts Model"},"tts_voice_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tts Voice Id"},"transcript":{"type":"string","title":"Transcript"},"storage_key":{"type":"string","title":"Storage Key"},"storage_backend":{"type":"string","title":"Storage Backend"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_by":{"type":"integer","title":"Created By"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","recording_id","organization_id","transcript","storage_key","storage_backend","metadata","created_by","created_at","is_active"],"title":"RecordingResponseSchema","description":"Response schema for a single recording."},"RecordingUpdateRequestSchema":{"properties":{"recording_id":{"type":"string","maxLength":64,"minLength":1,"pattern":"^[a-zA-Z0-9_-]+$","title":"Recording Id","description":"New descriptive recording ID (letters, numbers, hyphens, underscores only)"}},"type":"object","required":["recording_id"],"title":"RecordingUpdateRequestSchema","description":"Request schema for updating a recording's ID."},"RecordingUploadResponseSchema":{"properties":{"upload_url":{"type":"string","title":"Upload Url","description":"Presigned URL for uploading the audio"},"recording_id":{"type":"string","title":"Recording Id","description":"Short unique recording ID"},"storage_key":{"type":"string","title":"Storage Key","description":"Storage key where file will be uploaded"}},"type":"object","required":["upload_url","recording_id","storage_key"],"title":"RecordingUploadResponseSchema","description":"Response schema with presigned upload URL."},"RedialCampaignRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name","description":"Name for the redial campaign"},"retry_on_voicemail":{"type":"boolean","title":"Retry On Voicemail","default":true},"retry_on_no_answer":{"type":"boolean","title":"Retry On No Answer","default":true},"retry_on_busy":{"type":"boolean","title":"Retry On Busy","default":true},"retry_config":{"anyOf":[{"$ref":"#/components/schemas/RetryConfigRequest"},{"type":"null"}]}},"type":"object","title":"RedialCampaignRequest"},"RetryConfigRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"max_retries":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"Max Retries","default":2},"retry_delay_seconds":{"type":"integer","maximum":3600.0,"minimum":30.0,"title":"Retry Delay Seconds","default":120},"retry_on_busy":{"type":"boolean","title":"Retry On Busy","default":true},"retry_on_no_answer":{"type":"boolean","title":"Retry On No Answer","default":true},"retry_on_voicemail":{"type":"boolean","title":"Retry On Voicemail","default":true}},"type":"object","title":"RetryConfigRequest"},"RetryConfigResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"max_retries":{"type":"integer","title":"Max Retries"},"retry_delay_seconds":{"type":"integer","title":"Retry Delay Seconds"},"retry_on_busy":{"type":"boolean","title":"Retry On Busy"},"retry_on_no_answer":{"type":"boolean","title":"Retry On No Answer"},"retry_on_voicemail":{"type":"boolean","title":"Retry On Voicemail"}},"type":"object","required":["enabled","max_retries","retry_delay_seconds","retry_on_busy","retry_on_no_answer","retry_on_voicemail"],"title":"RetryConfigResponse"},"RewindTextChatSessionRequest":{"properties":{"cursor_turn_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor Turn Id"},"expected_revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Revision"}},"type":"object","title":"RewindTextChatSessionRequest"},"RimeTTSConfiguration":{"properties":{"provider":{"type":"string","const":"rime","title":"Provider","default":"rime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Rime TTS model.","default":"arcana","examples":["arcana","mistv3","mistv2","mist"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Rime voice ID.","default":"celeste"},"speed":{"type":"number","maximum":2.0,"minimum":0.5,"title":"Speed","description":"Speech speed multiplier.","default":1.0},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code.","default":"en","examples":["en","de","fr","es","hi"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Rime"},"S3SignedUrlResponse":{"properties":{"url":{"type":"string","title":"Url"},"expires_in":{"type":"integer","title":"Expires In"}},"type":"object","required":["url","expires_in"],"title":"S3SignedUrlResponse"},"SarvamLLMConfiguration":{"properties":{"provider":{"type":"string","const":"sarvam","title":"Provider","default":"sarvam"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Sarvam chat model. Use sarvam-30b for low-latency voice agents; sarvam-105b for complex multi-step reasoning.","default":"sarvam-30b","examples":["sarvam-30b","sarvam-105b"],"allow_custom_input":true},"temperature":{"type":"number","maximum":2.0,"minimum":0.0,"title":"Temperature","description":"Sampling temperature. Sarvam recommends 0.5 for balanced conversational responses.","default":0.5}},"type":"object","required":["api_key"],"title":"Sarvam"},"SarvamSTTConfiguration":{"properties":{"provider":{"type":"string","const":"sarvam","title":"Provider","default":"sarvam"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Sarvam STT model. saarika:v2.5 transcribes in the spoken language; saaras:v3 is the recommended model with flexible output modes.","default":"saarika:v2.5","examples":["saarika:v2.5","saaras:v3"]},"language":{"type":"string","title":"Language","description":"BCP-47 language code. Use unknown for automatic language detection.","default":"unknown","examples":["unknown","hi-IN","bn-IN","gu-IN","kn-IN","ml-IN","mr-IN","od-IN","pa-IN","ta-IN","te-IN","en-IN"],"model_options":{"saaras:v3":["unknown","hi-IN","bn-IN","gu-IN","kn-IN","ml-IN","mr-IN","od-IN","pa-IN","ta-IN","te-IN","en-IN","as-IN","ur-IN","ne-IN","kok-IN","ks-IN","sd-IN","sa-IN","sat-IN","mni-IN","brx-IN","mai-IN","doi-IN"],"saarika:v2.5":["unknown","hi-IN","bn-IN","gu-IN","kn-IN","ml-IN","mr-IN","od-IN","pa-IN","ta-IN","te-IN","en-IN"]}}},"type":"object","required":["api_key"],"title":"Sarvam"},"SarvamTTSConfiguration":{"properties":{"provider":{"type":"string","const":"sarvam","title":"Provider","default":"sarvam"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Sarvam TTS model (voice list depends on this).","default":"bulbul:v2","examples":["bulbul:v2","bulbul:v3"]},"voice":{"type":"string","title":"Voice","description":"Sarvam voice name; must match the selected model's voice list.","default":"anushka","examples":["anushka","manisha","vidya","arya","abhilash","karun","hitesh"],"model_options":{"bulbul:v2":["anushka","manisha","vidya","arya","abhilash","karun","hitesh"],"bulbul:v3":["shubh","aditya","ritu","priya","neha","rahul","pooja","rohan","simran","kavya","amit","dev","ishita","shreya","ratan","varun","manan","sumit","roopa","kabir","aayan","ashutosh","advait","amelia","sophia","anand","tanya","tarun","sunny","mani","gokul","vijay","shruti","suhani","mohit","kavitha","rehan","soham","rupali"]}},"language":{"type":"string","title":"Language","description":"BCP-47 Indian-language code (e.g. hi-IN, en-IN).","default":"hi-IN","examples":["bn-IN","en-IN","gu-IN","hi-IN","kn-IN","ml-IN","mr-IN","od-IN","pa-IN","ta-IN","te-IN","as-IN"]},"speed":{"type":"number","maximum":2.0,"minimum":0.5,"title":"Speed","description":"Speech speed multiplier.","default":1.0}},"type":"object","required":["api_key"],"title":"Sarvam"},"ScheduleConfigRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled","default":true},"timezone":{"type":"string","title":"Timezone","default":"UTC"},"slots":{"items":{"$ref":"#/components/schemas/TimeSlotRequest"},"type":"array","maxItems":50,"minItems":1,"title":"Slots"}},"type":"object","required":["slots"],"title":"ScheduleConfigRequest"},"ScheduleConfigResponse":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"timezone":{"type":"string","title":"Timezone"},"slots":{"items":{"$ref":"#/components/schemas/TimeSlotResponse"},"type":"array","title":"Slots"}},"type":"object","required":["enabled","timezone","slots"],"title":"ScheduleConfigResponse"},"ServiceKeyResponse":{"properties":{"name":{"type":"string","title":"Name"},"id":{"type":"integer","title":"Id"},"key_prefix":{"type":"string","title":"Key Prefix"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"archived_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Archived At"},"created_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By"}},"type":"object","required":["name","id","key_prefix","is_active","created_at"],"title":"ServiceKeyResponse"},"SignupRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},"type":"object","required":["email","password"],"title":"SignupRequest"},"SmallestAISTTConfiguration":{"properties":{"provider":{"type":"string","const":"smallest","title":"Provider","default":"smallest"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Smallest AI STT model. Supports 38 languages with real-time streaming.","default":"pulse","examples":["pulse"]},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code for transcription.","default":"en","examples":["en","hi","fr","de","es","it","nl","pl","ru","pt","bn","gu","kn","ml","mr","ta","te","pa","or","bg","cs","da","et","fi","hu","lt","lv","mt","ro","sk","sv","uk"],"allow_custom_input":true}},"type":"object","required":["api_key"],"title":"Smallest AI","description":"Smallest AI ultralow-latency TTS (Waves) and STT (Pulse) APIs.","provider_docs_url":"https://smallest.ai/docs"},"SmallestAITTSConfiguration":{"properties":{"provider":{"type":"string","const":"smallest","title":"Provider","default":"smallest"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Smallest AI TTS model. lightning_v3.1_pro is the premium pool (American, British, Indian accents); lightning_v3.1 is the standard pool with 217 voices across 12 languages.","default":"lightning_v3.1","examples":["lightning_v3.1","lightning_v3.1_pro"]},"voice":{"type":"string","title":"Voice","description":"Smallest AI voice ID.","default":"sophia","examples":["sophia","avery","liam","lucas","olivia","ryan","freya","william","devansh","arjun","niharika","maya","dhruv","mia","maithili"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code for synthesis.","default":"en","examples":["en","hi","fr","de","es","it","nl","pl","ru","ar","bn","gu","he","kn","mr","ta"],"allow_custom_input":true},"speed":{"type":"number","maximum":2.0,"minimum":0.5,"title":"Speed","description":"Speech speed multiplier (0.5 to 2.0).","default":1.0}},"type":"object","required":["api_key"],"title":"Smallest AI","description":"Smallest AI ultralow-latency TTS (Waves) and STT (Pulse) APIs.","provider_docs_url":"https://smallest.ai/docs"},"SpeachesLLMConfiguration":{"properties":{"provider":{"type":"string","const":"speaches","title":"Provider","default":"speaches"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Usually not required for self-hosted endpoints. Leave blank unless your server enforces one."},"model":{"type":"string","title":"Model","description":"Model name as exposed by your OpenAI-compatible server.","default":"llama3","examples":["llama3","mistral","phi3","qwen2","gemma2","deepseek-r1"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"OpenAI-compatible endpoint (Ollama, vLLM, etc.).","default":"http://localhost:11434/v1"}},"type":"object","title":"Local Models (Speaches)","description":"Self-hosted OpenAI-compatible local models. See the Speaches project for setup and supported backends.","provider_docs_url":"https://github.com/speaches-ai/speaches"},"SpeachesSTTConfiguration":{"properties":{"provider":{"type":"string","const":"speaches","title":"Provider","default":"speaches"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Usually not required for self-hosted STT. Leave blank unless enforced."},"model":{"type":"string","title":"Model","description":"Whisper model identifier as served by your STT endpoint.","default":"Systran/faster-distil-whisper-small.en","examples":["Systran/faster-distil-whisper-small.en","Systran/faster-whisper-large-v3"],"allow_custom_input":true},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code.","default":"en","examples":["en","ar","nl","fr","de","hi","it","pt","es"],"allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"OpenAI-compatible STT endpoint (Speaches, etc.).","default":"http://localhost:8000/v1"}},"type":"object","title":"Local Models (Speaches)","description":"Self-hosted OpenAI-compatible local models. See the Speaches project for setup and supported backends.","provider_docs_url":"https://github.com/speaches-ai/speaches"},"SpeachesTTSConfiguration":{"properties":{"provider":{"type":"string","const":"speaches","title":"Provider","default":"speaches"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Api Key","description":"Usually not required for self-hosted TTS. Leave blank unless enforced."},"model":{"type":"string","title":"Model","description":"Model name as served by your TTS endpoint (e.g. Kokoro-FastAPI).","default":"kokoro","examples":["hexgrad/Kokoro-82M"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Voice ID for the TTS engine.","default":"af_heart","allow_custom_input":true},"base_url":{"type":"string","title":"Base Url","description":"OpenAI-compatible TTS endpoint (Kokoro-FastAPI, etc.).","default":"http://localhost:8000/v1"},"speed":{"type":"number","maximum":4.0,"minimum":0.25,"title":"Speed","description":"Speech speed (0.25 to 4.0).","default":1.0}},"type":"object","title":"Local Models (Speaches)","description":"Self-hosted OpenAI-compatible local models. See the Speaches project for setup and supported backends.","provider_docs_url":"https://github.com/speaches-ai/speaches"},"SpeechmaticsSTTConfiguration":{"properties":{"provider":{"type":"string","const":"speechmatics","title":"Provider","default":"speechmatics"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Speechmatics operating point: 'standard' or 'enhanced'.","default":"enhanced"},"language":{"type":"string","title":"Language","description":"ISO 639-1 language code.","default":"en","examples":["ar","ar_en","ba","eu","be","bn","bg","yue","ca","hr","cs","da","nl","en","eo","et","fi","fr","gl","de","el","he","hi","hu","id","ia","ga","it","ja","ko","lv","lt","ms","en_ms","mt","cmn","cmn_en","cmn_en_ms_ta","mr","mn","no","fa","pl","pt","ro","ru","sk","sl","es","sw","sv","tl","ta","en_ta","th","tr","uk","ur","ug","vi","cy"]}},"type":"object","required":["api_key"],"title":"Speechmatics"},"SuperuserWorkflowRunResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"workflow_id":{"type":"integer","title":"Workflow Id"},"workflow_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workflow Name"},"user_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"User Id"},"organization_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Organization Id"},"organization_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organization Name"},"mode":{"type":"string","title":"Mode"},"is_completed":{"type":"boolean","title":"Is Completed"},"recording_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recording Url"},"transcript_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript Url"},"usage_info":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Usage Info"},"cost_info":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Cost Info"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"},"gathered_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Gathered Context"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","workflow_id","workflow_name","user_id","organization_id","organization_name","mode","is_completed","recording_url","transcript_url","usage_info","cost_info","initial_context","gathered_context","created_at"],"title":"SuperuserWorkflowRunResponse"},"SuperuserWorkflowRunsListResponse":{"properties":{"workflow_runs":{"items":{"$ref":"#/components/schemas/SuperuserWorkflowRunResponse"},"type":"array","title":"Workflow Runs"},"total_count":{"type":"integer","title":"Total Count"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["workflow_runs","total_count","page","limit","total_pages"],"title":"SuperuserWorkflowRunsListResponse"},"TelephonyConfigWarningsResponse":{"properties":{"telnyx_missing_webhook_public_key_count":{"type":"integer","title":"Telnyx Missing Webhook Public Key Count"}},"type":"object","required":["telnyx_missing_webhook_public_key_count"],"title":"TelephonyConfigWarningsResponse","description":"Aggregated telephony-configuration warning counts for the user's org.\n\nDrives the page banner and nav badge that nudge customers to finish\noptional-but-recommended configuration steps. Shape is a flat dict so\nnew warning types can be added without breaking the client."},"TelephonyConfigurationCreateRequest":{"properties":{"name":{"type":"string","maxLength":64,"minLength":1,"title":"Name"},"is_default_outbound":{"type":"boolean","title":"Is Default Outbound","default":false},"config":{"oneOf":[{"$ref":"#/components/schemas/ARIConfigurationRequest"},{"$ref":"#/components/schemas/CloudonixConfigurationRequest"},{"$ref":"#/components/schemas/PlivoConfigurationRequest"},{"$ref":"#/components/schemas/TelnyxConfigurationRequest"},{"$ref":"#/components/schemas/TwilioConfigurationRequest"},{"$ref":"#/components/schemas/VobizConfigurationRequest"},{"$ref":"#/components/schemas/VonageConfigurationRequest"}],"title":"Config","discriminator":{"propertyName":"provider","mapping":{"ari":"#/components/schemas/ARIConfigurationRequest","cloudonix":"#/components/schemas/CloudonixConfigurationRequest","plivo":"#/components/schemas/PlivoConfigurationRequest","telnyx":"#/components/schemas/TelnyxConfigurationRequest","twilio":"#/components/schemas/TwilioConfigurationRequest","vobiz":"#/components/schemas/VobizConfigurationRequest","vonage":"#/components/schemas/VonageConfigurationRequest"}}}},"type":"object","required":["name","config"],"title":"TelephonyConfigurationCreateRequest","description":"Body for ``POST /telephony-configs``.\n\n``config`` carries the provider-specific credential fields (the same\ndiscriminated union used by the legacy single-config endpoint). Any\n``from_numbers`` on the inner config are ignored \u2014 phone numbers are\nmanaged via the dedicated phone-numbers endpoints."},"TelephonyConfigurationDetail":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"provider":{"type":"string","title":"Provider"},"is_default_outbound":{"type":"boolean","title":"Is Default Outbound"},"credentials":{"additionalProperties":true,"type":"object","title":"Credentials"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","provider","is_default_outbound","credentials","created_at","updated_at"],"title":"TelephonyConfigurationDetail","description":"Body of ``GET /telephony-configs/{id}`` \u2014 credentials are masked."},"TelephonyConfigurationListItem":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"provider":{"type":"string","title":"Provider"},"is_default_outbound":{"type":"boolean","title":"Is Default Outbound"},"phone_number_count":{"type":"integer","title":"Phone Number Count","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","provider","is_default_outbound","created_at","updated_at"],"title":"TelephonyConfigurationListItem","description":"One row in ``GET /telephony-configs``."},"TelephonyConfigurationListResponse":{"properties":{"configurations":{"items":{"$ref":"#/components/schemas/TelephonyConfigurationListItem"},"type":"array","title":"Configurations"}},"type":"object","required":["configurations"],"title":"TelephonyConfigurationListResponse"},"TelephonyConfigurationResponse":{"properties":{"twilio":{"anyOf":[{"$ref":"#/components/schemas/TwilioConfigurationResponse"},{"type":"null"}]},"plivo":{"anyOf":[{"$ref":"#/components/schemas/PlivoConfigurationResponse"},{"type":"null"}]},"vonage":{"anyOf":[{"$ref":"#/components/schemas/VonageConfigurationResponse"},{"type":"null"}]},"vobiz":{"anyOf":[{"$ref":"#/components/schemas/VobizConfigurationResponse"},{"type":"null"}]},"cloudonix":{"anyOf":[{"$ref":"#/components/schemas/CloudonixConfigurationResponse"},{"type":"null"}]},"ari":{"anyOf":[{"$ref":"#/components/schemas/ARIConfigurationResponse"},{"type":"null"}]},"telnyx":{"anyOf":[{"$ref":"#/components/schemas/TelnyxConfigurationResponse"},{"type":"null"}]}},"type":"object","title":"TelephonyConfigurationResponse","description":"Top-level telephony configuration response.\n\nKeeps the per-provider field shape that the UI client depends on. When\nthe UI moves to metadata-driven forms, this can be replaced with a\nflat discriminated union."},"TelephonyConfigurationUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":64,"minLength":1},{"type":"null"}],"title":"Name"},"config":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/ARIConfigurationRequest"},{"$ref":"#/components/schemas/CloudonixConfigurationRequest"},{"$ref":"#/components/schemas/PlivoConfigurationRequest"},{"$ref":"#/components/schemas/TelnyxConfigurationRequest"},{"$ref":"#/components/schemas/TwilioConfigurationRequest"},{"$ref":"#/components/schemas/VobizConfigurationRequest"},{"$ref":"#/components/schemas/VonageConfigurationRequest"}],"discriminator":{"propertyName":"provider","mapping":{"ari":"#/components/schemas/ARIConfigurationRequest","cloudonix":"#/components/schemas/CloudonixConfigurationRequest","plivo":"#/components/schemas/PlivoConfigurationRequest","telnyx":"#/components/schemas/TelnyxConfigurationRequest","twilio":"#/components/schemas/TwilioConfigurationRequest","vobiz":"#/components/schemas/VobizConfigurationRequest","vonage":"#/components/schemas/VonageConfigurationRequest"}}},{"type":"null"}],"title":"Config"}},"type":"object","title":"TelephonyConfigurationUpdateRequest","description":"Body for ``PUT /telephony-configs/{id}``. Partial update."},"TelephonyProviderMetadata":{"properties":{"provider":{"type":"string","title":"Provider"},"display_name":{"type":"string","title":"Display Name"},"fields":{"items":{"$ref":"#/components/schemas/TelephonyProviderUIField"},"type":"array","title":"Fields"},"docs_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Docs Url"}},"type":"object","required":["provider","display_name","fields"],"title":"TelephonyProviderMetadata","description":"UI form metadata for a single telephony provider."},"TelephonyProviderUIField":{"properties":{"name":{"type":"string","title":"Name"},"label":{"type":"string","title":"Label"},"type":{"type":"string","title":"Type"},"required":{"type":"boolean","title":"Required"},"sensitive":{"type":"boolean","title":"Sensitive"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"placeholder":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Placeholder"}},"type":"object","required":["name","label","type","required","sensitive"],"title":"TelephonyProviderUIField","description":"One form field on a telephony provider's configuration UI."},"TelephonyProvidersMetadataResponse":{"properties":{"providers":{"items":{"$ref":"#/components/schemas/TelephonyProviderMetadata"},"type":"array","title":"Providers"}},"type":"object","required":["providers"],"title":"TelephonyProvidersMetadataResponse","description":"List of UI form definitions used by the telephony-config screen."},"TelnyxConfigurationRequest":{"properties":{"provider":{"type":"string","const":"telnyx","title":"Provider","default":"telnyx"},"api_key":{"type":"string","title":"Api Key","description":"Telnyx API Key"},"connection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connection Id","description":"Telnyx Call Control Application ID (connection_id). If omitted, a Call Control Application is auto-created on save and its id is stored on the configuration."},"webhook_public_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Public Key","description":"Webhook public key from Mission Control Portal \u2192 Keys & Credentials \u2192 Public Key. Used to verify Telnyx webhook signatures."},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of Telnyx phone numbers"}},"type":"object","required":["api_key"],"title":"TelnyxConfigurationRequest","description":"Request schema for Telnyx configuration."},"TelnyxConfigurationResponse":{"properties":{"provider":{"type":"string","const":"telnyx","title":"Provider","default":"telnyx"},"api_key":{"type":"string","title":"Api Key"},"connection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connection Id"},"webhook_public_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Public Key"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["api_key","from_numbers"],"title":"TelnyxConfigurationResponse","description":"Response schema for Telnyx configuration with masked sensitive fields."},"TimeSlotRequest":{"properties":{"day_of_week":{"type":"integer","maximum":6.0,"minimum":0.0,"title":"Day Of Week"},"start_time":{"type":"string","pattern":"^\\d{2}:\\d{2}$","title":"Start Time"},"end_time":{"type":"string","pattern":"^\\d{2}:\\d{2}$","title":"End Time"}},"type":"object","required":["day_of_week","start_time","end_time"],"title":"TimeSlotRequest"},"TimeSlotResponse":{"properties":{"day_of_week":{"type":"integer","title":"Day Of Week"},"start_time":{"type":"string","title":"Start Time"},"end_time":{"type":"string","title":"End Time"}},"type":"object","required":["day_of_week","start_time","end_time"],"title":"TimeSlotResponse"},"ToolParameter":{"properties":{"name":{"type":"string","title":"Name","description":"Parameter name used as a key in the tool request body.","llm_hint":"Use a stable snake_case name the agent can naturally fill."},"type":{"type":"string","enum":["string","number","boolean","object","array"],"title":"Type","description":"JSON type for the parameter value.","llm_hint":"Allowed values are string, number, boolean, object, and array."},"description":{"type":"string","title":"Description","description":"Description shown to the model for this parameter.","llm_hint":"Write this as an instruction to the agent: what value to provide and when."},"required":{"type":"boolean","title":"Required","description":"Whether this parameter is required when the tool is called.","default":true}},"type":"object","required":["name","type","description"],"title":"ToolParameter","description":"A parameter that the tool accepts from the model at call time."},"ToolResponse":{"properties":{"id":{"type":"integer","title":"Id"},"tool_uuid":{"type":"string","title":"Tool Uuid"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"category":{"type":"string","title":"Category"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"icon_color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon Color"},"status":{"type":"string","title":"Status"},"definition":{"additionalProperties":true,"type":"object","title":"Definition"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"created_by":{"anyOf":[{"$ref":"#/components/schemas/CreatedByResponse"},{"type":"null"}]}},"type":"object","required":["id","tool_uuid","name","description","category","icon","icon_color","status","definition","created_at","updated_at"],"title":"ToolResponse","description":"Response schema for a reusable tool."},"TransferCallConfig":{"properties":{"destination":{"type":"string","title":"Destination","description":"Phone number or SIP endpoint to transfer the call to, e.g. +1234567890 or PJSIP/1234."},"messageType":{"type":"string","enum":["none","custom","audio"],"title":"Messagetype","description":"Type of message to play before transfer.","default":"none"},"customMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custommessage","description":"Custom message to play before transferring."},"audioRecordingId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Audiorecordingid","description":"Recording ID for audio message before transfer."},"timeout":{"type":"integer","maximum":120.0,"minimum":5.0,"title":"Timeout","description":"Maximum seconds to wait for the destination to answer.","default":30}},"type":"object","required":["destination"],"title":"TransferCallConfig","description":"Configuration for Transfer Call tools."},"TransferCallToolDefinition":{"properties":{"schema_version":{"type":"integer","title":"Schema Version","description":"Schema version.","default":1},"type":{"type":"string","const":"transfer_call","title":"Type","description":"Tool type."},"config":{"$ref":"#/components/schemas/TransferCallConfig","description":"Transfer Call configuration."}},"type":"object","required":["type","config"],"title":"TransferCallToolDefinition","description":"Tool definition for Transfer Call tools."},"TriggerCallRequest":{"properties":{"phone_number":{"type":"string","title":"Phone Number"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"},"telephony_configuration_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Telephony Configuration Id"}},"type":"object","required":["phone_number"],"title":"TriggerCallRequest","description":"Request model for triggering a call via API"},"TriggerCallResponse":{"properties":{"status":{"type":"string","title":"Status"},"workflow_run_id":{"type":"integer","title":"Workflow Run Id"},"workflow_run_name":{"type":"string","title":"Workflow Run Name"}},"type":"object","required":["status","workflow_run_id","workflow_run_name"],"title":"TriggerCallResponse","description":"Response model for successful call initiation"},"TurnCredentialsResponse":{"properties":{"username":{"type":"string","title":"Username"},"password":{"type":"string","title":"Password"},"ttl":{"type":"integer","title":"Ttl"},"uris":{"items":{"type":"string"},"type":"array","title":"Uris"}},"type":"object","required":["username","password","ttl","uris"],"title":"TurnCredentialsResponse","description":"Response model for TURN credentials."},"TwilioConfigurationRequest":{"properties":{"provider":{"type":"string","const":"twilio","title":"Provider","default":"twilio"},"account_sid":{"type":"string","title":"Account Sid","description":"Twilio Account SID"},"auth_token":{"type":"string","title":"Auth Token","description":"Twilio Auth Token"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of Twilio phone numbers"}},"type":"object","required":["account_sid","auth_token"],"title":"TwilioConfigurationRequest","description":"Request schema for Twilio configuration."},"TwilioConfigurationResponse":{"properties":{"provider":{"type":"string","const":"twilio","title":"Provider","default":"twilio"},"account_sid":{"type":"string","title":"Account Sid"},"auth_token":{"type":"string","title":"Auth Token"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["account_sid","auth_token","from_numbers"],"title":"TwilioConfigurationResponse","description":"Response schema for Twilio configuration with masked sensitive fields."},"UltravoxRealtimeLLMConfiguration":{"properties":{"provider":{"type":"string","const":"ultravox_realtime","title":"Provider","default":"ultravox_realtime"},"api_key":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"Api Key"},"model":{"type":"string","title":"Model","description":"Ultravox realtime voice-agent model.","default":"ultravox-v0.7","examples":["ultravox-v0.7","fixie-ai/ultravox"],"allow_custom_input":true},"voice":{"type":"string","title":"Voice","description":"Ultravox voice name or voice ID.","default":"Mark"}},"type":"object","required":["api_key"],"title":"Ultravox Realtime"},"UpdateCampaignRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name"},"retry_config":{"anyOf":[{"$ref":"#/components/schemas/RetryConfigRequest"},{"type":"null"}]},"max_concurrency":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":1.0},{"type":"null"}],"title":"Max Concurrency"},"schedule_config":{"anyOf":[{"$ref":"#/components/schemas/ScheduleConfigRequest"},{"type":"null"}]},"circuit_breaker":{"anyOf":[{"$ref":"#/components/schemas/CircuitBreakerConfigRequest"},{"type":"null"}]}},"type":"object","title":"UpdateCampaignRequest"},"UpdateCredentialRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"credential_type":{"anyOf":[{"$ref":"#/components/schemas/WebhookCredentialType"},{"type":"null"}]},"credential_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Credential Data"}},"type":"object","title":"UpdateCredentialRequest","description":"Request schema for updating a webhook credential."},"UpdateFolderRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"}},"type":"object","required":["name"],"title":"UpdateFolderRequest"},"UpdateToolRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"icon":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Icon"},"icon_color":{"anyOf":[{"type":"string","maxLength":7},{"type":"null"}],"title":"Icon Color"},"definition":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/HttpApiToolDefinition"},{"$ref":"#/components/schemas/EndCallToolDefinition"},{"$ref":"#/components/schemas/TransferCallToolDefinition"},{"$ref":"#/components/schemas/CalculatorToolDefinition"},{"$ref":"#/components/schemas/McpToolDefinition"}],"discriminator":{"propertyName":"type","mapping":{"calculator":"#/components/schemas/CalculatorToolDefinition","end_call":"#/components/schemas/EndCallToolDefinition","http_api":"#/components/schemas/HttpApiToolDefinition","mcp":"#/components/schemas/McpToolDefinition","transfer_call":"#/components/schemas/TransferCallToolDefinition"}}},{"type":"null"}],"title":"Definition"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},"type":"object","title":"UpdateToolRequest","description":"Request schema for updating a reusable tool."},"UpdateWorkflowRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"workflow_definition":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Workflow Definition"},"template_context_variables":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Template Context Variables"},"workflow_configurations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Workflow Configurations"}},"type":"object","title":"UpdateWorkflowRequest"},"UpdateWorkflowStatusRequest":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"UpdateWorkflowStatusRequest"},"UsageHistoryResponse":{"properties":{"runs":{"items":{"$ref":"#/components/schemas/WorkflowRunUsageResponse"},"type":"array","title":"Runs"},"total_dograh_tokens":{"type":"number","title":"Total Dograh Tokens"},"total_duration_seconds":{"type":"integer","title":"Total Duration Seconds"},"total_count":{"type":"integer","title":"Total Count"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["runs","total_dograh_tokens","total_duration_seconds","total_count","page","limit","total_pages"],"title":"UsageHistoryResponse"},"UserConfigurationRequestResponseSchema":{"properties":{"llm":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Llm"},"tts":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Tts"},"stt":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Stt"},"embeddings":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Embeddings"},"realtime":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Realtime"},"is_realtime":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Realtime"},"test_phone_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Phone Number"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timezone"},"organization_pricing":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"}]},"type":"object"},{"type":"null"}],"title":"Organization Pricing"}},"type":"object","title":"UserConfigurationRequestResponseSchema"},"UserResponse":{"properties":{"id":{"type":"integer","title":"Id"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"organization_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Organization Id"},"provider_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Id"}},"type":"object","required":["id","email"],"title":"UserResponse"},"ValidateWorkflowResponse":{"properties":{"is_valid":{"type":"boolean","title":"Is Valid"},"errors":{"items":{"$ref":"#/components/schemas/WorkflowError"},"type":"array","title":"Errors"}},"type":"object","required":["is_valid","errors"],"title":"ValidateWorkflowResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VobizConfigurationRequest":{"properties":{"provider":{"type":"string","const":"vobiz","title":"Provider","default":"vobiz"},"auth_id":{"type":"string","title":"Auth Id","description":"Vobiz Account ID (e.g., MA_SYQRLN1K)"},"auth_token":{"type":"string","title":"Auth Token","description":"Vobiz Auth Token"},"application_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Id","description":"Vobiz Application ID. The application's answer_url is updated when inbound workflows are attached to numbers on this account. If omitted, an application is auto-created on save and its id is stored on the configuration."},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of Vobiz phone numbers (E.164 without + prefix)"}},"type":"object","required":["auth_id","auth_token"],"title":"VobizConfigurationRequest","description":"Request schema for Vobiz configuration."},"VobizConfigurationResponse":{"properties":{"provider":{"type":"string","const":"vobiz","title":"Provider","default":"vobiz"},"auth_id":{"type":"string","title":"Auth Id"},"auth_token":{"type":"string","title":"Auth Token"},"application_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Id"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["auth_id","auth_token","from_numbers"],"title":"VobizConfigurationResponse","description":"Response schema for Vobiz configuration with masked sensitive fields."},"VoiceInfo":{"properties":{"voice_id":{"type":"string","title":"Voice Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"accent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accent"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"preview_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview Url"}},"type":"object","required":["voice_id","name"],"title":"VoiceInfo"},"VoicesResponse":{"properties":{"provider":{"type":"string","title":"Provider"},"voices":{"items":{"$ref":"#/components/schemas/VoiceInfo"},"type":"array","title":"Voices"}},"type":"object","required":["provider","voices"],"title":"VoicesResponse"},"VonageConfigurationRequest":{"properties":{"provider":{"type":"string","const":"vonage","title":"Provider","default":"vonage"},"api_key":{"type":"string","title":"Api Key","description":"Vonage API Key"},"api_secret":{"type":"string","title":"Api Secret","description":"Vonage API Secret"},"application_id":{"type":"string","title":"Application Id","description":"Vonage Application ID"},"private_key":{"type":"string","title":"Private Key","description":"Private key for JWT generation"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers","description":"List of Vonage phone numbers (without + prefix)"}},"type":"object","required":["api_key","api_secret","application_id","private_key"],"title":"VonageConfigurationRequest","description":"Request schema for Vonage configuration."},"VonageConfigurationResponse":{"properties":{"provider":{"type":"string","const":"vonage","title":"Provider","default":"vonage"},"application_id":{"type":"string","title":"Application Id"},"api_key":{"type":"string","title":"Api Key"},"api_secret":{"type":"string","title":"Api Secret"},"private_key":{"type":"string","title":"Private Key"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["application_id","api_key","api_secret","private_key","from_numbers"],"title":"VonageConfigurationResponse","description":"Response schema for Vonage configuration with masked sensitive fields."},"WebhookCredentialType":{"type":"string","enum":["none","api_key","bearer_token","basic_auth","custom_header"],"title":"WebhookCredentialType","description":"Webhook credential authentication types"},"WorkflowCountResponse":{"properties":{"total":{"type":"integer","title":"Total"},"active":{"type":"integer","title":"Active"},"archived":{"type":"integer","title":"Archived"}},"type":"object","required":["total","active","archived"],"title":"WorkflowCountResponse","description":"Response for workflow count endpoint."},"WorkflowError":{"properties":{"kind":{"$ref":"#/components/schemas/ItemKind"},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"field":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Field"},"message":{"type":"string","title":"Message"}},"type":"object","required":["kind","id","field","message"],"title":"WorkflowError"},"WorkflowListResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"total_runs":{"type":"integer","title":"Total Runs"},"folder_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Folder Id"},"workflow_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workflow Uuid"}},"type":"object","required":["id","name","status","created_at","total_runs"],"title":"WorkflowListResponse","description":"Lightweight response for workflow listings (excludes large fields)."},"WorkflowOption":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"WorkflowOption"},"WorkflowResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"workflow_definition":{"additionalProperties":true,"type":"object","title":"Workflow Definition"},"current_definition_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Current Definition Id"},"template_context_variables":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Template Context Variables"},"call_disposition_codes":{"anyOf":[{"$ref":"#/components/schemas/CallDispositionCodes"},{"type":"null"}]},"total_runs":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Runs"},"workflow_configurations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Workflow Configurations"},"version_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Version Number"},"version_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version Status"},"workflow_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workflow Uuid"}},"type":"object","required":["id","name","status","created_at","workflow_definition","current_definition_id"],"title":"WorkflowResponse"},"WorkflowRunDetail":{"properties":{"phone_number":{"type":"string","title":"Phone Number"},"disposition":{"type":"string","title":"Disposition"},"duration_seconds":{"type":"number","title":"Duration Seconds"},"workflow_id":{"type":"integer","title":"Workflow Id"},"run_id":{"type":"integer","title":"Run Id"},"workflow_name":{"type":"string","title":"Workflow Name"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["phone_number","disposition","duration_seconds","workflow_id","run_id","workflow_name","created_at"],"title":"WorkflowRunDetail"},"WorkflowRunResponseSchema":{"properties":{"id":{"type":"integer","title":"Id"},"workflow_id":{"type":"integer","title":"Workflow Id"},"name":{"type":"string","title":"Name"},"mode":{"type":"string","title":"Mode"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"is_completed":{"type":"boolean","title":"Is Completed"},"transcript_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript Url"},"recording_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recording Url"},"user_recording_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Recording Url"},"bot_recording_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bot Recording Url"},"transcript_public_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript Public Url"},"recording_public_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recording Public Url"},"user_recording_public_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Recording Public Url"},"bot_recording_public_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bot Recording Public Url"},"public_access_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Public Access Token"},"cost_info":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Cost Info"},"usage_info":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Usage Info"},"definition_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Definition Id"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"},"gathered_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Gathered Context"},"call_type":{"$ref":"#/components/schemas/CallType"},"logs":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Logs"},"annotations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Annotations"}},"type":"object","required":["id","workflow_id","name","mode","created_at","is_completed","transcript_url","recording_url","cost_info","definition_id","call_type"],"title":"WorkflowRunResponseSchema"},"WorkflowRunTextSessionResponse":{"properties":{"workflow_run_id":{"type":"integer","title":"Workflow Run Id"},"workflow_id":{"type":"integer","title":"Workflow Id"},"name":{"type":"string","title":"Name"},"mode":{"type":"string","title":"Mode"},"state":{"type":"string","title":"State"},"is_completed":{"type":"boolean","title":"Is Completed"},"revision":{"type":"integer","title":"Revision"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"},"gathered_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Gathered Context"},"annotations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Annotations"},"session_data":{"additionalProperties":true,"type":"object","title":"Session Data"},"checkpoint":{"additionalProperties":true,"type":"object","title":"Checkpoint"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["workflow_run_id","workflow_id","name","mode","state","is_completed","revision","session_data","checkpoint","created_at"],"title":"WorkflowRunTextSessionResponse"},"WorkflowRunUsageResponse":{"properties":{"id":{"type":"integer","title":"Id"},"workflow_id":{"type":"integer","title":"Workflow Id"},"workflow_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workflow Name"},"name":{"type":"string","title":"Name"},"created_at":{"type":"string","title":"Created At"},"dograh_token_usage":{"type":"number","title":"Dograh Token Usage"},"call_duration_seconds":{"type":"integer","title":"Call Duration Seconds"},"recording_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recording Url"},"transcript_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript Url"},"user_recording_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Recording Url"},"bot_recording_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bot Recording Url"},"recording_public_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recording Public Url"},"transcript_public_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript Public Url"},"user_recording_public_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Recording Public Url"},"bot_recording_public_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bot Recording Public Url"},"public_access_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Public Access Token"},"phone_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone Number","description":"Deprecated. Use caller_number and called_number instead.","deprecated":true},"caller_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Caller Number"},"called_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Called Number"},"call_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Call Type"},"mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mode"},"disposition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Disposition"},"initial_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Initial Context"},"gathered_context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Gathered Context"},"charge_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Charge Usd"}},"type":"object","required":["id","workflow_id","workflow_name","name","created_at","dograh_token_usage","call_duration_seconds"],"title":"WorkflowRunUsageResponse"},"WorkflowRunsResponse":{"properties":{"runs":{"items":{"$ref":"#/components/schemas/WorkflowRunResponseSchema"},"type":"array","title":"Runs"},"total_count":{"type":"integer","title":"Total Count"},"page":{"type":"integer","title":"Page"},"limit":{"type":"integer","title":"Limit"},"total_pages":{"type":"integer","title":"Total Pages"},"applied_filters":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Applied Filters"}},"type":"object","required":["runs","total_count","page","limit","total_pages"],"title":"WorkflowRunsResponse"},"WorkflowSummaryResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"WorkflowSummaryResponse"},"WorkflowTemplateResponse":{"properties":{"id":{"type":"integer","title":"Id"},"template_name":{"type":"string","title":"Template Name"},"template_description":{"type":"string","title":"Template Description"},"template_json":{"additionalProperties":true,"type":"object","title":"Template Json"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","template_name","template_description","template_json","created_at"],"title":"WorkflowTemplateResponse"},"WorkflowVersionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"version_number":{"type":"integer","title":"Version Number"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"workflow_json":{"additionalProperties":true,"type":"object","title":"Workflow Json"},"workflow_configurations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Workflow Configurations"},"template_context_variables":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Template Context Variables"}},"type":"object","required":["id","version_number","status","created_at","workflow_json"],"title":"WorkflowVersionResponse"}}}} \ No newline at end of file diff --git a/docs/contribution/setup.mdx b/docs/contribution/setup.mdx index a2ed2495..beb7f8de 100644 --- a/docs/contribution/setup.mdx +++ b/docs/contribution/setup.mdx @@ -6,6 +6,23 @@ description: Set up the Dograh contributor environment with the devcontainer-fir If the steps below do not work for you, please open an issue on [GitHub](https://github.com/dograh-hq/dograh/issues). + +**Using Claude Code or Codex?** Install the official Dograh setup skill and let your agent walk you through the contributor setup — it covers both the devcontainer and host-managed paths, runs Dograh's own scripts, and verifies the stack is healthy. + + +```text Claude Code +/plugin marketplace add dograh-hq/dograh-plugins +/plugin install dograh@dograh +``` +```text Codex +codex plugin marketplace add dograh-hq/dograh-plugins +codex plugin add dograh@dograh +``` + + +Start a new session, then ask it to *"set up Dograh for development"* (or run `/dograh-setup develop` in Claude Code). More at [dograh-hq/dograh-plugins](https://github.com/dograh-hq/dograh-plugins). + + ### Recommended: Devcontainer Setup #### System Requirements diff --git a/docs/deployment/docker.mdx b/docs/deployment/docker.mdx index 28a6a8ba..04934e50 100644 --- a/docs/deployment/docker.mdx +++ b/docs/deployment/docker.mdx @@ -8,6 +8,23 @@ Dograh AI can be deployed using Docker in two main configurations. Choose the op - **Option 1**: For local development and testing on your own machine - **Option 2**: For remote server deployment with HTTPS (using IP address). If you also have a custom domain, you can first deploy Dograh stack on your server using steps in this document and then proceed to the [Custom Domain](deployment/custom-domain) section. + +**Using Claude Code or Codex?** Install the official Dograh setup skill and let your agent drive either deployment below — it orients to your OS, picks local vs remote, runs Dograh's own setup scripts, and verifies the result with a built-in health check. + + +```text Claude Code +/plugin marketplace add dograh-hq/dograh-plugins +/plugin install dograh@dograh +``` +```text Codex +codex plugin marketplace add dograh-hq/dograh-plugins +codex plugin add dograh@dograh +``` + + +Start a new session, then ask it to *"set up Dograh"* (or run `/dograh-setup` in Claude Code). More at [dograh-hq/dograh-plugins](https://github.com/dograh-hq/dograh-plugins). + + ## Option 1: Local Docker Deployment Watch the video tutorial below for a step-by-step walkthrough of setting up Dograh AI locally with Docker. diff --git a/docs/getting-started/index.mdx b/docs/getting-started/index.mdx index 09252089..cba5988c 100644 --- a/docs/getting-started/index.mdx +++ b/docs/getting-started/index.mdx @@ -39,6 +39,23 @@ Invoke-WebRequest -OutFile start_docker.ps1 https://raw.githubusercontent.com/do ``` + +**Using an AI coding agent?** If you work in **Claude Code** or **Codex**, install the official Dograh setup skill and let your agent handle installation, configuration, and troubleshooting for you. It orients to your OS, picks the right deploy path, runs Dograh's own setup scripts, and verifies the result. Install it once: + + +```text Claude Code +/plugin marketplace add dograh-hq/dograh-plugins +/plugin install dograh@dograh +``` +```text Codex +codex plugin marketplace add dograh-hq/dograh-plugins +codex plugin add dograh@dograh +``` + + +Then start a new session and ask it to *"set up Dograh"* (in Claude Code you can also run `/dograh-setup`). See [dograh-hq/dograh-plugins](https://github.com/dograh-hq/dograh-plugins) for details. + + Please check [Prerequisites](getting-started/prerequisites) for the system requirements and [Troubleshooting](getting-started/troubleshooting) for common issues. ## Next Steps diff --git a/pipecat b/pipecat index 0d64dc6e..7992b834 160000 --- a/pipecat +++ b/pipecat @@ -1 +1 @@ -Subproject commit 0d64dc6e0e3e6b3c46cc66373e34b4f54f980268 +Subproject commit 7992b83484da402f45816bb3555cd50ceeb0ec1a diff --git a/sdk/python/src/dograh_sdk/_generated_models.py b/sdk/python/src/dograh_sdk/_generated_models.py index b2f99daf..10bceb97 100644 --- a/sdk/python/src/dograh_sdk/_generated_models.py +++ b/sdk/python/src/dograh_sdk/_generated_models.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: -# filename: dograh-openapi-XXXXXX.json.w5T4z8AeiH -# timestamp: 2026-06-12T16:16:24+00:00 +# filename: dograh-openapi-XXXXXX.json.lMzKvoOMbD +# timestamp: 2026-06-17T13:44:53+00:00 from __future__ import annotations diff --git a/sdk/python/src/dograh_sdk/typed/webhook.py b/sdk/python/src/dograh_sdk/typed/webhook.py index 305c0e46..0d1f0ba6 100644 --- a/sdk/python/src/dograh_sdk/typed/webhook.py +++ b/sdk/python/src/dograh_sdk/typed/webhook.py @@ -69,7 +69,7 @@ class Webhook(TypedNode): Additional HTTP headers to include with the request. """ - payload_template: dict[str, Any] = field(default_factory=lambda: {'call_id': '{{workflow_run_id}}', 'first_name': '{{initial_context.first_name}}', 'rsvp': '{{gathered_context.rsvp}}', 'duration': '{{cost_info.call_duration_seconds}}', 'recording_url': '{{recording_url}}', 'transcript_url': '{{transcript_url}}'}) + payload_template: dict[str, Any] = field(default_factory=lambda: {'call_id': '{{workflow_run_id}}', 'first_name': '{{initial_context.first_name}}', 'rsvp': '{{gathered_context.rsvp}}', 'duration': '{{cost_info.call_duration_seconds}}', 'recording_url': '{{recording_url}}', 'user_recording_url': '{{user_recording_url}}', 'bot_recording_url': '{{bot_recording_url}}', 'transcript_url': '{{transcript_url}}'}) """ JSON body of the request. Values are Jinja-rendered against the run context — `{{workflow_run_id}}`, `{{gathered_context.foo}}`, diff --git a/ui/public/embed/dograh-widget.js b/ui/public/embed/dograh-widget.js index 9a266208..741cf189 100644 --- a/ui/public/embed/dograh-widget.js +++ b/ui/public/embed/dograh-widget.js @@ -26,10 +26,12 @@ stream: null, sessionToken: null, workflowRunId: null, + pcId: null, connectionStatus: 'idle', // idle, connecting, connected, failed audioElement: null, turnCredentials: null, // TURN server credentials callStartedAt: null, // Timestamp when call connected (for duration tracking) + gracefulDisconnect: false, callbacks: { onReady: null, onCallStart: null, @@ -611,6 +613,7 @@ * Start voice call */ async function startCall() { + state.gracefulDisconnect = false; updateStatus('connecting', 'Connecting...', 'Please wait while we establish the connection'); if (state.callbacks.onCallStart) { @@ -766,45 +769,69 @@ }; // Monitor connection state - state.pc.oniceconnectionstatechange = () => { - console.log('ICE connection state:', state.pc.iceConnectionState); + state.pc.oniceconnectionstatechange = handlePeerConnectionStateChange; + state.pc.onconnectionstatechange = handlePeerConnectionStateChange; + state.pc.onicecandidate = sendIceCandidate; + } - if (state.pc.iceConnectionState === 'connected' || state.pc.iceConnectionState === 'completed') { - const wasAlreadyConnected = state.callStartedAt !== null; - updateStatus('connected', 'Connected', 'Your voice call is now active'); - if (!wasAlreadyConnected) { - state.callStartedAt = Date.now(); - if (state.callbacks.onCallConnected) { - state.callbacks.onCallConnected({ - agentId: state.config.workflowId || null, - token: state.config.token || null, - workflowRunId: state.workflowRunId || null - }); - } + function handlePeerConnectionStateChange() { + const pc = state.pc; + if (!pc) return; + + console.log('Peer connection state:', pc.connectionState, 'ICE:', pc.iceConnectionState); + + if (pc.connectionState === 'connected' || pc.iceConnectionState === 'connected' || pc.iceConnectionState === 'completed') { + const wasAlreadyConnected = state.callStartedAt !== null; + updateStatus('connected', 'Connected', 'Your voice call is now active'); + if (!wasAlreadyConnected) { + state.callStartedAt = Date.now(); + if (state.callbacks.onCallConnected) { + state.callbacks.onCallConnected({ + agentId: state.config.workflowId || null, + token: state.config.token || null, + workflowRunId: state.workflowRunId || null + }); } - } else if (state.pc.iceConnectionState === 'failed' || state.pc.iceConnectionState === 'disconnected') { - updateStatus('failed', 'Connection lost', 'The call has been disconnected'); - stopCall(); } - }; + return; + } + if (pc.connectionState === 'failed' || pc.iceConnectionState === 'failed') { + stopCall({ + graceful: false, + status: 'failed', + text: 'Connection lost', + subtext: 'The call has been disconnected' + }); + return; + } + + if ( + pc.connectionState === 'closed' || + pc.connectionState === 'disconnected' || + pc.iceConnectionState === 'closed' || + pc.iceConnectionState === 'disconnected' + ) { + stopCall({ graceful: true }); + } + } + + function sendIceCandidate(event) { // Handle ICE candidates for trickling - state.pc.onicecandidate = (event) => { - if (state.ws && state.ws.readyState === WebSocket.OPEN) { - const message = { - type: 'ice-candidate', - payload: { - candidate: event.candidate ? { - candidate: event.candidate.candidate, - sdpMid: event.candidate.sdpMid, - sdpMLineIndex: event.candidate.sdpMLineIndex - } : null, - pc_id: state.pcId - } - }; - state.ws.send(JSON.stringify(message)); - } - }; + if (state.ws && state.ws.readyState === WebSocket.OPEN) { + const message = { + type: 'ice-candidate', + payload: { + candidate: event.candidate ? { + candidate: event.candidate.candidate, + sdpMid: event.candidate.sdpMid, + sdpMLineIndex: event.candidate.sdpMLineIndex + } : null, + pc_id: state.pcId + } + }; + state.ws.send(JSON.stringify(message)); + } } /** @@ -828,9 +855,16 @@ reject(error); }; - state.ws.onclose = () => { + state.ws.onclose = (event) => { console.log('WebSocket closed'); - if (state.connectionStatus === 'connected') { + state.ws = null; + + if (event.reason === 'call ended') { + stopCall({ graceful: true, closeWebSocket: false }); + return; + } + + if (state.connectionStatus === 'connected' && !state.gracefulDisconnect) { updateStatus('failed', 'Connection lost', 'The call has been disconnected'); } }; @@ -882,6 +916,11 @@ updateStatus('failed', 'Server error', message.payload.message || 'An error occurred'); break; + case 'call-ended': + console.log('Call ended by server:', message.payload); + stopCall({ graceful: true }); + break; + default: console.warn('Unknown message type:', message.type); } @@ -913,7 +952,15 @@ /** * Stop voice call */ - function stopCall() { + function stopCall(options = {}) { + const graceful = options.graceful !== false; + const closeWebSocket = options.closeWebSocket !== false; + const status = options.status || 'idle'; + const text = options.text || 'Call ended'; + const subtext = options.subtext || 'Click below to start a new call'; + + state.gracefulDisconnect = graceful; + // Fire onCallDisconnected only if the call had actually connected, with // identifiers and duration. Must run before we clear callStartedAt. if (state.callStartedAt && state.callbacks.onCallDisconnected) { @@ -927,15 +974,20 @@ } state.callStartedAt = null; - updateStatus('idle', 'Call ended', 'Click below to start a new call'); + updateStatus(status, text, subtext); if (state.callbacks.onCallEnd) { state.callbacks.onCallEnd(); } // Close WebSocket - if (state.ws) { - state.ws.close(); + if (closeWebSocket && state.ws) { + const ws = state.ws; + state.ws = null; + if (ws.readyState !== WebSocket.CLOSED && ws.readyState !== WebSocket.CLOSING) { + ws.close(); + } + } else if (!closeWebSocket) { state.ws = null; } @@ -947,8 +999,11 @@ // Close peer connection if (state.pc) { - state.pc.close(); + const pc = state.pc; state.pc = null; + if (pc.signalingState !== 'closed') { + pc.close(); + } } // Clear audio diff --git a/ui/src/app/billing/page.tsx b/ui/src/app/billing/page.tsx index 0a9732c9..9ac8a497 100644 --- a/ui/src/app/billing/page.tsx +++ b/ui/src/app/billing/page.tsx @@ -5,6 +5,8 @@ import { ChevronRight, CircleDollarSign, CreditCard, + ExternalLink, + Info, RefreshCw, } from "lucide-react"; import Link from "next/link"; @@ -124,7 +126,8 @@ export default function BillingPage() { ); const isBillingV2 = credits?.billing_version === "v2"; - const canPurchaseCredits = isBillingV2 && config?.deploymentMode !== "oss"; + const isOssMode = config?.deploymentMode === "oss"; + const canPurchaseCredits = isBillingV2 && !isOssMode; const totalQuota = credits?.total_quota ?? 0; const remainingCredits = credits?.remaining_credits ?? 0; const usedCredits = credits?.total_credits_used ?? 0; @@ -265,6 +268,36 @@ export default function BillingPage() { + {isOssMode && ( +
+ +
+

Credit purchases are unavailable in OSS mode

+

+ You can't purchase credits from this self-hosted app. Sign up and + purchase credits at{" "} + + app.dograh.com + + + . Then add the generated service key in{" "} + + Model Configurations + + . Usage for that service key is visible in app.dograh.com. +

+
+
+ )} +
diff --git a/ui/src/app/workflow/[workflowId]/run/[runId]/hooks/useWebSocketRTC.tsx b/ui/src/app/workflow/[workflowId]/run/[runId]/hooks/useWebSocketRTC.tsx index 2aaf65c7..3a7ee3ee 100644 --- a/ui/src/app/workflow/[workflowId]/run/[runId]/hooks/useWebSocketRTC.tsx +++ b/ui/src/app/workflow/[workflowId]/run/[runId]/hooks/useWebSocketRTC.tsx @@ -19,6 +19,16 @@ interface UseWebSocketRTCProps { onNodeTransition?: (transition: ConversationNodeTransitionItem) => void; } +type ConnectionStatus = 'idle' | 'connecting' | 'connected' | 'failed'; + +interface CleanupConnectionOptions { + graceful?: boolean; + status?: ConnectionStatus; + closeWebSocket?: boolean; + closePeerConnection?: boolean; + delayPeerClose?: boolean; +} + const HANDLED_SERVICE_ERROR_TYPES = new Set([ 'quota_exceeded', 'insufficient_credits', @@ -27,7 +37,7 @@ const HANDLED_SERVICE_ERROR_TYPES = new Set([ ]); export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initialContextVariables, onNodeTransition }: UseWebSocketRTCProps) => { - const [connectionStatus, setConnectionStatus] = useState<'idle' | 'connecting' | 'connected' | 'failed'>('idle'); + const [connectionStatus, setConnectionStatus] = useState('idle'); const [connectionActive, setConnectionActive] = useState(false); const [isCompleted, setIsCompleted] = useState(false); const [apiKeyModalOpen, setApiKeyModalOpen] = useState(false); @@ -62,11 +72,22 @@ export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initia const wsRef = useRef(null); const timeStartRef = useRef(null); const onNodeTransitionRef = useRef(onNodeTransition); + const connectionActiveRef = useRef(connectionActive); + const isCompletedRef = useRef(isCompleted); + const gracefulDisconnectRef = useRef(false); useEffect(() => { onNodeTransitionRef.current = onNodeTransition; }, [onNodeTransition]); + useEffect(() => { + connectionActiveRef.current = connectionActive; + }, [connectionActive]); + + useEffect(() => { + isCompletedRef.current = isCompleted; + }, [isCompleted]); + // Generate a cryptographically secure unique ID const generateSecureId = () => { // Use Web Crypto API to generate random bytes @@ -95,6 +116,68 @@ export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initia return `${wsUrl}/api/v1/ws/signaling/${workflowId}/${workflowRunId}?token=${accessToken}`; }, [workflowId, workflowRunId, accessToken]); + const closePeerConnection = useCallback((pc: RTCPeerConnection | null, delayClose = false) => { + if (!pc) return; + + if (pc.getTransceivers) { + pc.getTransceivers().forEach((transceiver) => { + if (transceiver.stop) { + try { + transceiver.stop(); + } catch (e) { + logger.debug('Failed to stop transceiver during cleanup:', e); + } + } + }); + } + + pc.getSenders().forEach((sender) => { + if (sender.track) { + sender.track.stop(); + } + }); + + const close = () => { + if (pcRef.current === pc) { + pcRef.current = null; + } + if (pc.signalingState !== 'closed') { + pc.close(); + } + }; + + if (delayClose) { + setTimeout(close, 500); + } else { + close(); + } + }, []); + + const cleanupConnection = useCallback((options: CleanupConnectionOptions = {}) => { + const graceful = options.graceful ?? true; + const status = options.status ?? (graceful ? 'idle' : 'failed'); + + gracefulDisconnectRef.current = graceful; + connectionActiveRef.current = false; + isCompletedRef.current = graceful; + + setConnectionActive(false); + setIsCompleted(graceful); + setConnectionStatus(status); + + if (options.closeWebSocket !== false) { + const ws = wsRef.current; + if (ws && ws.readyState !== WebSocket.CLOSED && ws.readyState !== WebSocket.CLOSING) { + ws.close(); + } + wsRef.current = null; + } + + if (options.closePeerConnection !== false) { + closePeerConnection(pcRef.current, options.delayPeerClose ?? false); + } + }, [closePeerConnection]); + const createPeerConnection = () => { // Build ICE servers list const iceServers: RTCIceServer[] = []; @@ -155,43 +238,36 @@ export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initia } }); - pc.addEventListener('iceconnectionstatechange', () => { - logger.info(`ICE connection state changed: ${pc.iceConnectionState}`); - if (pc.iceConnectionState === 'connected' || pc.iceConnectionState === 'completed') { + const handlePeerStateChange = () => { + logger.info(`Peer connection state changed: ${pc.connectionState}; ICE: ${pc.iceConnectionState}`); + + if ( + pc.connectionState === 'connected' || + pc.iceConnectionState === 'connected' || + pc.iceConnectionState === 'completed' + ) { setConnectionStatus('connected'); - } else if (pc.iceConnectionState === 'failed') { - setConnectionStatus('failed'); - } else if (pc.iceConnectionState === 'disconnected') { - // Server-initiated disconnect - clean up gracefully - logger.info('Server initiated disconnect - cleaning up connection'); - - // Close WebSocket if still open - if (wsRef.current) { - wsRef.current.close(); - wsRef.current = null; - } - - // Mark as completed to trigger recording check - setConnectionActive(false); - setIsCompleted(true); - setConnectionStatus('idle'); - - // Clean up peer connection - if (pc.getTransceivers) { - pc.getTransceivers().forEach((transceiver) => { - if (transceiver.stop) { - transceiver.stop(); - } - }); - } - - pc.getSenders().forEach((sender) => { - if (sender.track) { - sender.track.stop(); - } - }); + return; } - }); + + if (pc.connectionState === 'failed' || pc.iceConnectionState === 'failed') { + cleanupConnection({ graceful: false, status: 'failed' }); + return; + } + + if ( + pc.connectionState === 'closed' || + pc.connectionState === 'disconnected' || + pc.iceConnectionState === 'closed' || + pc.iceConnectionState === 'disconnected' + ) { + logger.info('Peer connection ended - cleaning up connection'); + cleanupConnection({ graceful: true, status: 'idle' }); + } + }; + + pc.addEventListener('iceconnectionstatechange', handlePeerStateChange); + pc.addEventListener('connectionstatechange', handlePeerStateChange); pc.addEventListener('track', (evt) => { if (evt.track.kind === 'audio' && audioRef.current) { @@ -221,11 +297,23 @@ export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initia reject(error); }; - ws.onclose = () => { + ws.onclose = (event) => { logger.info('WebSocket closed'); wsRef.current = null; + if (event.reason === 'call ended') { + cleanupConnection({ + graceful: true, + status: 'idle', + closeWebSocket: false, + }); + return; + } // Don't set failed status if already completed (graceful disconnect) - if (connectionActive && !isCompleted) { + if ( + connectionActiveRef.current && + !isCompletedRef.current && + !gracefulDisconnectRef.current + ) { setConnectionStatus('failed'); } }; @@ -245,6 +333,7 @@ export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initia type: 'answer', sdp: answer.sdp }); + connectionActiveRef.current = true; setConnectionActive(true); logger.info('Remote description set'); } @@ -281,25 +370,19 @@ export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initia setApiKeyError(message.payload.message || 'Service quota exceeded'); setApiKeyModalOpen(true); - // Stop the connection gracefully - setConnectionStatus('failed'); - setConnectionActive(false); - - // Close WebSocket and peer connection - if (wsRef.current) { - wsRef.current.close(); - wsRef.current = null; - } - if (pcRef.current) { - pcRef.current.close(); - pcRef.current = null; - } + // Stop the connection and surface the handled service error. + cleanupConnection({ graceful: false, status: 'failed' }); } else { // Log other errors as actual errors logger.error('Server error:', message.payload); } break; + case 'call-ended': + logger.info('Call ended by server:', message.payload); + cleanupConnection({ graceful: true, status: 'idle' }); + break; + case 'rtf-user-transcription': { const transcription = message.payload; @@ -503,7 +586,7 @@ export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initia } }; }); - }, [getWebSocketUrl, connectionActive, isCompleted]); + }, [getWebSocketUrl, cleanupConnection]); const negotiate = async () => { const pc = pcRef.current; @@ -552,7 +635,12 @@ export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initia const start = async () => { if (isStarting || !accessToken) return; + gracefulDisconnectRef.current = false; + connectionActiveRef.current = false; + isCompletedRef.current = false; setIsStarting(true); + setConnectionActive(false); + setIsCompleted(false); setConnectionStatus('connecting'); try { @@ -676,40 +764,7 @@ export const useWebSocketRTC = ({ workflowId, workflowRunId, accessToken, initia }; const stop = () => { - setConnectionActive(false); - setIsCompleted(true); - setConnectionStatus('idle'); - - // Close WebSocket - if (wsRef.current) { - wsRef.current.close(); - wsRef.current = null; - } - - // Close peer connection - const pc = pcRef.current; - if (!pc) return; - - if (pc.getTransceivers) { - pc.getTransceivers().forEach((transceiver) => { - if (transceiver.stop) { - transceiver.stop(); - } - }); - } - - pc.getSenders().forEach((sender) => { - if (sender.track) { - sender.track.stop(); - } - }); - - setTimeout(() => { - if (pcRef.current) { - pcRef.current.close(); - pcRef.current = null; - } - }, 500); + cleanupConnection({ graceful: true, status: 'idle', delayPeerClose: true }); }; // Cleanup on unmount diff --git a/ui/src/app/workflow/[workflowId]/run/[runId]/page.tsx b/ui/src/app/workflow/[workflowId]/run/[runId]/page.tsx index 7537dad9..3362e1ab 100644 --- a/ui/src/app/workflow/[workflowId]/run/[runId]/page.tsx +++ b/ui/src/app/workflow/[workflowId]/run/[runId]/page.tsx @@ -1,6 +1,18 @@ 'use client'; -import { Check, Copy, ExternalLink, FileText, Video } from 'lucide-react'; +import { + Bot, + Check, + Copy, + Download, + ExternalLink, + FileText, + Loader2, + Pause, + Play, + UserRound, + Video, +} from 'lucide-react'; import Link from 'next/link'; import { useParams } from 'next/navigation'; import posthog from 'posthog-js'; @@ -18,13 +30,16 @@ import { PostHogEvent } from '@/constants/posthog-events'; import { WORKFLOW_RUN_MODES } from '@/constants/workflowRunModes'; import { useOnboarding } from '@/context/OnboardingContext'; import { useAuth } from '@/lib/auth'; -import { downloadFile } from '@/lib/files'; +import { downloadFile, getSignedUrl } from '@/lib/files'; +import { cn } from '@/lib/utils'; interface WorkflowRunResponse { mode: string; is_completed: boolean; transcript_url: string | null; recording_url: string | null; + user_recording_url: string | null; + bot_recording_url: string | null; cost_info: { dograh_token_usage?: number | null; call_duration_seconds?: number | null; @@ -36,6 +51,7 @@ interface WorkflowRunResponse { } const RUN_SHELL_HEIGHT_CLASS = "h-[calc(100svh-49px)] min-h-[calc(100svh-49px)] max-h-[calc(100svh-49px)]"; +const WAVEFORM_BAR_COUNT = 96; function formatDuration(seconds?: number | null) { if (seconds == null || Number.isNaN(seconds)) return 'N/A'; @@ -71,6 +87,309 @@ function MetricCard({ label, value }: { label: string; value: string }) { ); } +function buildWaveformPeaks(audioBuffer: AudioBuffer) { + const channel = audioBuffer.getChannelData(0); + const samplesPerBar = Math.max(1, Math.floor(channel.length / WAVEFORM_BAR_COUNT)); + + return Array.from({ length: WAVEFORM_BAR_COUNT }, (_, index) => { + const start = index * samplesPerBar; + const end = Math.min(start + samplesPerBar, channel.length); + let sum = 0; + + for (let i = start; i < end; i += 1) { + sum += channel[i] * channel[i]; + } + + const rms = Math.sqrt(sum / Math.max(1, end - start)); + return Math.max(0.08, Math.min(1, rms * 5)); + }); +} + +async function loadWaveformPeaks(url: string) { + const response = await fetch(url); + const audioData = await response.arrayBuffer(); + const AudioContextConstructor = + window.AudioContext || + (window as typeof window & { webkitAudioContext?: typeof AudioContext }) + .webkitAudioContext; + + if (!AudioContextConstructor) return null; + + const audioContext = new AudioContextConstructor(); + try { + const decoded = await audioContext.decodeAudioData(audioData); + return buildWaveformPeaks(decoded); + } finally { + void audioContext.close(); + } +} + +function WaveformLane({ + peaks, + track, + position, +}: { + peaks: number[] | null; + track: 'user' | 'bot'; + position: 'top' | 'bottom'; +}) { + return ( +
+ {peaks ? ( + peaks.map((peak, index) => ( + + )) + ) : ( +
+ )} +
+ ); +} + +function SplitTracksSection({ + userRecordingUrl, + botRecordingUrl, +}: { + userRecordingUrl: string; + botRecordingUrl: string; +}) { + const userAudioRef = useRef(null); + const botAudioRef = useRef(null); + const [signedUrls, setSignedUrls] = useState<{ user: string | null; bot: string | null }>({ + user: null, + bot: null, + }); + const [peaks, setPeaks] = useState<{ user: number[] | null; bot: number[] | null }>({ + user: null, + bot: null, + }); + const [isLoading, setIsLoading] = useState(false); + const [isPlaying, setIsPlaying] = useState(false); + const [progress, setProgress] = useState(0); + + useEffect(() => { + let isActive = true; + const userAudio = userAudioRef.current; + const botAudio = botAudioRef.current; + + userAudio?.pause(); + botAudio?.pause(); + setSignedUrls({ user: null, bot: null }); + setPeaks({ user: null, bot: null }); + setIsPlaying(false); + setProgress(0); + setIsLoading(true); + + async function loadTracks() { + try { + const [userUrl, botUrl] = await Promise.all([ + getSignedUrl(userRecordingUrl, true), + getSignedUrl(botRecordingUrl, true), + ]); + if (!isActive) return; + + setSignedUrls({ user: userUrl, bot: botUrl }); + if (!userUrl || !botUrl) return; + + const [userPeaks, botPeaks] = await Promise.all([ + loadWaveformPeaks(userUrl), + loadWaveformPeaks(botUrl), + ]); + + if (isActive) { + setPeaks({ user: userPeaks, bot: botPeaks }); + } + } catch (error) { + console.error('Error loading split track waveforms:', error); + } finally { + if (isActive) { + setIsLoading(false); + } + } + } + + void loadTracks(); + + return () => { + isActive = false; + userAudio?.pause(); + botAudio?.pause(); + }; + }, [userRecordingUrl, botRecordingUrl]); + + useEffect(() => { + if (!isPlaying) return; + + let frameId: number; + const updateProgress = () => { + const userAudio = userAudioRef.current; + const botAudio = botAudioRef.current; + const userDuration = Number.isFinite(userAudio?.duration) ? userAudio?.duration ?? 0 : 0; + const botDuration = Number.isFinite(botAudio?.duration) ? botAudio?.duration ?? 0 : 0; + const duration = Math.max(userDuration, botDuration); + const currentTime = Math.max(userAudio?.currentTime ?? 0, botAudio?.currentTime ?? 0); + + setProgress(duration > 0 ? Math.min(1, currentTime / duration) : 0); + frameId = window.requestAnimationFrame(updateProgress); + }; + + frameId = window.requestAnimationFrame(updateProgress); + return () => window.cancelAnimationFrame(frameId); + }, [isPlaying]); + + const pauseTracks = () => { + userAudioRef.current?.pause(); + botAudioRef.current?.pause(); + setIsPlaying(false); + }; + + const handleTrackEnded = () => { + const userAudio = userAudioRef.current; + const botAudio = botAudioRef.current; + const userDone = !userAudio || userAudio.ended; + const botDone = !botAudio || botAudio.ended; + + if (userDone && botDone) { + setIsPlaying(false); + setProgress(1); + } + }; + + const togglePlayback = async () => { + const userAudio = userAudioRef.current; + const botAudio = botAudioRef.current; + if (!userAudio || !botAudio || !signedUrls.user || !signedUrls.bot) return; + + if (isPlaying) { + pauseTracks(); + return; + } + + const userDuration = Number.isFinite(userAudio.duration) ? userAudio.duration : 0; + const botDuration = Number.isFinite(botAudio.duration) ? botAudio.duration : 0; + const duration = Math.max(userDuration, botDuration); + const currentTime = Math.max(userAudio.currentTime, botAudio.currentTime); + const startTime = duration > 0 && currentTime >= duration - 0.1 ? 0 : currentTime; + + userAudio.currentTime = Math.min(startTime, userDuration || startTime); + botAudio.currentTime = Math.min(startTime, botDuration || startTime); + + try { + await Promise.all([userAudio.play(), botAudio.play()]); + setIsPlaying(true); + } catch (error) { + pauseTracks(); + console.error('Error playing split tracks:', error); + } + }; + + const canPlay = Boolean(signedUrls.user && signedUrls.bot); + const progressPercent = Math.round(progress * 1000) / 10; + + return ( + +