Dograh

Embedding a Voice Agent Into Your SaaS Product via API

Embedding a Voice Agent Into Your SaaS Product via API
TutorialNovember 12, 2026·7 min read

Embedding a Voice Agent Into Your SaaS Product via API

Abhishek Kumar
Abhishek Kumar·Co-founder, Dograh AI

Co-founder of Dograh, building the future of open-source voice AI agents. Own your voice AI stack.

To embed a voice agent in a SaaS product, call the platform's API from your own backend: keep the API key on your server, give each customer an agent or per-call context, start calls with one request, and read the results back. Dograh, the open-source AI voice agent platform, works this way.

Key Takeaways

  • Your backend holds the API key, never the browser.
  • One agent with per-call context fits most products. Duplicate it when flows differ.
  • model_overrides runs each customer's calls on that customer's own model keys.

This post is part of our guide to how to build an AI voice agent, where an API Trigger lets your own system start a call and pass details with it. Here we wire Dograh into a SaaS product, step by step, from the API key to the call results.

What you need before you start

You need an agent that already works in a browser test call, a phone provider connected for real calls, and an API key. Create the key under Developers in the sidebar. Keys start with dgr_ and appear only once, so save yours in your secret manager straight away. If your backend is in Python or TypeScript, the official SDKs wrap the same REST API and read the key and server address from DOGRAH_API_KEY and DOGRAH_API_URL.

You are not building a voice pipeline here. Pipecat, which Dograh is built on, is an excellent base, but a production phone agent needs a lot of plumbing around it, from telephony and turn-taking to recordings and retries. Dograh handles that plumbing, so your product only calls an API. Self-hosted, that API runs on your own servers, in the same cloud account as your product if you like.

Check: a request to /api/v1/workflow/fetch with your key in the X-API-Key header returns your agents.

Step 1: Keep the key on your server

The browser talks to your backend, and only your backend talks to Dograh. An API key belongs to one organization, and anyone holding it can start calls and read every agent in that organization. So it lives where your other secrets live, as OWASP's secrets management cheat sheet recommends for any credential, and never in front-end code. When a user clicks a button such as Call me, your backend checks who they are and which customer account they belong to, then makes the request.

A user clicks Call me on a product page, and the request goes to the product's own backend, which checks who the user is and which account they belong to and keeps the API key in a safe. Only the backend calls Dograh, which starts the call to the user's phone, and the front-end code holds no key.
Your backend checks who the user is and which customer account they belong to, then makes the request. The key lives where your other secrets live, never in front-end code.

Voice or chat inside the page itself takes a different route. Dograh's web widget uses its own embed token and a list of allowed domains, so no API key reaches the page. Our guide to add a voice widget to your website covers that setup.

Then decide where customers sit. Most SaaS products keep every customer in one organization with an agent per customer, or one shared agent. A large customer that needs its own phone setup and billing can have its own organization, or its own self-hosted install. Our post on managing multiple clients on one voice AI platform weighs those options.

Check: a search of your front-end build for dgr_ finds nothing.

Step 2: Give each customer an agent

Start with one shared agent and pass each customer's details with every call, because most products never need more. A customer whose call flow really differs gets a copy of its own. The duplicate endpoint copies an agent's latest state, draft included, into a new agent named after the original with "- Duplicate" added, and gives any API Trigger nodes fresh IDs:

curl -X POST https://your-dograh-host/api/v1/workflow/123/duplicate \
  -H "X-API-Key: $DOGRAH_API_KEY"

What this does: It creates a new agent from agent 123 and returns the copy, including its new id. Store that id against the customer in your own database, so every later request for this customer finds the right agent.

To change the copy, send its new name or definition with PUT /api/v1/workflow/{id}, which saves a draft. POST /api/v1/workflow/{id}/publish then runs full validation and makes the draft the version that takes calls. Calls need the copy's Agent UUID, a stable ID that GET /api/v1/workflow/fetch/{id} returns as workflow_uuid and that never changes when you publish again.

Check: the copy appears under Voice Agents, and its Agent UUID is saved with the customer record.

Dograh

Open Source Alternative to Vapi / Retell

Self-hosted voice agent platform — no per-minute fees

dograh-hq/dograh

Star on GitHub

Step 3: Start calls from your product

