diff --git a/api/app.py b/api/app.py
index a0dacd3..735de66 100644
--- a/api/app.py
+++ b/api/app.py
@@ -49,6 +49,10 @@ app = FastAPI(
version="1.0.0",
openapi_url=f"{API_PREFIX}/openapi.json",
lifespan=lifespan,
+ servers=[
+ {"url": "https://app.dograh.com", "description": "Production"},
+ {"url": "http://localhost:8000", "description": "Local development"},
+ ],
)
diff --git a/docs/api-reference/agents.mdx b/docs/api-reference/agents.mdx
new file mode 100644
index 0000000..12ca527
--- /dev/null
+++ b/docs/api-reference/agents.mdx
@@ -0,0 +1,20 @@
+---
+title: "Overview"
+description: "Create and manage voice agents (workflows) via the API"
+---
+
+In Dograh, a **voice agent** is called a **workflow** in the API. A workflow defines the conversation flow, LLM configuration, voice settings, and tools available to your agent.
+
+| Method | Endpoint | Quick Link |
+|---|---|---|
+| `POST` | `/workflow/create/definition` | [Create from definition](/api-reference/agents/create-from-definition) |
+| `POST` | `/workflow/create/template` | [Create from template](/api-reference/agents/create-from-template) |
+| `GET` | `/workflow/fetch` | [List agents](/api-reference/agents/list) |
+| `GET` | `/workflow/count` | [Get agent count](/api-reference/agents/count) |
+| `GET` | `/workflow/fetch/{workflow_id}` | [Get an agent](/api-reference/agents/get) |
+| `PUT` | `/workflow/{workflow_id}` | [Update an agent](/api-reference/agents/update) |
+| `PUT` | `/workflow/{workflow_id}/status` | [Archive an agent](/api-reference/agents/archive) |
+| `POST` | `/workflow/{workflow_id}/validate` | [Validate a workflow](/api-reference/agents/validate) |
+| `POST` | `/workflow/{workflow_id}/runs` | [Create test run](/api-reference/agents/runs/create) |
+| `GET` | `/workflow/{workflow_id}/runs` | [List runs](/api-reference/agents/runs/list) |
+| `GET` | `/workflow/{workflow_id}/runs/{run_id}` | [Get a run](/api-reference/agents/runs/get) |
diff --git a/docs/api-reference/agents/archive.mdx b/docs/api-reference/agents/archive.mdx
new file mode 100644
index 0000000..7291e8f
--- /dev/null
+++ b/docs/api-reference/agents/archive.mdx
@@ -0,0 +1,7 @@
+---
+title: "Archive Agent"
+description: "Archive or restore a voice agent"
+openapi: "PUT /api/v1/workflow/{workflow_id}/status"
+---
+
+Send `{"status": "archived"}` to deactivate an agent, or `{"status": "active"}` to restore it. Archived agents cannot receive calls but their history and definition are preserved.
diff --git a/docs/api-reference/agents/count.mdx b/docs/api-reference/agents/count.mdx
new file mode 100644
index 0000000..afadfdb
--- /dev/null
+++ b/docs/api-reference/agents/count.mdx
@@ -0,0 +1,15 @@
+---
+title: "Get Agent Count"
+description: "Get the total number of agents broken down by status"
+openapi: "GET /api/v1/workflow/count"
+---
+
+Returns totals broken down by status — useful for dashboards or quota checks.
+
+```json
+{
+ "total": 5,
+ "active": 4,
+ "archived": 1
+}
+```
diff --git a/docs/api-reference/agents/create-from-definition.mdx b/docs/api-reference/agents/create-from-definition.mdx
new file mode 100644
index 0000000..084a10d
--- /dev/null
+++ b/docs/api-reference/agents/create-from-definition.mdx
@@ -0,0 +1,9 @@
+---
+title: "Create from Definition"
+description: "Create a voice agent from an explicit workflow definition"
+openapi: "POST /api/v1/workflow/create/definition"
+---
+
+Creates an agent from a node and edge graph you provide directly. Use this when you want full control over the workflow structure, or when programmatically generating agents.
+
+The `workflow_definition` object contains `nodes` (the steps in the conversation) and `edges` (transitions between steps). See [Editing a Workflow](/voice-agent/editing-a-workflow) for the full schema.
diff --git a/docs/api-reference/agents/create-from-template.mdx b/docs/api-reference/agents/create-from-template.mdx
new file mode 100644
index 0000000..f96ac68
--- /dev/null
+++ b/docs/api-reference/agents/create-from-template.mdx
@@ -0,0 +1,9 @@
+---
+title: "Create from Template"
+description: "Generate a voice agent from a natural language description"
+openapi: "POST /api/v1/workflow/create/template"
+---
+
+Dograh uses an LLM to generate the initial workflow definition from your description. The result is a fully editable agent — use [Update](/api-reference/agents/update) to refine it after creation.
+
+This is the fastest way to get a working agent, especially for common use cases like appointment booking, lead qualification, or customer support.
diff --git a/docs/api-reference/agents/get.mdx b/docs/api-reference/agents/get.mdx
new file mode 100644
index 0000000..3d94b03
--- /dev/null
+++ b/docs/api-reference/agents/get.mdx
@@ -0,0 +1,7 @@
+---
+title: "Get Agent"
+description: "Retrieve a single agent by ID, including its full workflow definition"
+openapi: "GET /api/v1/workflow/fetch/{workflow_id}"
+---
+
+Returns the full agent including `workflow_definition` (nodes and edges), `template_context_variables`, `workflow_configurations`, and run statistics.
diff --git a/docs/api-reference/agents/list.mdx b/docs/api-reference/agents/list.mdx
new file mode 100644
index 0000000..0b4f4c2
--- /dev/null
+++ b/docs/api-reference/agents/list.mdx
@@ -0,0 +1,7 @@
+---
+title: "List Agents"
+description: "Retrieve all agents in your organization"
+openapi: "GET /api/v1/workflow/fetch"
+---
+
+Returns all agents (workflows) in your organization, including both active and archived. Each item includes summary fields — use [Get an agent](/api-reference/agents/get) to retrieve the full workflow definition.
diff --git a/docs/api-reference/agents/runs/create.mdx b/docs/api-reference/agents/runs/create.mdx
new file mode 100644
index 0000000..abba3a6
--- /dev/null
+++ b/docs/api-reference/agents/runs/create.mdx
@@ -0,0 +1,7 @@
+---
+title: "Create Test Run"
+description: "Execute a workflow without placing a real phone call"
+openapi: "POST /api/v1/workflow/{workflow_id}/runs"
+---
+
+Creates a test execution of the workflow. No outbound call is placed — this is useful for validating agent behavior, checking prompt outputs, and testing tool integrations before going live.
diff --git a/docs/api-reference/agents/runs/get.mdx b/docs/api-reference/agents/runs/get.mdx
new file mode 100644
index 0000000..f80f11b
--- /dev/null
+++ b/docs/api-reference/agents/runs/get.mdx
@@ -0,0 +1,7 @@
+---
+title: "Get Run"
+description: "Retrieve a single workflow run by ID"
+openapi: "GET /api/v1/workflow/{workflow_id}/runs/{run_id}"
+---
+
+Returns the full run record including status, transcript, recording URL, gathered context, and usage/cost info. Use `recording_url` and `transcript_url` to download artifacts, or use the [Download endpoint](/api-reference/calls/download) for time-limited public URLs.
diff --git a/docs/api-reference/agents/runs/list.mdx b/docs/api-reference/agents/runs/list.mdx
new file mode 100644
index 0000000..5770bb1
--- /dev/null
+++ b/docs/api-reference/agents/runs/list.mdx
@@ -0,0 +1,7 @@
+---
+title: "List Runs"
+description: "Retrieve all runs for a workflow"
+openapi: "GET /api/v1/workflow/{workflow_id}/runs"
+---
+
+Returns all runs for the given workflow, including both test runs and live call runs.
diff --git a/docs/api-reference/agents/update.mdx b/docs/api-reference/agents/update.mdx
new file mode 100644
index 0000000..cc3cb0b
--- /dev/null
+++ b/docs/api-reference/agents/update.mdx
@@ -0,0 +1,7 @@
+---
+title: "Update Agent"
+description: "Update an agent's name, workflow definition, or configuration"
+openapi: "PUT /api/v1/workflow/{workflow_id}"
+---
+
+All fields are optional — only include the fields you want to change. Updating `workflow_definition` creates a new versioned definition while preserving the history of previous versions.
diff --git a/docs/api-reference/agents/validate.mdx b/docs/api-reference/agents/validate.mdx
new file mode 100644
index 0000000..c22919d
--- /dev/null
+++ b/docs/api-reference/agents/validate.mdx
@@ -0,0 +1,9 @@
+---
+title: "Validate Workflow"
+description: "Validate a workflow definition without executing it"
+openapi: "POST /api/v1/workflow/{workflow_id}/validate"
+---
+
+Checks the current workflow definition for structural errors — missing required fields, invalid node configurations, broken edge references — without placing a call or creating a run.
+
+If invalid, the response includes a list of errors each with a `kind` (`node`, `edge`, or `workflow`), the offending `id`, the `field`, and a human-readable `message`. See [Errors](/api-reference/errors) for the full error schema.
diff --git a/docs/api-reference/api-keys.mdx b/docs/api-reference/api-keys.mdx
new file mode 100644
index 0000000..5d4bc92
--- /dev/null
+++ b/docs/api-reference/api-keys.mdx
@@ -0,0 +1,21 @@
+---
+title: "Overview"
+description: "Create and manage API keys for programmatic access"
+---
+
+API keys authenticate requests from your applications and services. Each key is scoped to your organization — all API calls made with a key create and access resources within that organization.
+
+| Method | Endpoint | Quick Link |
+|---|---|---|
+| `POST` | `/user/api-keys` | [Create an API key](/api-reference/api-keys/create) |
+| `GET` | `/user/api-keys` | [List API keys](/api-reference/api-keys/list) |
+| `DELETE` | `/user/api-keys/{api_key_id}` | [Archive an API key](/api-reference/api-keys/archive) |
+| `PUT` | `/user/api-keys/{api_key_id}/reactivate` | [Reactivate an API key](/api-reference/api-keys/reactivate) |
+
+## Best practices
+
+- **Use one key per environment** — separate keys for development, staging, and production make rotation easy and limit blast radius if a key is compromised.
+- **Use one key per service** — this allows you to revoke a single service's access without affecting others.
+- **Rotate keys regularly** — create a new key, update your secret store, then archive the old key.
+- **Never hardcode keys** — use environment variables or a secrets manager. Never commit keys to version control.
+- **Monitor `last_used_at`** — keys with no recent activity may be safe to archive.
diff --git a/docs/api-reference/api-keys/archive.mdx b/docs/api-reference/api-keys/archive.mdx
new file mode 100644
index 0000000..c5751d0
--- /dev/null
+++ b/docs/api-reference/api-keys/archive.mdx
@@ -0,0 +1,7 @@
+---
+title: "Archive API Key"
+description: "Deactivate an API key by ID"
+openapi: "DELETE /api/v1/user/api-keys/{api_key_id}"
+---
+
+Archiving immediately revokes the key. Any request using the key after archiving returns `401`. Use [Reactivate](/api-reference/api-keys/reactivate) to restore access.
diff --git a/docs/api-reference/api-keys/create.mdx b/docs/api-reference/api-keys/create.mdx
new file mode 100644
index 0000000..d5f9070
--- /dev/null
+++ b/docs/api-reference/api-keys/create.mdx
@@ -0,0 +1,34 @@
+---
+title: "Create API Key"
+description: "Create a new API key for programmatic access"
+openapi: "POST /api/v1/user/api-keys"
+---
+
+
+The full key is only returned once at creation. Store it immediately in a secrets manager or environment variable — it cannot be retrieved again.
+
+
+## Authentication
+
+This endpoint requires a valid user session token. If you do not yet have an API key, obtain a session token by logging in first and pass it as a `Bearer` token in the `Authorization` header.
+
+**Step 1 — Log in to get a session token**
+
+```bash
+curl -X POST https://your-dograh-instance/api/v1/auth/login \
+ -H "Content-Type: application/json" \
+ -d '{"email": "you@example.com", "password": "your-password"}'
+```
+
+The response contains a `token` field. Use it in the next step.
+
+**Step 2 — Create an API key**
+
+```bash
+curl -X POST https://your-dograh-instance/api/v1/user/api-keys \
+ -H "Authorization: Bearer " \
+ -H "Content-Type: application/json" \
+ -d '{"name": "my-api-key"}'
+```
+
+Once you have an API key, you can use `X-API-Key: ` in place of `Authorization: Bearer` for all subsequent requests.
diff --git a/docs/api-reference/api-keys/list.mdx b/docs/api-reference/api-keys/list.mdx
new file mode 100644
index 0000000..8c9a919
--- /dev/null
+++ b/docs/api-reference/api-keys/list.mdx
@@ -0,0 +1,7 @@
+---
+title: "List API Keys"
+description: "Retrieve all API keys for your organization"
+openapi: "GET /api/v1/user/api-keys"
+---
+
+The `key` field is never returned in list responses — only `key_prefix` (the first 8 characters) is shown for identification. To include archived keys, pass `?include_archived=true`.
diff --git a/docs/api-reference/api-keys/reactivate.mdx b/docs/api-reference/api-keys/reactivate.mdx
new file mode 100644
index 0000000..d141049
--- /dev/null
+++ b/docs/api-reference/api-keys/reactivate.mdx
@@ -0,0 +1,7 @@
+---
+title: "Reactivate API Key"
+description: "Reactivate a previously archived API key"
+openapi: "PUT /api/v1/user/api-keys/{api_key_id}/reactivate"
+---
+
+Restores a previously [archived](/api-reference/api-keys/archive) key. The key resumes accepting requests immediately.
diff --git a/docs/api-reference/authentication.mdx b/docs/api-reference/authentication.mdx
new file mode 100644
index 0000000..376a9e9
--- /dev/null
+++ b/docs/api-reference/authentication.mdx
@@ -0,0 +1,49 @@
+---
+title: "Authentication"
+description: "How to authenticate requests to the Dograh API"
+---
+
+## API key authentication
+
+API keys are the recommended way to authenticate programmatic requests. Pass your key in the `X-API-Key` request header.
+
+```bash
+curl https://your-dograh-instance/api/v1/workflow/fetch \
+ -H "X-API-Key: dg_your_api_key"
+```
+
+API keys are scoped to an organization. All resources created or accessed using a key belong to that organization.
+
+### Create an API key
+
+Create keys in the dashboard under **Settings → API Keys**. The full key is shown **only once** at creation time — store it immediately in a secrets manager or environment variable.
+
+
+For self-hosted deployments using local auth, sign up and log in via the dashboard first, then create an API key there before making API calls.
+
+
+### Manage API keys
+
+| Action | Method | Path |
+|---|---|---|
+| List keys | `GET` | `/user/api-keys` |
+| Create key | `POST` | `/user/api-keys` |
+| Archive key | `DELETE` | `/user/api-keys/{api_key_id}` |
+| Reactivate key | `PUT` | `/user/api-keys/{api_key_id}/reactivate` |
+
+Archiving a key immediately revokes it. All subsequent requests using that key return `401`.
+
+---
+
+## Error responses
+
+| Status | Cause |
+|---|---|
+| `401 Unauthorized` | Missing, invalid, or expired credentials |
+| `403 Forbidden` | Valid credentials but insufficient permissions for the resource |
+
+```json
+{
+ "detail": "Invalid or expired API key"
+}
+```
diff --git a/docs/api-reference/calls.mdx b/docs/api-reference/calls.mdx
new file mode 100644
index 0000000..8bed841
--- /dev/null
+++ b/docs/api-reference/calls.mdx
@@ -0,0 +1,36 @@
+---
+title: "Overview"
+description: "Initiate outbound calls and trigger agents via the API"
+---
+
+| Method | Endpoint | Quick Link |
+|---|---|---|
+| `POST` | `/public/agent/{uuid}` | [Trigger an outbound call](/api-reference/calls/trigger) |
+| `POST` | `/telephony/initiate-call` | [Initiate a call (authenticated)](/api-reference/calls/initiate) |
+| `GET` | `/workflow/{workflow_id}/runs/{run_id}` | [Retrieve call details](/api-reference/calls/get-run) |
+| `GET` | `/public/download/workflow/{token}/{artifact_type}` | [Download recordings and transcripts](/api-reference/calls/download) |
+| `POST` | `/telephony/inbound/{workflow_id}` | [Inbound call webhook](/api-reference/calls/inbound) |
+
+## Using initial context
+
+`initial_context` passes runtime data into the agent at call time. Values are available as template variables in your agent's prompt using double-brace syntax.
+
+```json
+{
+ "initial_context": {
+ "customer_name": "Jane",
+ "appointment_date": "March 15"
+ }
+}
+```
+
+Your agent prompt can then reference `{{customer_name}}` and `{{appointment_date}}` and they will be substituted when the call starts.
+
+## Run status values
+
+| Status | Description |
+|---|---|
+| `pending` | Call queued but not yet connected |
+| `in_progress` | Call is live |
+| `completed` | Call ended normally |
+| `failed` | Call failed before or during execution |
diff --git a/docs/api-reference/calls/download.mdx b/docs/api-reference/calls/download.mdx
new file mode 100644
index 0000000..06f4ea6
--- /dev/null
+++ b/docs/api-reference/calls/download.mdx
@@ -0,0 +1,7 @@
+---
+title: "Download Recordings and Transcripts"
+description: "Download a recording or transcript using a time-limited public URL"
+openapi: "GET /api/v1/public/download/workflow/{token}/{artifact_type}"
+---
+
+`artifact_type` is either `recording` or `transcript`. The `token` is a time-limited download token — generate one from the run details before calling this endpoint.
diff --git a/docs/api-reference/calls/get-run.mdx b/docs/api-reference/calls/get-run.mdx
new file mode 100644
index 0000000..e1543a9
--- /dev/null
+++ b/docs/api-reference/calls/get-run.mdx
@@ -0,0 +1,9 @@
+---
+title: "Retrieve Call Details"
+description: "Get the details, transcript, and recording for a call"
+openapi: "GET /api/v1/workflow/{workflow_id}/runs/{run_id}"
+---
+
+Returns the full run record including call status, duration, transcript URL, recording URL, gathered context, and usage/cost info.
+
+Use the `recording_url` and `transcript_url` directly, or use the [Download endpoint](/api-reference/calls/download) to generate time-limited public URLs for sharing.
diff --git a/docs/api-reference/calls/inbound.mdx b/docs/api-reference/calls/inbound.mdx
new file mode 100644
index 0000000..ff5ed3d
--- /dev/null
+++ b/docs/api-reference/calls/inbound.mdx
@@ -0,0 +1,9 @@
+---
+title: "Inbound Call Webhook"
+description: "Webhook endpoint that routes inbound calls to a specific agent"
+openapi: "POST /api/v1/telephony/inbound/{workflow_id}"
+---
+
+Configure this URL in your telephony provider's dashboard (Twilio, Vonage, etc.) to route inbound calls to a specific agent. The `workflow_id` determines which agent handles the call.
+
+See [Inbound Calls](/integrations/telephony/inbound) for full setup instructions per provider.
diff --git a/docs/api-reference/calls/initiate.mdx b/docs/api-reference/calls/initiate.mdx
new file mode 100644
index 0000000..1b0bab1
--- /dev/null
+++ b/docs/api-reference/calls/initiate.mdx
@@ -0,0 +1,7 @@
+---
+title: "Initiate a Call (Authenticated)"
+description: "Start an outbound call with more control than the public endpoint"
+openapi: "POST /api/v1/telephony/initiate-call"
+---
+
+Use this endpoint when you need to specify a `workflow_run_id` to resume context from a previous run, or when you want to use the workflow's integer ID instead of its public UUID.
diff --git a/docs/api-reference/calls/trigger.mdx b/docs/api-reference/calls/trigger.mdx
new file mode 100644
index 0000000..5d52973
--- /dev/null
+++ b/docs/api-reference/calls/trigger.mdx
@@ -0,0 +1,15 @@
+---
+title: "Trigger an Outbound Call"
+description: "Initiate an outbound call using an agent's public UUID"
+openapi: "POST /api/v1/public/agent/{uuid}"
+---
+
+The simplest way to initiate a call programmatically. The `uuid` is visible in the dashboard URL when viewing an agent.
+
+Use `workflow_run_id` from the response to later [retrieve call details](/api-reference/calls/get-run), recordings, and transcripts.
+
+Pass `initial_context` to inject runtime data as template variables into the agent's prompt. See [Using initial context](/api-reference/calls#using-initial-context).
+
+
+Your telephony provider must be configured before outbound calls will connect. See [Telephony](/integrations/telephony/overview) for setup instructions.
+
diff --git a/docs/api-reference/campaigns.mdx b/docs/api-reference/campaigns.mdx
new file mode 100644
index 0000000..c7590c5
--- /dev/null
+++ b/docs/api-reference/campaigns.mdx
@@ -0,0 +1,29 @@
+---
+title: "Overview"
+description: "Create and manage outbound calling campaigns"
+---
+
+A **campaign** runs a workflow against a list of contacts. You upload a CSV of phone numbers, configure retry logic and scheduling, then start the campaign. Dograh dials contacts automatically up to your configured concurrency limit.
+
+| Method | Endpoint | Quick Link |
+|---|---|---|
+| `POST` | `/s3/presigned-upload-url` | [Upload contacts CSV](/api-reference/campaigns/upload-contacts) |
+| `POST` | `/campaign/create` | [Create a campaign](/api-reference/campaigns/create) |
+| `GET` | `/campaign/` | [List campaigns](/api-reference/campaigns/list) |
+| `GET` | `/campaign/{campaign_id}` | [Get a campaign](/api-reference/campaigns/get) |
+| `PATCH` | `/campaign/{campaign_id}` | [Update a campaign](/api-reference/campaigns/update) |
+| `POST` | `/campaign/{campaign_id}/start` | [Start](/api-reference/campaigns/start) |
+| `POST` | `/campaign/{campaign_id}/pause` | [Pause](/api-reference/campaigns/pause) |
+| `POST` | `/campaign/{campaign_id}/resume` | [Resume](/api-reference/campaigns/resume) |
+| `GET` | `/campaign/{campaign_id}/progress` | [Get campaign progress](/api-reference/campaigns/progress) |
+| `GET` | `/campaign/{campaign_id}/runs` | [Get campaign call runs](/api-reference/campaigns/runs) |
+
+## Campaign status values
+
+| Status | Description |
+|---|---|
+| `draft` | Created but not started |
+| `running` | Actively dialing contacts |
+| `paused` | Temporarily stopped; can be resumed |
+| `completed` | All contacts processed |
+| `failed` | Campaign encountered a fatal error |
diff --git a/docs/api-reference/campaigns/create.mdx b/docs/api-reference/campaigns/create.mdx
new file mode 100644
index 0000000..1d06e5b
--- /dev/null
+++ b/docs/api-reference/campaigns/create.mdx
@@ -0,0 +1,20 @@
+---
+title: "Create Campaign"
+description: "Create a new outbound calling campaign"
+openapi: "POST /api/v1/campaign/create"
+---
+
+Before creating a campaign, [upload your contacts CSV](/api-reference/campaigns/upload-contacts) to get a `source_url`.
+
+The `time_slots` field controls when Dograh is allowed to place calls. If omitted, calls can be placed at any time. The `timezone` field applies to all time slot windows.
+
+```json
+{
+ "time_slots": [
+ { "day": "monday", "start": "09:00", "end": "17:00" },
+ { "day": "tuesday", "start": "09:00", "end": "17:00" }
+ ]
+}
+```
+
+Once created, the campaign is in `draft` status. Call [Start](/api-reference/campaigns/start) to begin dialing.
diff --git a/docs/api-reference/campaigns/get.mdx b/docs/api-reference/campaigns/get.mdx
new file mode 100644
index 0000000..7e1219e
--- /dev/null
+++ b/docs/api-reference/campaigns/get.mdx
@@ -0,0 +1,5 @@
+---
+title: "Get Campaign"
+description: "Retrieve a single campaign by ID"
+openapi: "GET /api/v1/campaign/{campaign_id}"
+---
diff --git a/docs/api-reference/campaigns/list.mdx b/docs/api-reference/campaigns/list.mdx
new file mode 100644
index 0000000..256d9e4
--- /dev/null
+++ b/docs/api-reference/campaigns/list.mdx
@@ -0,0 +1,5 @@
+---
+title: "List Campaigns"
+description: "Retrieve all campaigns for your organization"
+openapi: "GET /api/v1/campaign/"
+---
diff --git a/docs/api-reference/campaigns/pause.mdx b/docs/api-reference/campaigns/pause.mdx
new file mode 100644
index 0000000..857817a
--- /dev/null
+++ b/docs/api-reference/campaigns/pause.mdx
@@ -0,0 +1,7 @@
+---
+title: "Pause Campaign"
+description: "Temporarily stop a running campaign"
+openapi: "POST /api/v1/campaign/{campaign_id}/pause"
+---
+
+Stops dispatching new calls. In-flight calls are not interrupted — they run to completion. Use [Resume](/api-reference/campaigns/resume) to continue from where the campaign paused.
diff --git a/docs/api-reference/campaigns/progress.mdx b/docs/api-reference/campaigns/progress.mdx
new file mode 100644
index 0000000..7e5e689
--- /dev/null
+++ b/docs/api-reference/campaigns/progress.mdx
@@ -0,0 +1,16 @@
+---
+title: "Get Campaign Progress"
+description: "Get the current progress of a campaign"
+openapi: "GET /api/v1/campaign/{campaign_id}/progress"
+---
+
+Returns a real-time snapshot of how many contacts have been processed.
+
+| Field | Description |
+|---|---|
+| `total` | Total number of contacts in the campaign |
+| `processed` | Contacts that have been attempted at least once |
+| `completed` | Contacts with a successful call outcome |
+| `failed` | Contacts that exhausted all retry attempts without success |
+| `pending` | Contacts not yet attempted |
+| `completion_percentage` | `processed / total × 100` |
diff --git a/docs/api-reference/campaigns/resume.mdx b/docs/api-reference/campaigns/resume.mdx
new file mode 100644
index 0000000..5ecd904
--- /dev/null
+++ b/docs/api-reference/campaigns/resume.mdx
@@ -0,0 +1,7 @@
+---
+title: "Resume Campaign"
+description: "Resume a paused campaign"
+openapi: "POST /api/v1/campaign/{campaign_id}/resume"
+---
+
+Resumes dispatching calls from where the campaign paused. Only valid on campaigns in `paused` status.
diff --git a/docs/api-reference/campaigns/runs.mdx b/docs/api-reference/campaigns/runs.mdx
new file mode 100644
index 0000000..d3c4bdd
--- /dev/null
+++ b/docs/api-reference/campaigns/runs.mdx
@@ -0,0 +1,7 @@
+---
+title: "Get Campaign Runs"
+description: "Retrieve individual call records for each contact in a campaign"
+openapi: "GET /api/v1/campaign/{campaign_id}/runs"
+---
+
+Returns the individual call records for each contact in the campaign. Each record includes the same fields as a [workflow run](/api-reference/calls#retrieve-call-details), including call status, duration, transcript, and recording URL.
diff --git a/docs/api-reference/campaigns/start.mdx b/docs/api-reference/campaigns/start.mdx
new file mode 100644
index 0000000..02b4fef
--- /dev/null
+++ b/docs/api-reference/campaigns/start.mdx
@@ -0,0 +1,7 @@
+---
+title: "Start Campaign"
+description: "Start dialing contacts in a campaign"
+openapi: "POST /api/v1/campaign/{campaign_id}/start"
+---
+
+Transitions the campaign from `draft` or `paused` to `running`. Dograh begins dialing contacts up to the configured `max_concurrency`.
diff --git a/docs/api-reference/campaigns/update.mdx b/docs/api-reference/campaigns/update.mdx
new file mode 100644
index 0000000..6db15e8
--- /dev/null
+++ b/docs/api-reference/campaigns/update.mdx
@@ -0,0 +1,7 @@
+---
+title: "Update Campaign"
+description: "Update campaign settings"
+openapi: "PATCH /api/v1/campaign/{campaign_id}"
+---
+
+You can update name, concurrency, time slots, and retry config. Updates are only allowed on campaigns in `draft` or `paused` status — [pause the campaign](/api-reference/campaigns/pause) first if it is currently running.
diff --git a/docs/api-reference/campaigns/upload-contacts.mdx b/docs/api-reference/campaigns/upload-contacts.mdx
new file mode 100644
index 0000000..5a971ca
--- /dev/null
+++ b/docs/api-reference/campaigns/upload-contacts.mdx
@@ -0,0 +1,33 @@
+---
+title: "Upload Contacts CSV"
+description: "Get a presigned S3 URL to upload a contacts CSV for a campaign"
+openapi: "POST /api/v1/s3/presigned-upload-url"
+---
+
+Uploading contacts is a two-step process. First call this endpoint to get a presigned upload URL, then PUT your CSV directly to that URL.
+
+```bash
+# Step 1: Get upload URL
+curl -X POST https://your-dograh-instance/api/v1/s3/presigned-upload-url \
+ -H "X-API-Key: dg_your_api_key"
+
+# Response:
+# { "upload_url": "https://...", "s3_key": "campaigns/..." }
+
+# Step 2: Upload the CSV
+curl -X PUT "https://presigned-url..." \
+ -H "Content-Type: text/csv" \
+ --data-binary @contacts.csv
+```
+
+Use the `s3_key` from the response as the `source_url` when [creating a campaign](/api-reference/campaigns/create).
+
+### CSV format
+
+The CSV must include a `phone_number` column. Any additional columns are passed as `initial_context` to each call, making them available as template variables in the workflow.
+
+```csv
+phone_number,customer_name,plan
++14155550100,Jane Smith,premium
++14155550101,Bob Jones,basic
+```
diff --git a/docs/api-reference/errors.mdx b/docs/api-reference/errors.mdx
new file mode 100644
index 0000000..4db204d
--- /dev/null
+++ b/docs/api-reference/errors.mdx
@@ -0,0 +1,106 @@
+---
+title: "Errors"
+description: "HTTP status codes and error formats returned by the Dograh API"
+---
+
+## Error format
+
+All errors return a JSON body with a `detail` field:
+
+```json
+{
+ "detail": "Human-readable error message"
+}
+```
+
+For request validation failures (status `422`), `detail` is an array of field-level errors:
+
+```json
+{
+ "detail": [
+ {
+ "loc": ["body", "phone_number"],
+ "msg": "field required",
+ "type": "value_error.missing"
+ }
+ ]
+}
+```
+
+---
+
+## HTTP status codes
+
+| Status | Meaning | Common causes |
+|---|---|---|
+| `400` | Bad Request | Missing required fields, invalid parameter values, unsupported operation |
+| `401` | Unauthorized | Missing auth header, invalid or expired API key or JWT token |
+| `403` | Forbidden | Valid credentials but the resource belongs to a different organization |
+| `404` | Not Found | Resource ID does not exist or is not accessible to your organization |
+| `409` | Conflict | Duplicate resource (e.g., email already registered) |
+| `422` | Unprocessable Entity | Request body or query parameter failed schema validation |
+| `500` | Internal Server Error | Unexpected server-side failure |
+| `501` | Not Implemented | Feature not supported in the current deployment |
+
+---
+
+## Workflow validation errors
+
+When validating a workflow (or creating one with invalid nodes), the API returns structured errors that reference specific nodes, edges, or fields:
+
+```json
+{
+ "errors": [
+ {
+ "kind": "node",
+ "id": "agent-1",
+ "field": "data.prompt",
+ "message": "Prompt cannot be empty"
+ },
+ {
+ "kind": "edge",
+ "id": "edge-3",
+ "field": null,
+ "message": "Edge target node does not exist"
+ },
+ {
+ "kind": "workflow",
+ "id": null,
+ "field": null,
+ "message": "Workflow must have exactly one Start Call node"
+ }
+ ]
+}
+```
+
+| Field | Type | Description |
+|---|---|---|
+| `kind` | `"node" \| "edge" \| "workflow"` | What the error applies to |
+| `id` | string or null | Node or edge ID from the workflow definition |
+| `field` | string or null | Dot-notation path to the specific field (e.g. `data.prompt`) |
+| `message` | string | Human-readable description of the problem |
+
+---
+
+## Telephony errors
+
+Telephony operations may fail with one of these named error types returned in the `detail` field:
+
+| Error | Description |
+|---|---|
+| `PROVIDER_MISMATCH` | The request was routed to the wrong telephony provider |
+| `WORKFLOW_NOT_FOUND` | The workflow ID in the inbound URL does not exist |
+| `ACCOUNT_VALIDATION_FAILED` | Your telephony provider credentials are invalid |
+| `PHONE_NUMBER_NOT_CONFIGURED` | The phone number is not set up in your telephony account |
+| `SIGNATURE_VALIDATION_FAILED` | Webhook signature verification failed (possible spoofed request) |
+| `QUOTA_EXCEEDED` | Your organization has exceeded its usage quota |
+| `GENERAL_AUTH_FAILED` | Generic authentication failure with the telephony provider |
+
+---
+
+## Tips for handling errors
+
+- **Retry on `500`** with exponential backoff — transient server errors can resolve on retry.
+- **Do not retry `4xx`** — these indicate problems with your request that will not self-resolve.
+- **Check `detail` carefully on `422`** — the `loc` array pinpoints exactly which field failed validation.
+- **Store API keys securely** — a `401` on a previously working key likely means the key was archived.
diff --git a/docs/api-reference/openapi.json b/docs/api-reference/openapi.json
new file mode 100644
index 0000000..2595c99
--- /dev/null
+++ b/docs/api-reference/openapi.json
@@ -0,0 +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.","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"}}}}}}},"/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"}},{"name":"x-webhook-signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Webhook-Signature"}}],"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/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"}},{"name":"x-vobiz-signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Vobiz-Signature"}},{"name":"x-vobiz-timestamp","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Vobiz-Timestamp"}}],"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"}},{"name":"x-vobiz-signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Vobiz-Signature"}},{"name":"x-vobiz-timestamp","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Vobiz-Timestamp"}}],"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/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"}},{"name":"x-vobiz-signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Vobiz-Signature"}},{"name":"x-vobiz-timestamp","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Vobiz-Timestamp"}}],"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/inbound/{workflow_id}":{"post":{"tags":["main"],"summary":"Handle Inbound Telephony","description":"Handle inbound telephony calls from any supported provider with common processing","operationId":"handle_inbound_telephony_api_v1_telephony_inbound__workflow_id__post","parameters":[{"name":"workflow_id","in":"path","required":true,"schema":{"type":"integer","title":"Workflow Id"}},{"name":"x-twilio-signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Twilio-Signature"}},{"name":"x-vobiz-signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Vobiz-Signature"}},{"name":"x-vobiz-timestamp","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Vobiz-Timestamp"}},{"name":"x-cx-apikey","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cx-Apikey"}}],"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/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/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/call-transfer":{"post":{"tags":["main"],"summary":"Initiate Call Transfer","description":"Initiate a call transfer via the telephony provider.\n\nThis endpoint only initiates the outbound call. Transfer context\n(original_call_sid, etc.) is stored by the caller\nbefore invoking this endpoint.","operationId":"initiate_call_transfer_api_v1_telephony_call_transfer_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferCallRequest"}}},"required":true},"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/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"}}}}}}},"/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"}}}}}}},"/api/v1/workflow/fetch/{workflow_id}":{"get":{"tags":["main"],"summary":"Get Workflow","description":"Get a single workflow by ID","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"}}}}}}},"/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":"authorization","in":"header","required":false,"schema":{"anyOf":[{"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}":{"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"}}}}}}},"/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/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/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/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"],"type":"string","title":"Provider"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"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}/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\n\nOnly works for CSV source type. For Google Sheets, use the source_id directly.\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":"authorization","in":"header","required":false,"schema":{"anyOf":[{"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"}}}}}},"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"}}}}}},"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"}}}}}}},"/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}/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/integration/":{"get":{"tags":["main"],"summary":"Get Integrations","description":"Get all integrations for the user's selected organization.\n\nReturns:\n List of integrations associated with the user's selected organization","operationId":"get_integrations_api_v1_integration__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/IntegrationResponse"},"title":"Response Get Integrations Api V1 Integration Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integration/session":{"post":{"tags":["main"],"summary":"Create Session","description":"Create a Nango session for the user's selected organization.\n\nReturns:\n Session token and ID for the created session","operationId":"create_session_api_v1_integration_session_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/SessionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integration/{integration_id}":{"put":{"tags":["main"],"summary":"Update Integration","description":"Update an integration's selected files (for Google Sheets).\n\nArgs:\n integration_id: The ID of the integration to update\n request: The update request containing selected files\n user: The authenticated user\n\nReturns:\n Updated integration details","operationId":"update_integration_api_v1_integration__integration_id__put","parameters":[{"name":"integration_id","in":"path","required":true,"schema":{"type":"integer","title":"Integration 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/UpdateIntegrationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/integration/{integration_id}/access-token":{"get":{"tags":["main"],"summary":"Get Integration Access Token","description":"Get the latest access token for an integration from Nango.\n\nArgs:\n integration_id: The ID of the integration\n user: The authenticated user\n\nReturns:\n Dict containing access token and expiration info","operationId":"get_integration_access_token_api_v1_integration__integration_id__access_token_get","parameters":[{"name":"integration_id","in":"path","required":true,"schema":{"type":"integer","title":"Integration 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/AccessTokenResponse"}}}},"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":"Get telephony configuration for the user's organization with masked sensitive fields.","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":"Save telephony configuration for the user's organization.","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":{"anyOf":[{"$ref":"#/components/schemas/TwilioConfigurationRequest"},{"$ref":"#/components/schemas/VonageConfigurationRequest"},{"$ref":"#/components/schemas/VobizConfigurationRequest"},{"$ref":"#/components/schemas/CloudonixConfigurationRequest"},{"$ref":"#/components/schemas/ARIConfigurationRequest"}],"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/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 transcript or recording file stored on S3.\n\nAccess Control:\n* Superusers can request any key.\n* Regular users can only request resources belonging to **their** workflow runs.","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":"authorization","in":"header","required":false,"schema":{"anyOf":[{"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/looptalk/test-sessions":{"post":{"tags":["main"],"summary":"Create Test Session","description":"Create a new LoopTalk test session.","operationId":"create_test_session_api_v1_looptalk_test_sessions_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/CreateTestSessionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSessionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["main"],"summary":"List Test Sessions","description":"List LoopTalk test sessions.","operationId":"list_test_sessions_api_v1_looptalk_test_sessions_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"load_test_group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Load Test Group Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","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/TestSessionResponse"},"title":"Response List Test Sessions Api V1 Looptalk Test Sessions Get"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/looptalk/test-sessions/{test_session_id}":{"get":{"tags":["main"],"summary":"Get Test Session","description":"Get a specific test session.","operationId":"get_test_session_api_v1_looptalk_test_sessions__test_session_id__get","parameters":[{"name":"test_session_id","in":"path","required":true,"schema":{"type":"integer","title":"Test Session 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/TestSessionResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/looptalk/test-sessions/{test_session_id}/start":{"post":{"tags":["main"],"summary":"Start Test Session","description":"Start a LoopTalk test session.","operationId":"start_test_session_api_v1_looptalk_test_sessions__test_session_id__start_post","parameters":[{"name":"test_session_id","in":"path","required":true,"schema":{"type":"integer","title":"Test Session 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/looptalk/test-sessions/{test_session_id}/stop":{"post":{"tags":["main"],"summary":"Stop Test Session","description":"Stop a running test session.","operationId":"stop_test_session_api_v1_looptalk_test_sessions__test_session_id__stop_post","parameters":[{"name":"test_session_id","in":"path","required":true,"schema":{"type":"integer","title":"Test Session 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/looptalk/test-sessions/{test_session_id}/conversation":{"get":{"tags":["main"],"summary":"Get Test Session Conversation","description":"Get conversation details for a test session.","operationId":"get_test_session_conversation_api_v1_looptalk_test_sessions__test_session_id__conversation_get","parameters":[{"name":"test_session_id","in":"path","required":true,"schema":{"type":"integer","title":"Test Session 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/looptalk/load-tests":{"post":{"tags":["main"],"summary":"Create Load Test","description":"Create and start a load test.","operationId":"create_load_test_api_v1_looptalk_load_tests_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/CreateLoadTestRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Load Test Api V1 Looptalk Load Tests Post"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/looptalk/load-tests/{load_test_group_id}/stats":{"get":{"tags":["main"],"summary":"Get Load Test Stats","description":"Get statistics for a load test group.","operationId":"get_load_test_stats_api_v1_looptalk_load_tests__load_test_group_id__stats_get","parameters":[{"name":"load_test_group_id","in":"path","required":true,"schema":{"type":"string","title":"Load Test Group 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/LoadTestStatsResponse"}}}},"404":{"description":"Not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/looptalk/active-tests":{"get":{"tags":["main"],"summary":"Get Active Tests","description":"Get information about currently active test sessions.","operationId":"get_active_tests_api_v1_looptalk_active_tests_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/usage/current-period":{"get":{"tags":["main"],"summary":"Get Current Period Usage","description":"Get current billing 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/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 format date string","title":"Start Date"},"description":"ISO format date string"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO format date string","title":"End Date"},"description":"ISO format date string"},{"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 string of filters","title":"Filters"},"description":"JSON string of filters"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"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/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":"Handle CORS preflight 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}":{"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"}}}}}},"options":{"tags":["main"],"summary":"Options Config","description":"Handle CORS preflight for config endpoint","operationId":"options_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"}}}}}}},"/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":"Handle CORS preflight 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 via API trigger.\n\nThis endpoint allows external systems (CRMs, automation tools, etc.) to\nprogrammatically trigger outbound phone calls with custom context variables.\n\nArgs:\n uuid: The unique trigger UUID\n request: The call request with phone number and optional context\n x_api_key: API key for authentication (passed in X-API-Key header)\n\nReturns:\n TriggerCallResponse with workflow run details\n\nRaises:\n HTTPException: Various error conditions (401, 403, 404, 400)","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/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"}}}}}}},"/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/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/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","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":""},"inbound_workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inbound Workflow Id","description":"Workflow ID for inbound calls"},"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","title":"Provider"},"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":""},"inbound_workflow_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inbound Workflow Id"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["provider","ari_endpoint","app_name","app_password","from_numbers"],"title":"ARIConfigurationResponse","description":"Response schema for ARI configuration with masked sensitive fields."},"AccessTokenResponse":{"properties":{"access_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Token"},"refresh_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refresh Token"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"},"connection_id":{"type":"string","title":"Connection Id"}},"type":"object","required":["access_token","refresh_token","expires_at","connection_id"],"title":"AccessTokenResponse"},"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"},"CallType":{"type":"string","enum":["inbound","outbound"],"title":"CallType"},"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"},"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"}]}},"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"},"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","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"},"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","title":"Provider"},"bearer_token":{"type":"string","title":"Bearer Token"},"domain_id":{"type":"string","title":"Domain Id"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["provider","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":"^(google-sheet|csv)$","title":"Source Type"},"source_id":{"type":"string","title":"Source 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."},"CreateLoadTestRequest":{"properties":{"name_prefix":{"type":"string","title":"Name Prefix"},"actor_workflow_id":{"type":"integer","title":"Actor Workflow Id"},"adversary_workflow_id":{"type":"integer","title":"Adversary Workflow Id"},"test_count":{"type":"integer","maximum":10.0,"minimum":1.0,"title":"Test Count"},"config":{"additionalProperties":true,"type":"object","title":"Config"}},"type":"object","required":["name_prefix","actor_workflow_id","adversary_workflow_id","test_count"],"title":"CreateLoadTestRequest"},"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"},"CreateTestSessionRequest":{"properties":{"name":{"type":"string","title":"Name"},"actor_workflow_id":{"type":"integer","title":"Actor Workflow Id"},"adversary_workflow_id":{"type":"integer","title":"Adversary Workflow Id"},"config":{"additionalProperties":true,"type":"object","title":"Config"}},"type":"object","required":["name","actor_workflow_id","adversary_workflow_id"],"title":"CreateTestSessionRequest"},"CreateToolRequest":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"category":{"type":"string","title":"Category","default":"http_api"},"icon":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Icon","default":"globe"},"icon_color":{"anyOf":[{"type":"string","maxLength":7},{"type":"null"}],"title":"Icon Color","default":"#3B82F6"},"definition":{"oneOf":[{"$ref":"#/components/schemas/HttpApiToolDefinition"},{"$ref":"#/components/schemas/EndCallToolDefinition"},{"$ref":"#/components/schemas/TransferCallToolDefinition"}],"title":"Definition","discriminator":{"propertyName":"type","mapping":{"end_call":"#/components/schemas/EndCallToolDefinition","http_api":"#/components/schemas/HttpApiToolDefinition","transfer_call":"#/components/schemas/TransferCallToolDefinition"}}}},"type":"object","required":["name","definition"],"title":"CreateToolRequest","description":"Request schema for creating a 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"},"quota_dograh_tokens":{"type":"integer","title":"Quota Dograh Tokens"},"percentage_used":{"type":"number","title":"Percentage Used"},"next_refresh_date":{"type":"string","title":"Next Refresh Date"},"quota_enabled":{"type":"boolean","title":"Quota Enabled"},"total_duration_seconds":{"type":"integer","title":"Total Duration Seconds"},"used_amount_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Used Amount Usd"},"quota_amount_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Quota 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","quota_dograh_tokens","percentage_used","next_refresh_date","quota_enabled","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"},"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"},"default_providers":{"additionalProperties":{"type":"string"},"type":"object","title":"Default Providers"}},"type":"object","required":["llm","tts","stt","embeddings","default_providers"],"title":"DefaultConfigurationsResponse"},"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"},"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."},"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"},"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"],"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"},"endCallReason":{"type":"boolean","title":"Endcallreason","description":"When enabled, LLM 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 LLM 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."},"FileMetadataResponse":{"properties":{"key":{"type":"string","title":"Key"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","required":["key","metadata"],"title":"FileMetadataResponse"},"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"}},"type":"object","required":["status","version","backend_api_endpoint","deployment_mode","auth_provider"],"title":"HealthResponse"},"HttpApiConfig":{"properties":{"method":{"type":"string","title":"Method","description":"HTTP method (GET, POST, PUT, PATCH, DELETE)"},"url":{"type":"string","title":"Url","description":"Target URL"},"headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Headers","description":"Static headers to include"},"credential_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credential Uuid","description":"Reference to ExternalCredentialModel for auth"},"parameters":{"anyOf":[{"items":{"$ref":"#/components/schemas/ToolParameter"},"type":"array"},{"type":"null"}],"title":"Parameters","description":"Parameters that the tool accepts from LLM"},"timeout_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Timeout Ms","description":"Request timeout in milliseconds","default":5000}},"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"}},"type":"object","required":["workflow_id"],"title":"InitiateCallRequest"},"IntegrationResponse":{"properties":{"id":{"type":"integer","title":"Id"},"integration_id":{"type":"string","title":"Integration Id"},"organisation_id":{"type":"integer","title":"Organisation Id"},"created_by":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Created By"},"provider":{"type":"string","title":"Provider"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","title":"Created At"},"action":{"type":"string","title":"Action"},"provider_data":{"additionalProperties":true,"type":"object","title":"Provider Data"}},"type":"object","required":["id","integration_id","organisation_id","created_by","provider","is_active","created_at","action","provider_data"],"title":"IntegrationResponse"},"ItemKind":{"type":"string","enum":["node","edge","workflow"],"title":"ItemKind"},"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"},"LoadTestStatsResponse":{"properties":{"total":{"type":"integer","title":"Total"},"pending":{"type":"integer","title":"Pending"},"running":{"type":"integer","title":"Running"},"completed":{"type":"integer","title":"Completed"},"failed":{"type":"integer","title":"Failed"},"sessions":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Sessions"}},"type":"object","required":["total","pending","running","completed","failed","sessions"],"title":"LoadTestStatsResponse"},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest"},"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"}},"type":"object","required":["document_uuid","s3_key"],"title":"ProcessDocumentRequestSchema","description":"Request schema for triggering document processing."},"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"},"S3SignedUrlResponse":{"properties":{"url":{"type":"string","title":"Url"},"expires_in":{"type":"integer","title":"Expires In"}},"type":"object","required":["url","expires_in"],"title":"S3SignedUrlResponse"},"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"},"SessionResponse":{"properties":{"session_token":{"type":"string","title":"Session Token"},"expires_at":{"type":"string","title":"Expires At"}},"type":"object","required":["session_token","expires_at"],"title":"SessionResponse"},"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"},"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"},"TelephonyConfigurationResponse":{"properties":{"twilio":{"anyOf":[{"$ref":"#/components/schemas/TwilioConfigurationResponse"},{"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"}]}},"type":"object","title":"TelephonyConfigurationResponse","description":"Top-level telephony configuration response."},"TestSessionResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status"},"actor_workflow_id":{"type":"integer","title":"Actor Workflow Id"},"adversary_workflow_id":{"type":"integer","title":"Adversary Workflow Id"},"load_test_group_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Load Test Group Id"},"test_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Test Index"},"config":{"additionalProperties":true,"type":"object","title":"Config"},"results":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Results"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"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"}},"type":"object","required":["id","name","status","actor_workflow_id","adversary_workflow_id","load_test_group_id","test_index","config","results","error","created_at","started_at","completed_at"],"title":"TestSessionResponse"},"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 key in request body)"},"type":{"type":"string","title":"Type","description":"Parameter type: string, number, or boolean"},"description":{"type":"string","title":"Description","description":"Description of what this parameter is for"},"required":{"type":"boolean","title":"Required","description":"Whether this parameter is required","default":true}},"type":"object","required":["name","type","description"],"title":"ToolParameter","description":"A parameter that the tool accepts."},"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 tool."},"TransferCallConfig":{"properties":{"destination":{"type":"string","title":"Destination","description":"Phone number or SIP endpoint to transfer the call to (E.164 format e.g., +1234567890, or SIP endpoint e.g., PJSIP/1234)"},"messageType":{"type":"string","enum":["none","custom"],"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 the call"},"timeout":{"type":"integer","maximum":120.0,"minimum":5.0,"title":"Timeout","description":"Maximum time in seconds to wait for destination to answer (5-120 seconds)","default":30}},"type":"object","required":["destination"],"title":"TransferCallConfig","description":"Configuration for Transfer Call tools."},"TransferCallRequest":{"properties":{"destination":{"type":"string","title":"Destination"},"organization_id":{"type":"integer","title":"Organization Id"},"transfer_id":{"type":"string","title":"Transfer Id"},"conference_name":{"type":"string","title":"Conference Name"},"timeout":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Timeout","default":20}},"type":"object","required":["destination","organization_id","transfer_id","conference_name"],"title":"TransferCallRequest","description":"Request model for initiating a call transfer."},"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"}},"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","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","minItems":1,"title":"From Numbers","description":"List of Twilio phone numbers"}},"type":"object","required":["account_sid","auth_token","from_numbers"],"title":"TwilioConfigurationRequest","description":"Request schema for Twilio configuration."},"TwilioConfigurationResponse":{"properties":{"provider":{"type":"string","title":"Provider"},"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":["provider","account_sid","auth_token","from_numbers"],"title":"TwilioConfigurationResponse","description":"Response schema for Twilio configuration with masked sensitive fields."},"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."},"UpdateIntegrationRequest":{"properties":{"selected_files":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Selected Files"}},"type":"object","required":["selected_files"],"title":"UpdateIntegrationRequest"},"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"}],"discriminator":{"propertyName":"type","mapping":{"end_call":"#/components/schemas/EndCallToolDefinition","http_api":"#/components/schemas/HttpApiToolDefinition","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 tool."},"UpdateWorkflowRequest":{"properties":{"name":{"type":"string","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","required":["name"],"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":"object"},{"type":"null"}],"title":"Llm"},"tts":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"}]},"type":"object"},{"type":"null"}],"title":"Tts"},"stt":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"}]},"type":"object"},{"type":"null"}],"title":"Stt"},"embeddings":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"items":{"type":"string"},"type":"array"}]},"type":"object"},{"type":"null"}],"title":"Embeddings"},"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"}},"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"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VobizConfigurationRequest":{"properties":{"provider":{"type":"string","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"},"from_numbers":{"items":{"type":"string"},"type":"array","minItems":1,"title":"From Numbers","description":"List of Vobiz phone numbers (E.164 without + prefix)"}},"type":"object","required":["auth_id","auth_token","from_numbers"],"title":"VobizConfigurationRequest","description":"Request schema for Vobiz configuration."},"VobizConfigurationResponse":{"properties":{"provider":{"type":"string","title":"Provider"},"auth_id":{"type":"string","title":"Auth Id"},"auth_token":{"type":"string","title":"Auth Token"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["provider","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","title":"Provider","default":"vonage"},"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key","description":"Vonage API Key"},"api_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"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","minItems":1,"title":"From Numbers","description":"List of Vonage phone numbers (without + prefix)"}},"type":"object","required":["application_id","private_key","from_numbers"],"title":"VonageConfigurationRequest","description":"Request schema for Vonage configuration."},"VonageConfigurationResponse":{"properties":{"provider":{"type":"string","title":"Provider"},"application_id":{"type":"string","title":"Application Id"},"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key"},"api_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Secret"},"private_key":{"type":"string","title":"Private Key"},"from_numbers":{"items":{"type":"string"},"type":"array","title":"From Numbers"}},"type":"object","required":["provider","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"}},"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":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Call Disposition Codes"},"total_runs":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Runs"},"workflow_configurations":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Workflow Configurations"}},"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"},"cost_info":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Cost 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"},"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"},"phone_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone Number"},"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"}}}}
\ No newline at end of file
diff --git a/docs/api-reference/overview.mdx b/docs/api-reference/overview.mdx
new file mode 100644
index 0000000..50407d6
--- /dev/null
+++ b/docs/api-reference/overview.mdx
@@ -0,0 +1,71 @@
+---
+title: "Overview"
+description: "Interact with Dograh programmatically via the REST API"
+---
+
+## Base URL
+
+All API requests are made to:
+
+```
+https://your-dograh-instance/api/v1
+```
+
+If you are using the hosted version, the base URL is `https://app.dograh.com/api/v1`.
+
+## Versioning
+
+The current API version is `v1`. The version is included in the URL path.
+
+## Request format
+
+All request bodies must be sent as JSON with the `Content-Type: application/json` header.
+
+```bash
+curl -X POST https://your-dograh-instance/api/v1/workflow/create/definition \
+ -H "Content-Type: application/json" \
+ -H "X-API-Key: dg_your_api_key" \
+ -d '{"name": "My Agent", "workflow_definition": {}}'
+```
+
+## Response format
+
+All responses are JSON. Successful responses return the relevant resource object. Error responses follow a consistent shape:
+
+```json
+{
+ "detail": "Error message describing what went wrong"
+}
+```
+
+For validation errors (422), the detail may be a list:
+
+```json
+{
+ "detail": [
+ {
+ "loc": ["body", "name"],
+ "msg": "field required",
+ "type": "value_error.missing"
+ }
+ ]
+}
+```
+
+## Health check
+
+Verify your instance is reachable before making API calls.
+
+```bash
+curl https://your-dograh-instance/api/v1/health
+```
+
+```json
+{
+ "status": "ok",
+ "version": "1.0.0",
+ "backend_api_endpoint": "https://your-dograh-instance",
+ "deployment_mode": "oss",
+ "auth_provider": "local"
+}
+```
diff --git a/docs/configurations/tracing.mdx b/docs/configurations/tracing.mdx
index 0cbf498..17fdb46 100644
--- a/docs/configurations/tracing.mdx
+++ b/docs/configurations/tracing.mdx
@@ -68,7 +68,7 @@ The tool descriptions shown in traces match the descriptions you set in your pat
### Custom Tools
-Any external tools you've attached to the node (e.g. any custom tools you created for API endpoints for booking, order submission, etc.) will appear here. See custom tools documentation here: https://docs.dograh.com/voice-agent/tools.
+Any external tools you've attached to the node (e.g. any custom tools you created for API endpoints for booking, order submission, etc.) will appear here. See the [custom tools documentation](/voice-agent/tools/http-api).
## Tool Calls in Traces
@@ -115,7 +115,7 @@ We provide seamless integration with Langfuse for self-hosted Dograh deployments
**Setup steps:**
1. Sign up at [Langfuse](https://langfuse.com) and create API credentials
-2. Add the following environment variables (in `docker-compose.yaml` for Docker deployments):
+2. Add the following [environment variables](/developer/environment-variables#tracing-langfuse) (in `docker-compose.yaml` for Docker deployments):
```
ENABLE_TRACING="true"
diff --git a/docs/core-concepts/calls-and-runs.mdx b/docs/core-concepts/calls-and-runs.mdx
new file mode 100644
index 0000000..b397380
--- /dev/null
+++ b/docs/core-concepts/calls-and-runs.mdx
@@ -0,0 +1,55 @@
+---
+title: "Calls & Runs"
+description: "The lifecycle of a call and how runs capture its results"
+---
+
+Every time a workflow executes, Dograh creates a **run**. The run is the record of that execution: what was said, what data was collected, how long it took, and what it cost.
+
+## Calls vs runs
+
+A **call** is the audio connection — whether over the phone via a telephony provider, or through the browser via Web Call.
+
+A **run** is the Dograh record of the workflow execution. Every call — outbound, inbound, web, or campaign — creates a run with the same contents: transcript, recording, gathered context, usage, and cost. Campaign runs are additionally linked to their parent campaign.
+
+## Call lifecycle
+
+The call lifecycle tracks the telephony connection — from the moment a number is dialed to when the line drops.
+
+```mermaid
+stateDiagram-v2
+ [*] --> Ringing: Number dialed
+ Ringing --> Connected: Caller answers
+ Ringing --> Ended: No answer / voicemail
+ Connected --> Ended: Conversation completes
+ Connected --> Ended: Error or disconnect
+ Ended --> [*]
+```
+
+For inbound calls, the flow starts when the caller dials in and the telephony provider routes the call to Dograh.
+
+
+## Inbound vs outbound
+
+**Outbound calls** are initiated by Dograh — you trigger them via the API or dashboard with a phone number and agent. Used for proactive outreach, reminders, and campaigns.
+
+**Inbound calls** are initiated by the caller — your telephony provider routes incoming calls to a Dograh agent via a webhook URL. Used for support lines, hotlines, and IVR replacement.
+
+## Web Calls
+
+Web Call lets you talk to your agent directly from the browser — no phone number or telephony setup required. It runs the full pipeline: STT, LLM, TTS, recording, and transcript, exactly the same as a phone call.
+
+Use it to try out your agent before going live. The run view shows the live transcript as the conversation progresses, node transitions as the workflow moves through the graph, and any tool or function calls the agent makes in real time.
+
+## What a run contains
+
+After a call completes, the run record includes:
+
+| Field | Description |
+|---|---|
+| `status` | Final run state |
+| `recording_url` | Download URL for the call audio |
+| `transcript_url` | Download URL for the conversation transcript |
+| `gathered_context` | Structured data extracted by the agent during the call |
+| `initial_context` | The data passed in when the call was triggered |
+| `usage_info` | Duration in seconds, token count |
+| `cost_info` | Cost in USD |
diff --git a/docs/core-concepts/campaigns.mdx b/docs/core-concepts/campaigns.mdx
new file mode 100644
index 0000000..2f3ff54
--- /dev/null
+++ b/docs/core-concepts/campaigns.mdx
@@ -0,0 +1,100 @@
+---
+title: "Campaigns"
+sidebarTitle: "Campaigns (Bulk Outbound Calls)"
+description: "Running a voice agent against a list of contacts at scale"
+---
+
+A campaign is how you run a workflow against many contacts automatically. Instead of triggering calls one by one via the API, you upload a list of phone numbers and Dograh dials them for you — respecting scheduling windows, concurrency limits, and retry rules.
+
+## How a campaign works
+
+```mermaid
+flowchart LR
+ CSV[Contacts CSV] --> Upload[Upload to Dograh]
+ Upload --> Campaign[Create Campaign]
+ Campaign --> Schedule[Scheduling & Concurrency]
+ Schedule --> Calls[Outbound Calls]
+ Calls --> Runs[Run Records]
+ Runs --> Results[Progress & Reports]
+```
+
+1. **Upload a contacts CSV** — must have a `phone_number` column; any extra columns become `initial_context` for each call
+2. **Create the campaign** — link it to a workflow, set concurrency, time slots, and retry behaviour
+3. **Start it** — Dograh begins dialing contacts up to your concurrency limit
+4. **Monitor progress** — track processed, completed, failed, and pending counts in real time
+5. **Pause and resume** — stop and restart at any point without losing progress
+
+## The contacts CSV
+
+The CSV drives the campaign. Each row is one contact.
+
+```csv
+phone_number,customer_name,account_id,plan
++14155550100,Jane Smith,acc_001,premium
++14155550101,Bob Jones,acc_002,basic
+```
+
+Columns beyond `phone_number` are automatically passed as `initial_context` to each call, making them available as template variables in your agent's prompt — so each call can feel personalised at scale.
+
+## Scheduling and concurrency
+
+**Concurrency** controls how many calls run simultaneously. It's capped by your telephony plan. Set it conservatively to start.
+
+**Time slots** restrict when Dograh is allowed to dial — useful for respecting business hours or regulations:
+
+```json
+{
+ "timezone": "America/New_York",
+ "time_slots": [
+ { "day": "monday", "start": "09:00", "end": "17:00" },
+ { "day": "tuesday", "start": "09:00", "end": "17:00" }
+ ]
+}
+```
+
+If no time slots are set, Dograh dials continuously once the campaign is started.
+
+## Retry behaviour
+
+Dograh can automatically retry contacts who didn't answer, were busy, or went to voicemail:
+
+```json
+{
+ "retry_config": {
+ "max_attempts": 3,
+ "retry_interval_minutes": 60
+ }
+}
+```
+
+## Circuit breaker
+
+The circuit breaker automatically pauses a campaign when the call failure rate gets too high — protecting against wasted spend and telephony reputation issues caused by a misconfigured agent or a bad contact list.
+
+When enabled, Dograh monitors the failure rate within a rolling time window. If it exceeds the threshold, the campaign is paused automatically and must be manually resumed after the issue is investigated.
+
+| Setting | Default | Description |
+|---|---|---|
+| Failure Threshold (%) | `50` | Pause when the failure rate within the window exceeds this percentage |
+| Window (seconds) | `120` | Rolling time window over which the failure rate is calculated |
+| Min Calls in Window | `5` | Minimum number of calls required before the circuit breaker can trip — prevents false positives on small samples |
+
+A campaign paused by the circuit breaker behaves the same as a manually paused campaign — in-flight calls complete normally, and it can be resumed once the underlying issue is resolved.
+
+## Campaign lifecycle
+
+| Status | Meaning |
+|---|---|
+| `draft` | Created but not started |
+| `running` | Actively dialing |
+| `paused` | Stopped; resumes from where it left off |
+| `completed` | All contacts processed |
+| `failed` | Encountered a fatal error |
+
+You can pause and resume a campaign at any time. In-flight calls complete normally before a pause takes effect.
+
+## Results
+
+Each contact's call creates a run record with the full transcript, recording, and gathered context — same as a manually triggered call. Use the [Get Campaign Runs](/api-reference/campaigns/runs) endpoint to retrieve them all.
+
+See the [Campaigns API reference](/api-reference/campaigns) to get started.
diff --git a/docs/core-concepts/context-and-variables.mdx b/docs/core-concepts/context-and-variables.mdx
new file mode 100644
index 0000000..ff9851e
--- /dev/null
+++ b/docs/core-concepts/context-and-variables.mdx
@@ -0,0 +1,80 @@
+---
+title: "Context & Variables"
+description: "How data flows into, through, and out of a conversation"
+---
+
+Dograh has a simple data model for passing information through a call. Understanding it is key to building agents that feel personalised and to extracting useful results after a call.
+
+## The three context objects
+
+```
+initial_context ──► Agent ──► gathered_context
+ │
+ [template variables](/voice-agent/template-variables)
+ (used in prompts)
+```
+
+### initial_context
+
+Data available to the agent before the call starts — the contact's name, account details, appointment information, anything the agent should know upfront. It can be set from several places:
+
+- **API trigger** — pass it in the request body when calling `POST /public/agent/{uuid}` or `POST /telephony/initiate-call`
+- **Campaign CSV** — columns beyond `phone_number` automatically become `initial_context` fields for each contact's call
+- **Dashboard** — set default template context variables on the agent, used when no external context is provided
+
+```json
+{
+ "phone_number": "+14155550100",
+ "initial_context": {
+ "customer_name": "Jane Smith",
+ "plan": "premium",
+ "renewal_date": "April 1"
+ }
+}
+```
+
+### Template variables
+
+Values from `initial_context` are available in your agent's prompt using `{{double_brace}}` syntax.
+
+```
+You are calling {{customer_name}} about their {{plan}} plan,
+which renews on {{renewal_date}}. Be friendly and confirm
+whether they'd like to continue.
+```
+
+When the call starts, Dograh substitutes the values before sending the prompt to the LLM — so the agent speaks naturally as if it already knows the contact.
+
+### gathered_context
+
+Data the agent collects *during* the call. You configure what to extract in the agent node's extraction settings — each variable has a name, type, and a prompt that tells the LLM what to look for.
+
+
+
+`gathered_context` is returned in the run record after the call completes and is available in [webhook payloads](/developer/webhooks) for downstream processing.
+
+## Data flow example
+
+```mermaid
+sequenceDiagram
+ participant App as Your System
+ participant Dog as Dograh
+ participant LLM as LLM
+
+ App->>Dog: initial_context: {customer_name: "Jane", plan: "premium"}
+ Dog->>LLM: Prompt with {{customer_name}} and {{plan}} substituted
+ LLM-->>Dog: Conversation response
+ Note over Dog,LLM: Call progresses...
+ Dog->>LLM: Extract: did the customer confirm renewal?
+ LLM-->>Dog: gathered_context: {renewal_confirmed: true}
+ Dog-->>App: Run record with gathered_context
+```
+
+## Where variables are available
+
+| Location | Variables available |
+|---|---|
+| Agent node prompts | `initial_context` fields via `{{variable_name}}` |
+| Edge conditions | Evaluated against the live conversation — no explicit variable syntax needed |
+| Webhook payload templates | All context objects via `{{initial_context.field}}`, `{{gathered_context.field}}` etc. |
+| Campaign CSV columns | CSV columns beyond `phone_number` become `initial_context` fields automatically |
diff --git a/docs/core-concepts/how-dograh-works.mdx b/docs/core-concepts/how-dograh-works.mdx
new file mode 100644
index 0000000..2b5eba1
--- /dev/null
+++ b/docs/core-concepts/how-dograh-works.mdx
@@ -0,0 +1,87 @@
+---
+title: "How Dograh Works"
+description: "The big picture — from API call to phone conversation to transcript"
+---
+
+Dograh is a platform for building and running voice AI agents. You define a conversation flow, connect a phone number, and Dograh handles the rest — transcribing the caller's speech (STT), generating intelligent responses (LLM), speaking them back in a natural voice (TTS), and returning structured results when the call ends.
+
+## The core loop
+
+```mermaid
+sequenceDiagram
+ participant U as Dashboard / Your App
+ participant API as Dograh API
+ participant STT as Transcriber (STT)
+ participant LLM as LLM Provider
+ participant TTS as Voice Synthesizer (TTS)
+ participant Tel as Telephony Provider
+ participant Cal as Caller / Contact
+
+ U->>API: Trigger call (dashboard or API)
+ API->>Tel: Initiate outbound call
+ Tel->>Cal: Phone rings
+ Cal-->>Tel: Answers
+ Tel-->>API: Raw audio stream
+ loop Conversation
+ API->>STT: Caller audio
+ STT-->>API: Transcribed text
+ API->>LLM: Transcript + agent prompt + context
+ LLM-->>API: Agent response text
+ API->>TTS: Response text
+ TTS-->>API: Synthesized audio
+ API->>Tel: Audio stream
+ Tel->>Cal: Agent speaks
+ end
+ API->>API: Extract context, run webhooks
+ API-->>U: Run record (transcript, recording, gathered data)
+```
+
+## Key components
+
+**Workflows (Agents)**
+The conversation logic. A workflow is a graph of nodes (conversation steps) connected by edges (conditional transitions). You define what the agent says, when it moves on, and what data it collects.
+
+**Runs**
+Every execution of a workflow creates a run. The run record holds the transcript, recording, extracted data, and cost information.
+
+**Telephony**
+The phone infrastructure. Dograh connects to your telephony provider (Twilio, Vonage, etc.) to place and receive calls. The audio streams between the caller and Dograh in real time.
+
+**Transcriber (STT)**
+Converts the caller's speech to text in real time. Dograh sends the audio stream to your configured speech-to-text provider and uses the transcript to drive both the LLM and the final run record.
+
+**LLM Provider**
+Processes the transcript and the active node's prompt to generate the agent's next response. It also evaluates edge conditions to decide when to move the conversation forward.
+
+**Voice Synthesizer (TTS)**
+Converts the LLM's text response to audio and streams it back to the caller. The choice of TTS provider and voice is configurable per agent.
+
+## How it fits together
+
+When you trigger a call:
+
+1. Dograh instructs your telephony provider to dial the number
+2. When the caller answers, a real-time audio pipeline opens
+3. The caller's speech is transcribed by the STT provider
+4. The transcript is sent to the LLM with the active node's prompt and conversation history
+5. The LLM responds — the response is synthesized to audio by the TTS provider and streamed to the caller
+6. When an edge condition is met, Dograh transitions to the next node
+7. When an end node is reached, the call ends
+8. Post-call: context is extracted, webhooks fire, the run record is saved
+
+## Next steps
+
+
+
+ How the conversation graph works
+
+
+ The lifecycle of a call
+
+
+ How data flows through a conversation
+
+
+ Running agents at scale
+
+
diff --git a/docs/core-concepts/workflows-and-agents.mdx b/docs/core-concepts/workflows-and-agents.mdx
new file mode 100644
index 0000000..b0173fc
--- /dev/null
+++ b/docs/core-concepts/workflows-and-agents.mdx
@@ -0,0 +1,60 @@
+---
+title: "Workflows & Agents"
+description: "How conversation flows are defined in Dograh"
+---
+
+In Dograh, what you see as an **agent** in the dashboard is called a **workflow** in the API. They are the same thing — a workflow is the underlying definition, agent is the product name for it.
+
+
+Anywhere the API says `workflow`, think "agent". Anywhere the API says `workflow_definition`, think "the conversation logic inside your agent".
+
+
+## The graph model
+
+A workflow is a **directed graph** — a set of nodes connected by edges.
+
+```mermaid
+graph LR
+ A[Start Call] -->|Caller greets| B[Qualify Intent]
+ B -->|Wants support| C[Support Agent]
+ B -->|Wants sales| D[Sales Agent]
+ C -->|Issue resolved| E[End Call]
+ D -->|Demo booked| E
+```
+
+**Nodes** are the steps in the conversation. Each node has a prompt that tells the LLM what to say and do at that point.
+
+**Edges** are the transitions between nodes. Each edge has a condition — a natural language description of when to move on. The LLM evaluates whether the condition has been met based on the conversation so far.
+
+## Node types
+
+| Type | What it does |
+|---|---|
+| `startCall` | Entry point for telephony calls. The first thing the agent says when a call connects |
+| `agentNode` | An LLM-powered conversation step. The core building block |
+| `globalNode` | Defines instructions that apply across all agent nodes (e.g. tone, language, fallback behaviour) |
+| `endCall` | Terminates the call |
+| `trigger` | Entry point for API-triggered runs (non-telephony) |
+| `webhook` | Fires an HTTP request when reached — use for CRM updates, notifications, etc. |
+| `qa` | Runs automated quality analysis on the completed call |
+
+## Edges and transitions
+
+An edge connects two nodes and fires when its condition is satisfied:
+
+
+
+`transition_speech` is optional — if set, the agent speaks it before moving to the next node.
+
+## Versioning
+
+Every time you update a workflow's `workflow_definition`, Dograh saves a new version while keeping the history. The current version is always what runs. Old versions are retained for auditing.
+
+## Creating workflows
+
+There are two ways to create a workflow via the API:
+
+- **From a definition** — provide the full node/edge graph yourself. Best for programmatic generation.
+- **From a template** — describe the use case in natural language and Dograh generates the initial graph using an LLM. Best for getting started quickly.
+
+See the [Workflow Definition Schema](/developer/workflow-schema) for the full field reference.
diff --git a/docs/developer/environment-variables.mdx b/docs/developer/environment-variables.mdx
new file mode 100644
index 0000000..f39d3b0
--- /dev/null
+++ b/docs/developer/environment-variables.mdx
@@ -0,0 +1,144 @@
+---
+title: "Environment Variables"
+description: "Complete reference for all environment variables used by the Dograh backend"
+---
+
+Core environment variables are centralized in `api/constants.py`. Variables marked **Required** in the description must be explicitly set — the application will either fail to boot or behave insecurely without them.
+
+## Deployment Modes
+
+Dograh supports two deployment modes, set via `DEPLOYMENT_MODE`:
+
+- **OSS**: The default mode. Designed for self-hosted deployments using [Docker Compose](/deployment/docker) — the fastest way to get Dograh running. Uses local JWT authentication and MinIO for storage.
+- **SaaS**: Intended for customised deployments outside of Docker. Authentication and API key management are handled through Dograh Managed Platform Services (MPS), allowing greater flexibility in how the platform is hosted and integrated.
+
+The relevant required variables for each mode are noted in the descriptions below.
+
+---
+
+## Application
+
+| Variable | Default | Description |
+|---|---|---|
+| `ENVIRONMENT` | `local` | Runtime environment. Affects logging and behaviour. One of `local`, `production`, `test` |
+| `DEPLOYMENT_MODE` | `oss` | Deployment mode. Use `oss` for self-hosted |
+| `AUTH_PROVIDER` | `local` | Authentication provider. Use `local` for OSS |
+| `ENABLE_TRACING` | `false` | Enable distributed tracing via [Langfuse](/configurations/tracing) |
+
+---
+
+## Database
+
+| Variable | Default | Description |
+|---|---|---|
+| `DATABASE_URL` | N/A | **Required.** PostgreSQL connection string. e.g. `postgresql+asyncpg://user:pass@host:5432/dbname` |
+| `REDIS_URL` | N/A | **Required.** Redis connection string. e.g. `redis://localhost:6379` |
+
+---
+
+## Authentication (OSS)
+
+| Variable | Default | Description |
+|---|---|---|
+| `OSS_JWT_SECRET` | N/A | **Required for OSS deployments.** Secret used to sign JWT tokens. Must be set to a strong random value in production |
+| `OSS_JWT_EXPIRY_HOURS` | `720` | JWT token lifetime in hours (default: 30 days) |
+
+
+Never use the placeholder `OSS_JWT_SECRET` in a production deployment. Generate a strong random secret and store it securely.
+
+
+---
+
+## URLs
+
+| Variable | Default | Description |
+|---|---|---|
+| `BACKEND_API_ENDPOINT` | `http://localhost:8000` | Internal URL of the backend API |
+| `UI_APP_URL` | `http://localhost:3010` | URL of the frontend application |
+| `MPS_API_URL` | `https://services.dograh.com` | Dograh Managed Platform Services URL |
+| `DOGRAH_MPS_SECRET_KEY` | `null` | **Required for non-OSS deployments.** Secret key for authenticating with MPS |
+
+---
+
+## Storage
+
+Dograh uses **MinIO by default**, which is bundled with the self-hosted deployment and requires no external setup. Set `ENABLE_AWS_S3=true` to switch to AWS S3 — typically used for cloud or managed deployments where S3 is already part of the infrastructure.
+
+### MinIO (OSS default)
+
+| Variable | Default | Description |
+|---|---|---|
+| `MINIO_ENDPOINT` | `localhost:9000` | MinIO server host and port |
+| `MINIO_PUBLIC_ENDPOINT` | `null` | Publicly accessible MinIO URL (for download links) |
+| `MINIO_ACCESS_KEY` | N/A | **Required for OSS deployments.** MinIO access key. Must be set to a secure value in production |
+| `MINIO_SECRET_KEY` | N/A | **Required for OSS deployments.** MinIO secret key. Must be set to a secure value in production |
+| `MINIO_BUCKET` | `voice-audio` | Bucket name for audio files |
+| `MINIO_SECURE` | `false` | Use HTTPS for MinIO connections |
+
+### AWS S3 (alternative)
+
+| Variable | Default | Description |
+|---|---|---|
+| `ENABLE_AWS_S3` | `false` | Set to `true` to use AWS S3 instead of MinIO |
+| `S3_BUCKET` | `null` | S3 bucket name |
+| `S3_REGION` | `us-east-1` | AWS region |
+
+---
+
+## WebRTC
+
+| Variable | Default | Description |
+|---|---|---|
+| `TURN_HOST` | `localhost` | TURN server hostname for WebRTC NAT traversal |
+| `TURN_PORT` | `3478` | TURN server port |
+| `TURN_TLS_PORT` | `5349` | TURN server TLS port |
+| `TURN_SECRET` | `null` | **Required for WebRTC.** Shared secret for TURN credential generation |
+| `TURN_CREDENTIAL_TTL` | `86400` | TURN credential validity in seconds (default: 24h) |
+
+---
+
+## Tracing (Langfuse)
+
+| Variable | Default | Description |
+|---|---|---|
+| `LANGFUSE_HOST` | `null` | Langfuse server URL |
+| `LANGFUSE_PUBLIC_KEY` | `null` | Langfuse public key |
+| `LANGFUSE_SECRET_KEY` | `null` | Langfuse secret key |
+
+Set `ENABLE_TRACING=true` alongside these to activate LLM call tracing. See the [Tracing guide](/configurations/tracing) for setup instructions.
+
+---
+
+## Monitoring
+
+| Variable | Default | Description |
+|---|---|---|
+| `SENTRY_DSN` | `null` | Sentry DSN for error tracking |
+| `ENABLE_TELEMETRY` | `false` | Enable anonymous telemetry collection |
+
+---
+
+## Logging
+
+| Variable | Default | Description |
+|---|---|---|
+| `LOG_LEVEL` | `DEBUG` | Log level: `DEBUG`, `INFO`, `WARNING`, `ERROR` |
+| `LOG_FILE_PATH` | `null` | Write logs to this file path (in addition to stdout) |
+| `LOG_ROTATION_SIZE` | `100 MB` | Rotate log file when it reaches this size |
+| `LOG_RETENTION` | `7 days` | How long to keep rotated log files |
+| `LOG_COMPRESSION` | `gz` | Compression format for rotated logs |
+| `SERIALIZE_LOG_OUTPUT` | `false` | Output logs as JSON (useful for log aggregation) |
+
+---
+
+## Campaigns
+
+| Variable | Default | Description |
+|---|---|---|
+| `DEFAULT_ORG_CONCURRENCY_LIMIT` | `2` | Maximum concurrent outbound calls per organization |
+
+---
+
+## Further Customisation
+
+The variables documented here cover the standard configuration surface. For advanced customisation — such as integrating additional services or tuning internal behaviour — consult the relevant module alongside `api/constants.py` to understand how each variable is consumed.
diff --git a/docs/developer/webhooks.mdx b/docs/developer/webhooks.mdx
new file mode 100644
index 0000000..81dff12
--- /dev/null
+++ b/docs/developer/webhooks.mdx
@@ -0,0 +1,110 @@
+---
+title: "Webhook Payloads"
+description: "Context variables available in webhook nodes and the data Dograh sends after a call"
+---
+
+Dograh executes **webhook nodes** asynchronously after a workflow run completes. You configure the target URL, HTTP method, headers, and payload template directly in the workflow definition.
+
+---
+
+## How webhooks work
+
+1. A call completes (or a run finishes)
+2. Dograh executes any `webhook` nodes in the workflow asynchronously
+3. The payload template is rendered with the run's context and sent as a JSON `POST` (or your configured method) to your endpoint
+4. Non-200 responses are logged but do not block or retry by default (configure `retry_config` to change this)
+
+---
+
+## Payload context variables
+
+The following variables are available in your `payload_template` using double-brace syntax (e.g. `{{workflow_run_id}}`):
+
+| Variable | Type | Description |
+|---|---|---|
+| `workflow_run_id` | integer | ID of the completed run |
+| `workflow_run_name` | string | Name of the run |
+| `workflow_id` | integer | ID of the workflow |
+| `workflow_name` | string | Name of the workflow |
+| `initial_context` | object | Context passed when the call was initiated |
+| `gathered_context` | object | Data extracted during the call by agent nodes |
+| `cost_info` | object | Call cost breakdown |
+| `annotations` | object | QA analysis results (if a `qa` node is configured) |
+| `recording_url` | string \| null | Public download URL for the call recording |
+| `transcript_url` | string \| null | Public download URL for the call transcript |
+
+### Example payload template
+
+```json
+{
+ "run_id": "{{workflow_run_id}}",
+ "customer": "{{initial_context.customer_name}}",
+ "outcome": "{{gathered_context.resolution}}",
+ "recording": "{{recording_url}}"
+}
+```
+
+---
+
+## Authentication
+
+Webhook requests support the following authentication methods, configured via a stored credential:
+
+| Type | Description |
+|---|---|
+| `NONE` | No authentication |
+| `API_KEY` | Sends the key in a custom header (e.g. `X-API-Key`) |
+| `BEARER_TOKEN` | Sends `Authorization: Bearer ` |
+| `BASIC_AUTH` | HTTP Basic authentication (username + password) |
+| `CUSTOM_HEADER` | Any custom header key-value pair |
+
+---
+
+## Receiving webhooks
+
+Your endpoint should:
+
+- Accept `POST` requests with `Content-Type: application/json`
+- Respond with a `2xx` status code promptly (within 30 seconds)
+- Handle duplicate deliveries idempotently (retries may deliver the same payload more than once)
+
+### Minimal example receiver (Python)
+
+```python
+from fastapi import FastAPI, Request
+
+app = FastAPI()
+
+@app.post("/webhook/dograh")
+async def handle_dograh_webhook(request: Request):
+ payload = await request.json()
+ run_id = payload.get("run_id")
+ outcome = payload.get("outcome")
+ # process the call result...
+ return {"status": "ok"}
+```
+
+---
+
+## Webhook node in a workflow definition
+
+See [Workflow Definition Schema](/developer/workflow-schema#webhook-node) for the full configuration reference.
+
+```json
+{
+ "id": "webhook-1",
+ "type": "webhook",
+ "position": { "x": 600, "y": 0 },
+ "data": {
+ "name": "Notify CRM",
+ "enabled": true,
+ "http_method": "POST",
+ "endpoint_url": "https://your-service.com/webhook/dograh",
+ "payload_template": {
+ "run_id": "{{workflow_run_id}}",
+ "customer": "{{initial_context.customer_name}}",
+ "outcome": "{{gathered_context.resolution}}"
+ }
+ }
+}
+```
diff --git a/docs/developer/workflow-schema.mdx b/docs/developer/workflow-schema.mdx
new file mode 100644
index 0000000..8916d35
--- /dev/null
+++ b/docs/developer/workflow-schema.mdx
@@ -0,0 +1,197 @@
+---
+title: "Workflow Definition Schema"
+description: "Schema reference for the workflow_definition object used in the Agents API"
+---
+
+The `workflow_definition` object passed to [Create from Definition](/api-reference/agents/create-from-definition) and [Update Agent](/api-reference/agents/update) defines the full conversation graph. It is the same structure the dashboard's visual workflow builder reads and writes — building an agent in the UI produces a `workflow_definition` under the hood, and anything you can configure visually can equally be expressed here as JSON.
+
+```json
+{
+ "nodes": [...],
+ "edges": [...]
+}
+```
+
+---
+
+## Nodes
+
+Each node represents a step in the conversation.
+
+```json
+{
+ "id": "uuid-string",
+ "type": "agentNode",
+ "position": { "x": 100, "y": 200 },
+ "data": { ... }
+}
+```
+
+| Field | Type | Description |
+|---|---|---|
+| `id` | string | Unique node ID (UUID recommended) |
+| `type` | string | One of the node types below |
+| `position` | object | Visual coordinates in the workflow builder |
+| `data` | object | Node configuration — fields vary by type |
+
+### Node types
+
+| Type | Description |
+|---|---|
+| `startCall` | Entry point for telephony calls |
+| `endCall` | Terminates the call |
+| `agentNode` | LLM-powered conversation step |
+| `globalNode` | Global configuration applied across all agent nodes |
+| `trigger` | Entry point for API-triggered (non-telephony) runs |
+| `webhook` | Sends an HTTP request when reached |
+| `qa` | Runs quality analysis on the completed call |
+
+---
+
+## Node data fields
+
+### Common fields (all node types)
+
+| Field | Type | Default | Description |
+|---|---|---|---|
+| `name` | string | required | Display name for the node |
+| `prompt` | string | required* | LLM system prompt. *Not required for `trigger`, `webhook`, `qa` nodes |
+| `allow_interrupt` | boolean | `false` | Allow the caller to interrupt the agent mid-speech |
+| `wait_for_user_response` | boolean | `false` | Pause and wait for caller input before continuing |
+| `wait_for_user_response_timeout` | number | `null` | Seconds to wait for input before timing out |
+| `detect_voicemail` | boolean | `false` | Detect and handle voicemail on outbound calls |
+| `delayed_start` | boolean | `false` | Delay execution of this node |
+| `delayed_start_duration` | number | `null` | Delay in seconds |
+| `add_global_prompt` | boolean | `true` | Merge the `globalNode` prompt into this node's prompt |
+
+### agentNode — data extraction
+
+| Field | Type | Default | Description |
+|---|---|---|---|
+| `extraction_enabled` | boolean | `false` | Extract structured data from the conversation |
+| `extraction_prompt` | string | `null` | Custom prompt to guide extraction |
+| `extraction_variables` | array | `[]` | Variables to extract (see below) |
+
+**Extraction variable schema:**
+
+```json
+{
+ "name": "customer_intent",
+ "type": "string",
+ "prompt": "What did the customer want to achieve?"
+}
+```
+
+`type` is one of `string`, `number`, or `boolean`.
+
+### agentNode — tools
+
+| Field | Type | Description |
+|---|---|---|
+| `tool_uuids` | string[] | IDs of tools (HTTP API, call transfer, etc.) to attach to this node |
+| `document_uuids` | string[] | IDs of knowledge base documents available to this node |
+
+### trigger node
+
+| Field | Type | Description |
+|---|---|---|
+| `trigger_path` | string | Unique UUID that becomes the API trigger endpoint path |
+
+### webhook node
+
+| Field | Type | Default | Description |
+|---|---|---|---|
+| `enabled` | boolean | `true` | Whether this webhook fires when reached |
+| `http_method` | string | — | `GET`, `POST`, `PUT`, `PATCH`, or `DELETE` |
+| `endpoint_url` | string | — | Target URL |
+| `credential_uuid` | string | `null` | UUID of a stored auth credential |
+| `custom_headers` | array | `[]` | Additional request headers `[{"key": "...", "value": "..."}]` |
+| `payload_template` | object | `null` | Request body template (supports context variables) |
+
+### qa node
+
+| Field | Type | Default | Description |
+|---|---|---|---|
+| `qa_enabled` | boolean | `true` | Enable QA analysis |
+| `qa_system_prompt` | string | `null` | Custom evaluation prompt |
+| `qa_model` | string | `null` | LLM model to use for evaluation |
+| `qa_min_call_duration` | integer | `15` | Minimum call duration in seconds to run QA |
+| `qa_voicemail_calls` | boolean | `false` | Include voicemail calls in QA |
+| `qa_sample_rate` | integer | `100` | Percentage of calls to analyse (1–100) |
+
+---
+
+## Edges
+
+Each edge connects two nodes and defines when the transition fires.
+
+```json
+{
+ "id": "edge-uuid",
+ "source": "node-uuid-a",
+ "target": "node-uuid-b",
+ "data": {
+ "label": "Customer confirms",
+ "condition": "The customer has confirmed their appointment",
+ "transition_speech": "Great, I've got that noted."
+ }
+}
+```
+
+| Field | Type | Description |
+|---|---|---|
+| `id` | string | Unique edge ID |
+| `source` | string | ID of the originating node |
+| `target` | string | ID of the destination node |
+| `data.label` | string | Short label shown in the workflow builder |
+| `data.condition` | string | Natural language condition the LLM evaluates to trigger this edge |
+| `data.transition_speech` | string | Optional speech the agent says before transitioning |
+
+---
+
+## Validation rules
+
+- All `source` and `target` IDs in edges must reference existing node IDs
+- All nodes except `trigger`, `webhook`, and `qa` must have a non-empty `prompt`
+- Node IDs must be unique within the workflow
+- Each workflow must have exactly one `startCall` or `trigger` node as the entry point
+
+---
+
+## Minimal example
+
+```json
+{
+ "nodes": [
+ {
+ "id": "start-1",
+ "type": "startCall",
+ "position": { "x": 0, "y": 0 },
+ "data": {
+ "name": "Start",
+ "prompt": "You are a friendly assistant. Greet the caller and ask how you can help."
+ }
+ },
+ {
+ "id": "end-1",
+ "type": "endCall",
+ "position": { "x": 400, "y": 0 },
+ "data": {
+ "name": "End",
+ "prompt": "Thank the caller and say goodbye."
+ }
+ }
+ ],
+ "edges": [
+ {
+ "id": "edge-1",
+ "source": "start-1",
+ "target": "end-1",
+ "data": {
+ "label": "Done",
+ "condition": "The caller's question has been answered and they want to end the call"
+ }
+ }
+ ]
+}
+```
diff --git a/docs/docs.json b/docs/docs.json
index 37c8809..df1ea54 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -12,6 +12,7 @@
"tabs": [
{
"tab": "Guides",
+ "icon": "book-open",
"groups": [
{
"group": "Getting started",
@@ -26,6 +27,16 @@
}
]
},
+ {
+ "group": "Core Concepts",
+ "pages": [
+ "core-concepts/how-dograh-works",
+ "core-concepts/workflows-and-agents",
+ "core-concepts/calls-and-runs",
+ "core-concepts/context-and-variables",
+ "core-concepts/campaigns"
+ ]
+ },
{
"group": "Configurations",
"pages": [
@@ -75,10 +86,31 @@
]
},
{
- "group": "Contribution",
+ "group": "Telephony",
"pages": [
- "contribution/introduction",
- "contribution/setup"
+ "integrations/telephony/overview",
+ "integrations/telephony/inbound",
+ "integrations/telephony/twilio",
+ "integrations/telephony/vonage",
+ "integrations/telephony/cloudonix",
+ "integrations/telephony/vobiz",
+ "integrations/telephony/asterisk-ari",
+ "integrations/telephony/webhooks",
+ "integrations/telephony/custom"
+ ]
+ }
+ ]
+ },
+ {
+ "tab": "Developer",
+ "icon": "code",
+ "groups": [
+ {
+ "group": "Guides",
+ "pages": [
+ "developer/workflow-schema",
+ "developer/webhooks",
+ "developer/environment-variables"
]
},
{
@@ -92,24 +124,88 @@
]
},
{
- "group": "Features",
+ "group": "Contribution",
"pages": [
- "features/campaigns",
- "features/looptalk"
+ "contribution/introduction",
+ "contribution/setup"
+ ]
+ }
+ ]
+ },
+ {
+ "tab": "API Reference",
+ "icon": "square-terminal",
+ "groups": [
+ {
+ "group": "Resources",
+ "pages": [
+ {
+ "group": "API Keys",
+ "pages": [
+ "api-reference/api-keys",
+ "api-reference/api-keys/create",
+ "api-reference/api-keys/list",
+ "api-reference/api-keys/archive",
+ "api-reference/api-keys/reactivate"
+ ]
+ },
+ {
+ "group": "Agents",
+ "pages": [
+ "api-reference/agents",
+ "api-reference/agents/create-from-definition",
+ "api-reference/agents/create-from-template",
+ "api-reference/agents/list",
+ "api-reference/agents/count",
+ "api-reference/agents/get",
+ "api-reference/agents/update",
+ "api-reference/agents/archive",
+ "api-reference/agents/validate",
+ {
+ "group": "Runs",
+ "pages": [
+ "api-reference/agents/runs/create",
+ "api-reference/agents/runs/list",
+ "api-reference/agents/runs/get"
+ ]
+ }
+ ]
+ },
+ {
+ "group": "Calls",
+ "pages": [
+ "api-reference/calls",
+ "api-reference/calls/trigger",
+ "api-reference/calls/initiate",
+ "api-reference/calls/get-run",
+ "api-reference/calls/download",
+ "api-reference/calls/inbound"
+ ]
+ },
+ {
+ "group": "Campaigns",
+ "pages": [
+ "api-reference/campaigns",
+ "api-reference/campaigns/upload-contacts",
+ "api-reference/campaigns/create",
+ "api-reference/campaigns/list",
+ "api-reference/campaigns/get",
+ "api-reference/campaigns/update",
+ "api-reference/campaigns/start",
+ "api-reference/campaigns/pause",
+ "api-reference/campaigns/resume",
+ "api-reference/campaigns/progress",
+ "api-reference/campaigns/runs"
+ ]
+ }
]
},
{
- "group": "Telephony",
+ "group": "Authentication & Errors",
"pages": [
- "integrations/telephony/overview",
- "integrations/telephony/inbound",
- "integrations/telephony/twilio",
- "integrations/telephony/vonage",
- "integrations/telephony/cloudonix",
- "integrations/telephony/vobiz",
- "integrations/telephony/asterisk-ari",
- "integrations/telephony/webhooks",
- "integrations/telephony/custom"
+ "api-reference/overview",
+ "api-reference/authentication",
+ "api-reference/errors"
]
}
]
@@ -137,18 +233,19 @@
"search": {
"prompt": "Search for Tools, Webhook, Deployment, etc..."
},
+ "openapi": "/api-reference/openapi.json",
"customCSS": "/custom.css",
"contextual": {
"options": [
- "copy",
- "view",
- "chatgpt",
- "claude",
- "perplexity",
- "mcp",
- "cursor",
- "vscode"
- ]
+ "copy",
+ "view",
+ "chatgpt",
+ "claude",
+ "perplexity",
+ "mcp",
+ "cursor",
+ "vscode"
+ ]
},
"footer": {
"socials": {
@@ -156,4 +253,4 @@
"linkedin": "https://linkedin.com/company/dograh"
}
}
-}
+}
\ No newline at end of file
diff --git a/docs/features/campaigns.mdx b/docs/features/campaigns.mdx
deleted file mode 100644
index 07ca9ac..0000000
--- a/docs/features/campaigns.mdx
+++ /dev/null
@@ -1,14 +0,0 @@
----
-title: "Campaigns"
-description: "Campaigns are how you can do outbound calling to your contacts."
----
-
-## Setting up
-
-It is recommended to setup telephony first using the documentation in [Telephony Integrations](/telephony/twilio).
-
-## Preparing the list of contacts
-
-You can upload a CSV list on the platform which will be used to make the calls.
-
-Rest of the documentation coming soon..
diff --git a/docs/features/looptalk.mdx b/docs/features/looptalk.mdx
deleted file mode 100644
index 55c35f8..0000000
--- a/docs/features/looptalk.mdx
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "Looptalk"
-description: "You can use Looptalk to test your voice agent against another voice agent. This way, you can test your voice agents at scale and iteratively improve the Agent's prompts."
----
-
-## Setting up
-
-Documentation coming soon..
diff --git a/docs/images/edge.png b/docs/images/edge.png
new file mode 100644
index 0000000..61e6f51
Binary files /dev/null and b/docs/images/edge.png differ
diff --git a/docs/images/extracted_variables.png b/docs/images/extracted_variables.png
new file mode 100644
index 0000000..2fcc2f5
Binary files /dev/null and b/docs/images/extracted_variables.png differ
diff --git a/docs/images/node.png b/docs/images/node.png
new file mode 100644
index 0000000..7a111b7
Binary files /dev/null and b/docs/images/node.png differ
diff --git a/docs/voice-agent/editing-a-workflow.mdx b/docs/voice-agent/editing-a-workflow.mdx
index 9cae6e1..03c394e 100644
--- a/docs/voice-agent/editing-a-workflow.mdx
+++ b/docs/voice-agent/editing-a-workflow.mdx
@@ -29,7 +29,7 @@ Contains instructions applicable across the entire call:
## Node-Level Toggles
### Add Global Prompt
-- Recommended to inject Global Node instructions into most nodes
+- Recommended to inject [Global Node](/voice-agent/global) instructions into most nodes
### Allow Interruption
- **Default "On"**: Bot stops and responds to user interruption
@@ -46,7 +46,7 @@ Supported in Agent and End Call Nodes:
- Define name, type, and description
- Examples: customer name, budget, interest
-## Webhook Node
+## [Webhook Node](/voice-agent/webhook)
- Executed at call end
- Sends payload to specific endpoint
@@ -63,5 +63,5 @@ Supported in Agent and End Call Nodes:
## Pathways and Tool Calls
- Define agent node movement
-- Use tool calls to transition between nodes
+- Use [tool calls](/voice-agent/tools/http-api) to transition between nodes
- **"tool"** is a reserved keyword for function calls and actions
\ No newline at end of file
diff --git a/docs/voice-agent/template-variables.mdx b/docs/voice-agent/template-variables.mdx
index 3b81909..564a7ee 100644
--- a/docs/voice-agent/template-variables.mdx
+++ b/docs/voice-agent/template-variables.mdx
@@ -4,7 +4,7 @@ description: "You can use Template Variables in your prompts for your Agent node
---
### Template Rendering
-You can reference template variables which is passed as `initial_context` either using the API Trigger or when uploading a Sheet for a campaign. You can also use any extracted variable as `gathered_context`
+You can reference template variables which is passed as [`initial_context`](/core-concepts/context-and-variables#initial_context) either using the [API Trigger](/voice-agent/api-trigger) or when uploading a Sheet for a [campaign](/core-concepts/campaigns). You can also use any extracted variable as [`gathered_context`](/core-concepts/context-and-variables#gathered_context)
The template rendering can take nested values.
@@ -25,4 +25,4 @@ You can write your prompt to access the user's name as below
Prompt: `You are Alice, who is talking to {{initial_context.user.name}}.`
### Nodes
-Dograh Voice Agents are composed of various nodes. These nodes can provide instructions to the voice agent, help you setup a trigger where you can trigger the voice agent to call someone, or help you setup a webhook, where you can update the results of the call in your CRM or trigger a downstream workflow in n8n. In the next steps, we will be documenting the nodes that you can use in building the voice agent.
\ No newline at end of file
+Dograh Voice Agents are composed of various nodes. These nodes can provide instructions to the voice agent, help you setup a [trigger](/voice-agent/api-trigger) where you can trigger the voice agent to call someone, or help you setup a [webhook](/voice-agent/webhook), where you can update the results of the call in your CRM or trigger a downstream workflow in n8n. In the next steps, we will be documenting the nodes that you can use in building the voice agent.
\ No newline at end of file
diff --git a/docs/voice-agent/webhook.mdx b/docs/voice-agent/webhook.mdx
index fc53067..511ac5c 100644
--- a/docs/voice-agent/webhook.mdx
+++ b/docs/voice-agent/webhook.mdx
@@ -26,8 +26,8 @@ The payload can contain a valid JSON, and you can reference variables while cons
- `{{workflow_run_id}}` Unique ID of the Agent run
- `{{workflow_id}}` ID of the Agent
- `{{workflow_name}}` Name of the workflow
-- `{{initial_context.*}}` Initial context variables
-- `{{gathered_context.*}}` Extracted variables
+- `{{initial_context.*}}` [Initial context variables](/core-concepts/context-and-variables#initial_context)
+- `{{gathered_context.*}}` [Extracted variables](/core-concepts/context-and-variables#gathered_context)
- `{{cost_info.call_duration_seconds}}` Call duration
- `{{recording_url}}` Call recording URL
- `{{transcript_url}}` Transcript URL