# Lehar > Developer documentation for the Lehar voice-AI platform. - [Lehar Developer Docs](https://docs.lehar.ai/index.md): Integrate Lehar voice and WhatsApp AI agents into your product with REST APIs, sessions, campaigns, and webhooks. - [Platform](https://docs.lehar.ai/get-started/platform.md): How Lehar is put together: control plane, voice agent, and the media layer. - [Quickstart](https://docs.lehar.ai/get-started/quickstart.md): Create an agent session and connect a participant in a few steps. - [Agents](https://docs.lehar.ai/concepts/agents.md): Configured AI agents: prompt sections, variables, provider config, and the draft → published lifecycle. - [Agent Testing](https://docs.lehar.ai/concepts/agent-testing.md): Simulate real callers against a draft agent and grade the transcript before you publish. - [Sessions](https://docs.lehar.ai/concepts/sessions.md): A single voice call — web or outbound phone — from creation to termination. - [Calls](https://docs.lehar.ai/concepts/calls.md): Place a single outbound phone call from your backend with an API key. - [Campaigns](https://docs.lehar.ai/concepts/campaigns.md): Outbound programs that call or message many recipients, orchestrated durably. - [Channels](https://docs.lehar.ai/concepts/channels.md): The ways an agent can reach a user: web voice, outbound phone, and WhatsApp. - [Providers & Models](https://docs.lehar.ai/concepts/providers.md): Choose the LLM, speech-to-text, and text-to-speech providers per agent or per session. - [Pronunciation Dictionaries](https://docs.lehar.ai/concepts/pronunciation-dictionaries.md): Control how an agent says specific words — brand names, places, acronyms — across every voice. - [Knowledge Base](https://docs.lehar.ai/concepts/knowledge-base.md): Give agents retrieval-augmented answers from your own Q&A content. - [Analytics](https://docs.lehar.ai/concepts/analytics.md): Aggregate call volume, connect rate, duration, cost and latency across your workspace. - [Billing & Credits](https://docs.lehar.ai/concepts/billing.md): How usage becomes credits, and how to read your balance and ledger. - [Create & publish an agent](https://docs.lehar.ai/guides/create-agent.md): Build a draft agent, test it, and publish it so campaigns can use it. - [Make an outbound phone call](https://docs.lehar.ai/guides/outbound-phone.md): Have an agent dial a single recipient over the phone. - [Run your first campaign](https://docs.lehar.ai/guides/first-campaign.md): Create a voice campaign, add recipients, publish, start, and monitor it. - [Campaign lifecycle](https://docs.lehar.ai/guides/campaign-lifecycle.md): How an outbound voice campaign executes: durable orchestration, business-hours scheduling, retries, and pause/resume. - [WhatsApp campaigns](https://docs.lehar.ai/guides/whatsapp.md): Send an approved template, hold a conversation, and escalate to a voice call when the recipient wants one. - [Webhooks & Events](https://docs.lehar.ai/guides/webhooks.md): The platform's async event backbone — how results are captured and how to consume them. - [Individual-call compatibility API](https://docs.lehar.ai/guides/individual-call-compatibility.md): Point an existing Ringg individual-call integration at Lehar by changing only the host, key and base path. - [API Overview](https://docs.lehar.ai/api-reference/introduction.md): Base URL, authentication, errors, and pagination for the Lehar API. - [Authentication](https://docs.lehar.ai/api-reference/authentication.md): API keys, bearer login sessions, scopes, and which endpoints need which. - [Ping](https://docs.lehar.ai/api-reference/health/ping.md) - [Receive Session Update Webhook](https://docs.lehar.ai/api-reference/webhooks/receive-session-update-webhook.md) - [Receive Inbound Session Bootstrap](https://docs.lehar.ai/api-reference/webhooks/receive-inbound-session-bootstrap.md): Inbound-call session bootstrap (BYON). - [Receive recording (egress) webhook](https://docs.lehar.ai/api-reference/webhooks/receive-recording-egress-webhook.md): Recording Service lifecycle events (started / updated / ended) that finalize the matching recording row. The path is part of the wire contract and is not renamed. - [Receive Whatsapp Webhook](https://docs.lehar.ai/api-reference/webhooks/receive-whatsapp-webhook.md) - [Signup](https://docs.lehar.ai/api-reference/auth/signup.md) - [Login](https://docs.lehar.ai/api-reference/auth/login.md) - [Me](https://docs.lehar.ai/api-reference/auth/me.md) - [Logout](https://docs.lehar.ai/api-reference/auth/logout.md) - [Validate Invitation](https://docs.lehar.ai/api-reference/auth/validate-invitation.md): Public: validate an invitation token so the accept page can render context. - [Accept Invitation](https://docs.lehar.ai/api-reference/auth/accept-invitation.md): Public: set a password for an invited user and log them in. - [Forgot Password](https://docs.lehar.ai/api-reference/auth/forgot-password.md): Public: request a password-reset email. Always returns 200 to avoid revealing whether an account exists for the given email (SEC-05). - [Validate Reset](https://docs.lehar.ai/api-reference/auth/validate-reset.md): Public: validate a password-reset token before showing the reset form. - [Reset Password](https://docs.lehar.ai/api-reference/auth/reset-password.md): Public: set a new password from a reset token and revoke existing sessions. - [Create agent](https://docs.lehar.ai/api-reference/agents/create-agent.md): Creates a draft agent. `id` is client-supplied. Prompt fields support `{{placeholders}}` filled from session `custom_variables`. Scope `sessions:write`. - [Get agent](https://docs.lehar.ai/api-reference/agents/get-agent.md): Fetches one agent by id (draft or published). Scope `sessions:read`. - [Update agent](https://docs.lehar.ai/api-reference/agents/update-agent.md): Updates a **draft** agent (partial). A published agent returns `409` — clone it to change it. Scope `sessions:write`. - [Delete Agent](https://docs.lehar.ai/api-reference/agents/delete-agent.md) - [Publish agent](https://docs.lehar.ai/api-reference/agents/publish-agent.md): Locks the config and makes the agent bindable by campaigns. One-way. Scope `sessions:write`. - [Clone agent](https://docs.lehar.ai/api-reference/agents/clone-agent.md): Copies an agent into a fresh draft (records the source in `template_agent_id`). Scope `sessions:write`. - [List agents](https://docs.lehar.ai/api-reference/agents/list-agents.md): Returns the agent catalog for the workspace (drafts and published). Scope `sessions:read`. - [Whatsapp Test Reply](https://docs.lehar.ai/api-reference/agents/whatsapp-test-reply.md): Drive the production WhatsApp reply engine for an in-dashboard test chat. - [List Suites](https://docs.lehar.ai/api-reference/agent-testing/list-suites.md) - [Create Suite](https://docs.lehar.ai/api-reference/agent-testing/create-suite.md) - [Generate Suite Route](https://docs.lehar.ai/api-reference/agent-testing/generate-suite-route.md): Auto-generate a reusable suite from an agent's config + judge criteria. - [Get Suite](https://docs.lehar.ai/api-reference/agent-testing/get-suite.md) - [Delete Suite](https://docs.lehar.ai/api-reference/agent-testing/delete-suite.md) - [Update Suite](https://docs.lehar.ai/api-reference/agent-testing/update-suite.md) - [Create Run](https://docs.lehar.ai/api-reference/agent-testing/create-run.md) - [List Runs](https://docs.lehar.ai/api-reference/agent-testing/list-runs.md) - [Get Run](https://docs.lehar.ai/api-reference/agent-testing/get-run.md) - [Delete Run](https://docs.lehar.ai/api-reference/agent-testing/delete-run.md) - [List Campaigns](https://docs.lehar.ai/api-reference/campaigns/list-campaigns.md) - [Create campaign](https://docs.lehar.ai/api-reference/campaigns/create-campaign.md): Creates a campaign as a `draft`. Bind the agent per channel: `voice_agent_id` for `voice`, `whatsapp_agent_id` for `whatsapp`, both for `whatsapp_voice`. The bound agent must be **published**. Scope `campaigns:write`. - [Get campaign](https://docs.lehar.ai/api-reference/campaigns/get-campaign.md): Reads one campaign record. Scope `campaigns:read`. - [Delete Campaign](https://docs.lehar.ai/api-reference/campaigns/delete-campaign.md) - [Update Campaign](https://docs.lehar.ai/api-reference/campaigns/update-campaign.md) - [List Campaign Recipients](https://docs.lehar.ai/api-reference/campaigns/list-campaign-recipients.md) - [Add recipients](https://docs.lehar.ai/api-reference/campaigns/add-recipients.md): Adds one recipient (a bare object) or many (`{ "recipients": [...] }`), deduplicated per `(campaign, phone)`. Stored numbers are masked in responses. Scope `campaigns:write`. - [Import Campaign Recipients](https://docs.lehar.ai/api-reference/campaigns/import-campaign-recipients.md) - [List attempts](https://docs.lehar.ai/api-reference/campaigns/list-attempts.md): Per-recipient dialing/messaging attempts. Scope `campaigns:read`. - [List Campaign Conversations](https://docs.lehar.ai/api-reference/campaigns/list-campaign-conversations.md) - [List Whatsapp Sessions](https://docs.lehar.ai/api-reference/campaigns/list-whatsapp-sessions.md): WhatsApp conversations as agent-scoped "sessions", across all campaigns. - [List Campaign Messages](https://docs.lehar.ai/api-reference/campaigns/list-campaign-messages.md) - [List campaign events](https://docs.lehar.ai/api-reference/campaigns/list-campaign-events.md): Append-only audit log of campaign transitions. Optional `recipient_id` filter. Scope `campaigns:read`. - [Start campaign](https://docs.lehar.ai/api-reference/campaigns/start-campaign.md): Starts (or resumes a paused) run. Needs at least one recipient and the Campaign Engine available. Any caller with `campaigns:write` can start — no admin role required. - [Pause Campaign](https://docs.lehar.ai/api-reference/campaigns/pause-campaign.md) - [Publish campaign](https://docs.lehar.ai/api-reference/campaigns/publish-campaign.md): Locks the config so the run is reproducible. Only a `draft` can be published. Scope `campaigns:write`. - [Reset Campaign Run](https://docs.lehar.ai/api-reference/campaigns/reset-campaign-run.md): Disabled. Re-running a finished campaign in place used to hard-delete its recipients (cascading to attempts) and reset it to ``published`` — a one-click, irreversible data-loss path. To run a finished campaign again, clone it (``POST /campaigns/{id}/clone``), which preserves the original and its res… - [Clone Campaign](https://docs.lehar.ai/api-reference/campaigns/clone-campaign.md) - [Get Billing Rate Catalog](https://docs.lehar.ai/api-reference/billing/get-billing-rate-catalog.md) - [Get My Billing Summary](https://docs.lehar.ai/api-reference/billing/get-my-billing-summary.md) - [Get My Billing Ledger](https://docs.lehar.ai/api-reference/billing/get-my-billing-ledger.md) - [List Customer Sessions](https://docs.lehar.ai/api-reference/sessions/list-customer-sessions.md) - [Create session](https://docs.lehar.ai/api-reference/sessions/create-session.md): Creates a voice session for the logged-in user and returns a `participant_token`. **Requires a bearer login session** — an API key alone returns `400`. Scope `sessions:write`. - [Get session](https://docs.lehar.ai/api-reference/sessions/get-session.md): Reads a session record. The `participant_token` is **never** returned on read — only at creation. Transcript and usage are delivered asynchronously via the session-update webhook. Scope `sessions:read`. - [Get Session Questionnaire](https://docs.lehar.ai/api-reference/sessions/get-session-questionnaire.md): Questionnaire results for a finished session: the questions, the answers, and the qualified verdict. Campaign sessions return the stored per-recipient answers; ad-hoc test sessions extract answers from the transcript on demand (the same pure path the campaign webhook uses), so you can see results wi… - [End Customer Session](https://docs.lehar.ai/api-reference/sessions/end-customer-session.md) - [Update Customer Session Status](https://docs.lehar.ai/api-reference/sessions/update-customer-session-status.md) - [List calls](https://docs.lehar.ai/api-reference/calls/list-calls.md): Scope `sessions:read`. - [Place an outbound call](https://docs.lehar.ai/api-reference/calls/place-an-outbound-call.md): Fires one outbound phone call, server-to-server. **Requires an `X-API-KEY` credential** — bearer logins and agent-session tokens are rejected even though they can carry `sessions:write`. Answers `200` with the call record; the call may not have dialled yet. The agent must be published and `channel=v… - [Get a call](https://docs.lehar.ai/api-reference/calls/get-a-call.md): The call record plus one `attempts` entry per dial, each its own session. Scope `sessions:read`. - [Cancel a call](https://docs.lehar.ai/api-reference/calls/cancel-a-call.md): Prevents further dials and ends the session if one is live. `409` if the call is already terminal. Scope `sessions:write`. - [Initiate individual call, v2 (compatibility)](https://docs.lehar.ai/api-reference/cu1/initiate-individual-call-v2-compatibility.md): Identical to `/cu1/v1/calls` — same handler, same request and response. v2 exists so a client already pointed at a v2 path does not have to change; its `number_pool_id` is accepted and ignored, because Lehar has no managed number pools. **Requires an `X-API-KEY` credential.** Scope `sessions:write`. - [Initiate individual call (compatibility)](https://docs.lehar.ai/api-reference/cu1/initiate-individual-call-compatibility.md): Drop-in compatible with the Ringg Initiate Individual Call contract, for migrating an existing integration without rewriting it. Translates onto the native POST /calls, which owns validation, idempotency and dispatch. Requires an X-API-KEY credential. Scope sessions:write. Prefer POST /calls for new… - [List webhook subscriptions](https://docs.lehar.ai/api-reference/webhook-subscriptions/list-webhook-subscriptions.md): Optionally filtered to one agent with `?agent_id=`. Neither `signing_secret` nor header values are ever returned here. Scope `workspace:read`. - [Register a webhook endpoint](https://docs.lehar.ai/api-reference/webhook-subscriptions/register-a-webhook-endpoint.md): Per-agent outbound webhook subscription. An agent with no subscription emits nothing. `headers` are replayed verbatim on every delivery and authenticate it; their values are never returned by any read. Signing is opt-in — `signing_secret` is returned **only here**, and only when `signing_enabled` is… - [Delete a webhook subscription](https://docs.lehar.ai/api-reference/webhook-subscriptions/delete-a-webhook-subscription.md): Scope `api_keys:write`. - [Update a webhook subscription](https://docs.lehar.ai/api-reference/webhook-subscriptions/update-a-webhook-subscription.md): Scope `api_keys:write`. `agent_id` cannot be changed — sending it is a 400. A `headers` update replaces the whole object, because values are never readable and so cannot be merged client-side. - [Analytics overview](https://docs.lehar.ai/api-reference/analytics/analytics-overview.md): Volume, connect rate, duration, cost and latency across the workspace for a date range, with deltas against the preceding range of equal length. Scope `analytics:read`. - [Analytics daily trend](https://docs.lehar.ai/api-reference/analytics/analytics-daily-trend.md): One row per UTC day, gap-filled with zeroes. Same parameters as the overview. Scope `analytics:read`. - [List Session Recordings](https://docs.lehar.ai/api-reference/recordings/list-session-recordings.md) - [List Campaign Recordings](https://docs.lehar.ai/api-reference/recordings/list-campaign-recordings.md) - [Get Recording Playback Url](https://docs.lehar.ai/api-reference/recordings/get-recording-playback-url.md) - [Delete Recording](https://docs.lehar.ai/api-reference/recordings/delete-recording.md) - [Get workspace](https://docs.lehar.ai/api-reference/workspace/get-workspace.md): Returns the current workspace and the API key used to authenticate. - [List API keys](https://docs.lehar.ai/api-reference/workspace/list-api-keys.md): Lists the workspace's API keys. Raw key material is never returned — only the prefix. - [Create API key](https://docs.lehar.ai/api-reference/workspace/create-api-key.md): Creates an API key. The raw `key` is returned **only once** in this response — store it in a secrets manager. Requires the `api_keys:write` scope. Every requested scope must be one the calling credential already holds; requesting a broader scope returns `403` and creates nothing. - [Revoke Api Key](https://docs.lehar.ai/api-reference/workspace/revoke-api-key.md) - [List Knowledge Bases](https://docs.lehar.ai/api-reference/knowledge-base/list-knowledge-bases.md) - [Create Knowledge Base](https://docs.lehar.ai/api-reference/knowledge-base/create-knowledge-base.md) - [Delete Knowledge Base](https://docs.lehar.ai/api-reference/knowledge-base/delete-knowledge-base.md) - [Update Knowledge Base](https://docs.lehar.ai/api-reference/knowledge-base/update-knowledge-base.md) - [List Knowledge Base](https://docs.lehar.ai/api-reference/knowledge-base/list-knowledge-base.md) - [Delete Knowledge Base Documents](https://docs.lehar.ai/api-reference/knowledge-base/delete-knowledge-base-documents.md) - [Ingest Knowledge Base](https://docs.lehar.ai/api-reference/knowledge-base/ingest-knowledge-base.md) - [Search Knowledge Base](https://docs.lehar.ai/api-reference/knowledge-base/search-knowledge-base.md) - [List pronunciation dictionaries](https://docs.lehar.ai/api-reference/pronunciation-dictionaries/list-pronunciation-dictionaries.md): Lists the workspace's pronunciation dictionaries. Scope `pronunciation_dictionary:read` (held by every member). - [Create a pronunciation dictionary](https://docs.lehar.ai/api-reference/pronunciation-dictionaries/create-a-pronunciation-dictionary.md): Creates a pronunciation dictionary — a named set of substitution rules the agent applies to its own speech just before it is spoken, identically across every voice provider. Attach one to an agent with the agent's `pronunciation_dictionary_id` (one dictionary per agent). Scope `pronunciation_diction… - [Delete a pronunciation dictionary](https://docs.lehar.ai/api-reference/pronunciation-dictionaries/delete-a-pronunciation-dictionary.md): Deletes the dictionary. Any agents referencing it are automatically unbound (their `pronunciation_dictionary_id` becomes null); the response reports how many. Scope `pronunciation_dictionary:write` (admins only). - [Update a pronunciation dictionary](https://docs.lehar.ai/api-reference/pronunciation-dictionaries/update-a-pronunciation-dictionary.md): Partial update. Any field you send replaces the stored value; sending `entries` replaces the whole list, and `description: ""` clears the note. Scope `pronunciation_dictionary:write` (admins only). - [List Whatsapp Templates](https://docs.lehar.ai/api-reference/whatsapp/list-whatsapp-templates.md) - [Create Whatsapp Template](https://docs.lehar.ai/api-reference/whatsapp/create-whatsapp-template.md) - [Delete Whatsapp Template](https://docs.lehar.ai/api-reference/whatsapp/delete-whatsapp-template.md) - [Get Model Catalog](https://docs.lehar.ai/api-reference/catalog/get-model-catalog.md): LLM/STT/TTS providers, models, voices, and speakers for the agent editor. - [List Sip Trunks](https://docs.lehar.ai/api-reference/phone-numbers/list-sip-trunks.md) - [Create Sip Trunk](https://docs.lehar.ai/api-reference/phone-numbers/create-sip-trunk.md) - [Archive Sip Trunk](https://docs.lehar.ai/api-reference/phone-numbers/archive-sip-trunk.md) - [List Pending Approvals](https://docs.lehar.ai/api-reference/phone-numbers/list-pending-approvals.md) - [List Available Numbers](https://docs.lehar.ai/api-reference/phone-numbers/list-available-numbers.md): Browse purchasable Vobiz DIDs for the managed path. Read-only, no spend. 140/1600 series are excluded server-side (see runbook §6). Returns 503 when the Vobiz DID API isn't configured — callers fall back to the manual "enter the DID your account manager quoted" flow. - [List Phone Numbers](https://docs.lehar.ai/api-reference/phone-numbers/list-phone-numbers.md) - [Create Phone Number](https://docs.lehar.ai/api-reference/phone-numbers/create-phone-number.md) - [Get Phone Number](https://docs.lehar.ai/api-reference/phone-numbers/get-phone-number.md) - [Update Phone Number](https://docs.lehar.ai/api-reference/phone-numbers/update-phone-number.md) - [Archive Phone Number](https://docs.lehar.ai/api-reference/phone-numbers/archive-phone-number.md) - [Activate Phone Number](https://docs.lehar.ai/api-reference/phone-numbers/activate-phone-number.md) - [Purchase Phone Number](https://docs.lehar.ai/api-reference/phone-numbers/purchase-phone-number.md): Buy a requested managed DID from Vobiz inventory. **Platform-admin only — debits the platform Vobiz balance.** Operates on a `provisioning` managed row (created when the customer requested the number); the row stays `provisioning` afterwards — activation (which includes the carrier-side trunk attach… - [Reject Phone Number](https://docs.lehar.ai/api-reference/phone-numbers/reject-phone-number.md) - [List Whatsapp Senders](https://docs.lehar.ai/api-reference/whatsapp-numbers/list-whatsapp-senders.md) - [Create Whatsapp Sender](https://docs.lehar.ai/api-reference/whatsapp-numbers/create-whatsapp-sender.md) - [Get Whatsapp Sender](https://docs.lehar.ai/api-reference/whatsapp-numbers/get-whatsapp-sender.md) - [Update Whatsapp Sender](https://docs.lehar.ai/api-reference/whatsapp-numbers/update-whatsapp-sender.md) - [Archive Whatsapp Sender](https://docs.lehar.ai/api-reference/whatsapp-numbers/archive-whatsapp-sender.md) ## OpenAPI Specs - [openapi](/api-reference/openapi.json)