One request starts a call. Send it to the agent's UUID with the number to dial in phone_number, the customer's details in initial_context, and, if the customer brings their own model keys, their provider connection in model_overrides:

curl -X POST https://your-dograh-host/api/v1/public/agent/workflow/$AGENT_UUID \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $DOGRAH_API_KEY" \
  -d '{
    "phone_number": "+1415555XXXX",
    "initial_context": {
      "account_name": "Northwind Dental",
      "customer_name": "Jane",
      "appointment_date": "March 15"
    },
    "model_overrides": {
      "llm": {
        "provider_connection_uuid": "22222222-2222-4222-8222-222222222222",
        "settings": { "model": "gpt-4.1-mini" }
      }
    }
  }'

What this does: It dials the number with the published agent. The prompt can use {{account_name}} and {{customer_name}}, and the language model runs on the customer's own connection, so their key carries the model bill for this call.

Each customer's key goes in as its own connection on the Providers page, and named model setups live on the Models page. Overrides follow a fixed order: the organization default, then the agent's own setting, then the API request, then Pre-Call Data Fetch. Dograh checks them before dialing and answers with a 422 error if one is invalid, so a bad key never reaches the caller. While you test a draft, send the same request to /api/v1/public/agent/test/workflow/{uuid}.

The reply carries "status": "initiated" and a workflow_run_id. Save that run ID with the customer, because it is how you find the call later. Our post on API triggers covers what else belongs in initial_context and checking consent before you dial.

Check: the reply says initiated, and the call shows under Agent Runs with the customer's details in its context.

Step 4: Bring the results back

A call is only useful to your product once its outcome lands there. There are two routes, push and pull. For push, add a Webhook node to the agent. When the call ends, it posts a payload you design, with values such as {{workflow_run_id}}, {{initial_context.account_name}}, {{gathered_context.call_disposition}} and the recording and transcript links. It retries temporary failures automatically, up to 5 attempts.

For pull, ask for the run whenever your product needs it, using the agent ID and the run ID you saved:

curl https://your-dograh-host/api/v1/workflow/456/runs/78910 \
  -H "X-API-Key: $DOGRAH_API_KEY"

What this does: It returns run 78910 of agent 456, with is_completed, the gathered_context the agent extracted, and links to the transcript and recording. A product page can show the outcome next to the customer without waiting for a webhook.

If the result belongs in your customers' CRM as well, our post on connecting a voice agent to your CRM covers HubSpot and Salesforce.

Check: a finished test call's outcome appears in your product next to the right customer.

Join the Dograh Community

Dograh is an OSS alternative to Vapi. Join our Slack community for queries, releases, best practices & community interactions.

Before you ship it

Plan for volume per organization. Self-hosted Dograh runs 10 concurrent calls per organization by default, raised with DEFAULT_ORG_CONCURRENCY_LIMIT, and Dograh Cloud's Pay as you go plan includes 10, with more on request. Every customer in one organization shares that limit. For call lists, use the Campaigns API, which handles pacing and retries, rather than looping over single calls. The same API also offers text chat sessions on an agent, if your product wants typed conversations as well.

Support gets easier with the run ID in hand. Each run has a full trace of what the agent heard and said, and QA can score a sample of live calls. Self-hosted Dograh has no per-minute platform fee, but servers, model keys and phone minutes still cost money. Dograh Cloud charges a 1¢-a-minute platform fee.

Before launch, start one call from your product for each customer type and watch the outcome come back to the right account. That one test catches most wiring mistakes before a customer does.

Glossary

Agent UUID
A Dograh agent's stable ID, also called workflow_uuid. It never changes when you publish new versions, so your product can store it once per customer and start calls with it.
initial_context
A JSON object sent with the call request that holds the customer's details. The agent's prompts and greeting read its values as template variables, such as {{customer_name}}.
model_overrides
A field in the call request that swaps the model setup for one call, for example to a customer's own provider connection. Dograh validates it before dialing and rejects an invalid one with a 422 error.
Embed token
The token Dograh's web widget uses to start a browser call or chat on allowed domains. It stands in for the API key in front-end code, which keeps the key on your server.

Frequently Asked Questions

Get started with Dograh

Build, deploy, and scale AI agents with Dograh. Join the community of developers building the future.