Connect a Dasha voice AI agent to your backend, CRM, calendar, and workflows with purpose-built tools, lifecycle webhooks, and the Dasha REST API.
A useful voice agent needs more than a good prompt. It needs safe, current information from the systems your team already uses—and a reliable way to return the outcome of each conversation.
With Dasha BlackBox, an API integration usually has three connected parts:
- Your application calls Dasha's API to create or manage agents and schedule calls.
- A Dasha tool calls your backend during a conversation to look up data or take an approved action.
- Dasha sends webhooks to your system when a call starts, completes, fails, or reaches a deadline.
This guide shows how those pieces fit together, with a practical pattern for connecting a Dasha voice agent to a CRM, order system, calendar, or custom application.
The short version: Let Dasha run the real-time conversation. Keep your business rules, source-of-truth data, permissions, and irreversible actions in your backend.
What is a Dasha API integration?
A Dasha API integration connects a Dasha BlackBox agent to the services that power your customer experience. For example, an agent can:
- look up an order or account during a call;
- check appointment availability and create a booking after confirmation;
- schedule outbound calls when a qualified CRM event occurs;
- transfer a caller when a human specialist is needed; and
- send the call outcome, transcript, and selected structured fields back to a CRM or analytics system.
The best implementation does not give the language model unrestricted access to a database or third-party API. Instead, it exposes a small set of purpose-built tools with clear input rules, then authorizes every request in a service you control.
The integration pattern at a glance
CRM, scheduling app, ecommerce platform, or custom backend │ │ 1. Dasha REST API: create/schedule a call ▼ Dasha BlackBox agent │ │ 2. Tool webhook: request a lookup or approved action ▼ Your integration service / API layer │ ├── CRM, calendar, order system, database │ │ 3. Result and lifecycle webhooks ▼ CRM, queue, analytics, or follow-up workflow
This split makes ownership clear: Dasha owns the conversation and call lifecycle; your integration layer owns authorization, data access, policy enforcement, and recovery from downstream failures.
Choose the right Dasha integration method
Use the interface that matches the job. Trying to make one webhook do everything leads to slow calls, duplicate updates, and unclear failure handling.
| What you need to do | Use | Direction | Example |
|---|---|---|---|
| Start or manage an agent or call | Dasha REST API | Your system → Dasha | Schedule an outbound appointment reminder |
| Get live data or perform an action during a conversation | Agent tool with a webhook | Dasha → your backend → external system | Check an order, create a ticket, reserve a slot |
| React after a call changes state | Event/result webhook | Dasha → your backend | Update the CRM when a call completes or fails |
| Use an existing standards-based tool provider | MCP connection | Dasha → MCP server | Connect approved pre-built tools without writing a custom adapter |
For proprietary data and business-specific workflows, custom tool webhooks give you the most control. For a standard, supported integration, an MCP connection can reduce the amount of custom plumbing. You can use both in one agent.
Before you build: define one narrow outcome
Start with a single conversation outcome, such as check an order, qualify a lead, or book an appointment. For that outcome, document:
- the information the agent may read aloud;
- the minimum data needed to locate the record;
- the checks required before a write action;
- the exact confirmation the customer must give; and
- what the CRM or system of record should receive after the call.
A good first tool is narrow: get_order_status, find_available_slots, or create_support_ticket. A vague tool such as crm_action forces the model to invent intent and parameters, which makes validation and auditing much harder.
For outbound calls, decide eligibility before the call is scheduled. Consent, do-not-contact rules, approved calling windows, retry limits, and local regulations belong in deterministic application logic—not only in an agent prompt.
Step 1: Create and test the agent
You can configure an agent in the Dasha dashboard or with the REST API. The dashboard is often the fastest way to establish the prompt, voice, tool configuration, and test conversations; the API is useful when your product needs to provision or update agents programmatically.
Before connecting production systems:
- Write a system prompt that states the agent's purpose, escalation path, and prohibited actions.
- Add only the tools the agent needs for the first use case.
- Test the normal path, missing-information path, and a request that should be refused or escalated.
- Keep the agent disabled until integration and conversation tests are complete.
The Dasha quickstart covers creating and testing a first agent. If you will place outbound calls, configure an enabled agent and link an outbound phone number before scheduling calls.
Step 2: Define a tool for live system access
A Dasha tool describes an action the agent may request during a conversation. The definition contains a name, a clear description, JSON Schema for allowed arguments, and the webhook endpoint that performs the work.
Here is an example order-status tool. The agent can use it when a caller asks about a specific order, but it cannot pass arbitrary query text or choose a customer record.
{ "name": "get_order_status", "description": "Look up the delivery status for an order the caller identifies. Use only after the caller provides an order number.", "schema": { "type": "object", "properties": { "order_number": { "type": "string", "pattern": "^ORD-[0-9]{6}$", "description": "The order number in the format ORD-123456" } }, "required": ["order_number"], "additionalProperties": false }, "webhook": { "url": "https://api.example.com/dasha/tools/order-status", "headers": { "Authorization": "Bearer your-webhook-secret" } }, "fallBackResult": { "available": false, "message": "Order status is temporarily unavailable. Offer to create a support request." } }
Tool names must start with a letter or underscore and use only letters, numbers, and underscores. Make both the tool and each parameter self-explanatory. The description helps the model decide when to use the tool; the schema limits what it can ask your service to do.
In the dashboard, add the tool from the Tools tab, then use Test Tool with valid, invalid, and missing arguments before relying on it in a conversation. See the complete Tools and Functions documentation for the configuration fields and test endpoint.
Design schemas for control, not convenience
Use the strongest practical constraints:
- Use
enumfor a small approved set of values. - Use
formatfor values such as email addresses or timestamps where it helps validation. - Use
pattern, numeric limits, andadditionalProperties: falsewhen the domain is well defined. - Do not accept internal IDs, price, permission level, or authorization state from the model unless your backend independently verifies them.
- Split read and write operations.
find_available_slotsandbook_confirmed_slotare easier to protect than one catch-all calendar tool.
A tool schema reduces bad inputs; it is not an authorization system. Your backend must still validate every received value.
Step 3: Build the tool webhook in your backend
When the agent invokes a tool, Dasha sends your endpoint a POST request with a ToolWebHookPayload. It includes the tool name, model-generated arguments, and call metadata such as callId, agentId, and orgId.
Your endpoint should do four things:
- Authenticate the request using the secret header configured on the tool.
- Confirm the payload type and tool name.
- Validate arguments and apply your own authorization rules against authoritative data.
- Return a compact JSON result that the agent can explain naturally.
The following Express example is intentionally small. Replace the placeholder functions with your application's authentication, record lookup, and audit logging.
app.post("/dasha/tools/order-status", async (req, res) => { if (!verifyBearer(req.get("authorization"), process.env.DASHA_TOOL_SECRET)) { return res.status(401).json({ error: "unauthorized" }); } const { type, toolName, arguments: args = {}, callId, agentId } = req.body; if (type !== "ToolWebHookPayload" || toolName !== "get_order_status") { return res.status(400).json({ error: "unexpected_tool_payload" }); } if (!/^ORD-\d{6}$/.test(args.order_number || "")) { return res.status(200).json({ available: false, message: "That order number is not in the expected format. Ask the caller to repeat it." }); } // Resolve the caller or account with your own trusted context. Do not treat // speech or model arguments as proof that the caller may see this order. const caller = await resolveAuthorizedCaller({ callId, agentId }); const order = await orders.findForCustomer(args.order_number, caller.customerId); await audit.log("dasha_order_lookup", { callId, agentId, orderNumber: args.order_number }); if (!order) { return res.status(200).json({ available: false, message: "No matching order is available for this customer. Offer human support." }); } return res.status(200).json({ available: true, order_number: order.number, status: order.safeCustomerStatus, estimated_delivery: order.estimatedDeliveryDate }); });
Return data the agent can use safely
Tool responses become context for the conversation. Return the fields needed to answer the customer's question, not an entire CRM record or raw API response. A concise structured result is easier to test, reduces data exposure, and gives the agent less ambiguous context.
For a write action such as booking, cancellation, refund request, or address change, reload the authoritative record in your backend and enforce all policy there. Verify the customer, re-check availability or record version, and require an explicit confirmation tied to the exact action. Use an idempotency key or durable operation record so a retry cannot create two bookings or two transactions.
Dasha can retry tool calls according to the tool configuration. Make read operations safe to repeat, and make every write operation idempotent.
Handle slow systems without leaving callers in silence
Most lookups should return quickly; aim for a response well under a second whenever possible. If an approved operation genuinely takes longer, configure the tool as long-running and give the agent a useful instruction for the waiting period. Dasha can continue the conversation and incorporate the result when it arrives.
Do not use a slow tool as a reason to move validation into the prompt. Put slow work behind a queue or integration service, return a clear pending outcome, and tell the caller what will happen next when immediate completion is not possible.
Step 4: Send call outcomes back to your CRM or workflow
A tool answers a question during a call. An event webhook tells your system that something happened in the call lifecycle. Configure result, failure, and other appropriate webhooks from the agent's Webhooks settings.
For a completed call, Dasha can send a CompletedWebHookPayload with the call ID, transcript, duration, result data, and an inspector URL. Failed and deadline-expired calls have their own payload types. Route payloads by their type field rather than assuming every event has the same shape.
app.post("/dasha/events", async (req, res) => { if (!verifyBearer(req.get("authorization"), process.env.DASHA_EVENT_SECRET)) { return res.sendStatus(401); } // Acknowledge quickly. Put the event on durable infrastructure before doing // CRM writes, notifications, or long-running analysis. await eventQueue.enqueue({ idempotencyKey: `${req.body.callId}:${req.body.type}`, payload: req.body }); return res.sendStatus(204); });
A worker can then route CompletedWebHookPayload, FailedWebHookPayload, and CallDeadLineWebHookPayload to their own business rules. Use callId plus the event type as an idempotency key. That way, a webhook retry updates the same CRM record instead of creating duplicate follow-up tasks, calendar events, or messages.
Your webhook endpoint should be publicly reachable over HTTPS, authenticate requests, and respond promptly. Dasha treats a 2xx response as success, does not retry 4xx responses, and retries on 5xx responses or timeouts. The webhook configuration guide and event schema reference detail the current payloads and response behavior.
Carry correlation data, not whole customer records
When you create an outbound call, additionalData can carry a stable source record ID, tenant ID, or campaign ID. Dasha returns it as callAdditionalData in webhook payloads, making it possible to associate the result with the right record.
Use it for identifiers and narrowly scoped personalization—not full CRM records, secrets, or data the agent does not need. At the destination, confirm that the callId and record ID match the call you created before applying an update. Phone-number matching alone is not a reliable correlation method.
Step 5: Schedule an outbound Dasha call from your application
When a business event makes a contact eligible for a call, your system can call Dasha's REST API. The example below creates an outbound call and passes only safe correlation data.
const response = await fetch( `https://blackbox.dasha.ai/api/v1/calls?agentId=${process.env.DASHA_AGENT_ID}`, { method: "POST", headers: { "Authorization": `Bearer ${process.env.DASHA_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ endpoint: "+15551234567", priority: 5, additionalData: { crmRecordId: "lead_4821", sourceEventId: "form_2026_09_16_4821", campaignId: "demo_follow_up" } }) } ); if (!response.ok) throw new Error(`Dasha call request failed: ${response.status}`); const call = await response.json(); await crm.calls.create({ dashaCallId: call.callId, state: "call_enqueued" });
Use an E.164 phone number. Store the returned callId immediately, but do not mark the contact reached, qualified, or completed yet: creating a call only means Dasha accepted the call record for scheduling. The completed-call webhook is the signal to update outcome-dependent fields.
The outbound calls API guide also covers priorities, bulk scheduling, status monitoring, and cancellation of calls that have not started.
Use post-call analysis for fields your workflow actually needs
A transcript is useful for review, but most downstream systems work better with a small, typed result. Configure post-call analysis labels for decisions that the next workflow needs, such as:
outcome:qualified,not_qualified,callback_requested, orno_answer;follow_up_required: true or false;appointment_time: a string or date-time when confirmed; andescalation_reason: a brief optional explanation.
Keep labels specific. Prefer enums when the possible values are known, and avoid asking the model to infer information the conversation never established. Map the structured completed-call result into CRM fields after validating the event and its correlation data. The post-call analysis guide explains how to configure labels and retrieve the results.
For a no-code or low-code example of this two-way pattern, see Dasha's guide to a Zapier integration with API and webhooks.
Dasha API integration checklist
Before enabling live traffic, verify the full loop—not only a successful API request.
Agent and conversation
- The prompt identifies the agent and explains its permitted scope.
- The agent knows when to ask for clarification, refuse a request, or transfer to a human.
- Every tool has a narrow name, clear description, and constrained JSON Schema.
- Tool calls have been tested with realistic voice conversations, not only sample JSON.
Security and data handling
- Dasha API keys and webhook secrets are stored in a secret manager or protected environment variables.
- Tool and event webhook endpoints use HTTPS and authenticate incoming requests.
- The backend validates every argument and authorizes every read or write from trusted data.
- Only the minimum required customer data appears in prompts,
additionalData, transcripts, logs, and tool responses. - Sensitive payment credentials, passwords, and government IDs never pass through the agent or ordinary webhook logs.
Reliability and operations
- The call ID is stored as soon as a call is created.
- CRM and workflow writes are idempotent on a durable event key such as
callId:type. - Webhook receivers acknowledge quickly and process slow work asynchronously.
- Timeouts, tool failures, duplicate deliveries, malformed inputs, and downstream outages have tested paths.
- Your team can inspect calls, tool requests, and webhook failures, and knows how to disable the agent quickly.
Dasha's production checklist is a useful final gate before turning on customer traffic.
Common Dasha integration mistakes—and how to avoid them
| Mistake | Why it causes trouble | Better approach |
|---|---|---|
Giving the agent a generic crm_action tool | The model has too much freedom and the service is difficult to secure | Build small tools for one read or one approved action |
| Treating a tool argument as trusted | Speech and model-generated values can be wrong or manipulated | Validate values, reload the record, and authorize in your backend |
| Updating the CRM when the call API accepts the request | The call may not have connected or completed | Store callId, then apply outcome updates from result webhooks |
| Matching call results by phone number | Numbers can be duplicated, reformatted, or changed | Correlate with callId and a stable record ID in additionalData |
| Doing heavy work before responding to a webhook | Retries and duplicate side effects become more likely | Persist or enqueue the event, acknowledge it, then process asynchronously |
| Logging full payloads by default | Transcripts and metadata may contain unnecessary sensitive data | Redact logs and retain only what authorized teams need |
| Letting an API call decide a financial or high-impact action | External systems can change between the request and the action | Re-check authoritative state, require explicit confirmation, and use idempotency controls |
Frequently asked questions
Can Dasha integrate with my CRM, calendar, or database?
Yes. Configure an agent tool that calls an HTTPS endpoint you control; that service can use your CRM, calendar, database, or other API. Use a completed-call webhook to write the result back to the system of record. This pattern works whether the underlying service is Salesforce, HubSpot, a scheduling platform, an ecommerce system, or a custom application.
What is the difference between a Dasha tool webhook and an event webhook?
A tool webhook is invoked during a conversation and returns data for the agent to use in its next response. An event webhook is a lifecycle notification—such as completion or failure—that your system acknowledges and processes for records, reporting, or follow-up. Use tools for live conversational actions and events for asynchronous workflow updates.
Can my application start Dasha calls through an API?
Yes. Your application can make an authenticated request to Dasha's calls endpoint with an agent ID, an E.164 endpoint, and optional safe additionalData. Save the returned call ID and wait for the appropriate webhook before recording a final business outcome.
How do I prevent duplicate CRM updates or bookings?
Treat webhook delivery as at-least-once. Persist a deduplication key such as callId:type before performing side effects. For state-changing tools, use your own durable idempotency record and re-check the current record state before committing the action.
Do I need to write custom code for every integration?
Not always. An MCP connection may provide tools through an existing MCP server, and platforms such as Zapier can connect a business trigger to Dasha's REST API and receive results through a webhook. Custom integration code is still the right choice when you need proprietary data access, strict authorization, complex business rules, or a durable audit trail.
Build the smallest reliable integration first
Start with one focused tool, one call trigger, and one completed-call update. Test the entire path with safe data: the prompt, tool arguments, backend authorization, customer-facing response, webhook payload, idempotent CRM update, and failure handling.
Once that loop is reliable, you can add more tools and workflows without turning your voice agent into an uncontrolled gateway to your systems. Create and test a Dasha agent, then connect it to the business logic that makes each conversation genuinely useful.



