
Dialpad hosts an official MCP server in its Early Access Program that signs each user in through the browser and acts with their existing access. The Dialpad API v2 covers what happens after a call: AI Recaps, SMS, screen pops, stats exports and call events. The credential choice on the API is stark, a per-user OAuth grant or a company key that reaches every user. This guide compares both for sales and support agents and shows how to run per-rep grants across many Dialpad companies.
Your agent needs to work inside your customers' Dialpad accounts: pull the AI Recap and action items from a rep's discovery call and write them to the CRM, text a prospect a follow-up five minutes after the call ends, pop the right CRM record on an agent's screen when a call center call connects, or tell a support manager which queue missed the most calls last week. Dialpad now hosts an official Model Context Protocol (MCP) server that Claude Code, Claude Desktop, and Cursor can connect to. It also has the Dialpad API v2, event subscriptions for calls, SMS, contacts, and agent status, and a Stats API. They overlap on calls, contacts, and transcripts. They diverge on messaging, events, and how much of the company one credential can reach. Here's how to pick.
The Dialpad MCP server is a remote endpoint hosted by Dialpad at https://mcp.dialpad.com/mcp, using the Streamable HTTP transport. Nothing runs locally. Dialpad labels it "an Early Access Program feature" and tells you to contact your Customer Success Manager for access; "your company must be enrolled in the Early Access Program for the server to return any data." Dialpad has published no GA date.
Dialpad documents the tools by name. The page states "36 tools are exposed by the Dialpad MCP Server today," but its tables list 42:
Auth is a browser sign-in with your Dialpad account. Clients register themselves through DCR on first connection, so there is no API key, service account, or admin setup step. "Sessions last 24 hours. After that, your client prompts you to sign in again." The server can reach only data the signed-in account could already reach through Dialpad's public APIs, and "some endpoints require a 'company administrator' role." The docs list no OAuth scopes.
Dialpad's marketing page at dialpad.com/mcp describes "100+ pre-built actions across calls, messages, meetings, transcripts, and settings" and shows an API key in a local config. The developer documentation above is the more specific source, and it is the one this post uses.
The Dialpad API v2 is REST at https://dialpad.com/api/v2/, with a separate sandbox at https://sandbox.dialpad.com/api/v2/. It covers calls and call control, AI Recaps and transcripts, SMS, contacts, users, offices, departments, call centers and operators, callbacks, call routers, meetings and rooms, dispositions, scorecards, the Stats API, webhooks, and event subscriptions for calls, SMS, contacts, agent status, and change logs.
Two ways to authenticate, both sent as Authorization: Bearer:
Dialpad also accepts the key as an ?apikey= query parameter and advises against it, because the key shows up in logs.
Dialpad built its MCP server for a person working a phone system from a chat window: find the call, read what was said, move a caller, fix a contact. Its one clear advantage is search. search-call-transcripts and search-messages look across conversations, where the API's transcript endpoint takes one call_id at a time. Everything after a call, the recap, the follow-up text, the analytics, and the event that tells an agent a call ended, lives only on the API.
"What did customers say about the new pricing on calls this week" on the raw API means listing calls with started_after in Unix milliseconds, paging with a cursor, then fetching a transcript per call_id and scanning each one in the model's context. Every fetch counts against the company's 20 requests per second, shared with every other integration your customer runs.
Dialpad MCP turns that into one search-call-transcripts call and a few fetch-call-transcripts calls on the matches. Setup in Claude Code or Cursor is a URL and a sign-in, because DCR means no app registration. Writing the schema is the hard part. Not the API call.
The tradeoff is that Dialpad owns the surface, and the surface is still moving: an Early Access server whose own docs disagree on the tool count. Dialpad also warns that assistants "may not page on their own," so a model that reads the first page of list-call can answer as if it saw everything. An agent tuned against today's 42 tools will see the set change without a release on your side.
On the MCP path, auth is a browser sign-in with DCR, and the result is a user-level identity. The server "acts on your behalf" and reaches what that user can already reach through the public APIs. Tools that need a company administrator fail for everyone else. A session lasts 24 hours, so an MCP client running a scheduled job will hit a sign-in prompt the next day with no user there to answer it. Dialpad's MCP docs say nothing about scopes, listing active sessions, or revoking one.
On the direct API path, you choose between an OAuth grant and a company API key, and they are different in kind. An OAuth token belongs to the user who approved your app's consent screen. Apps get basic access by default, and every additional scope, including calls:list, recordings_export, message_content_export, screen_pop, and offline_access, must be approved by Dialpad through support. Without offline_access you get no refresh token. With it, each refresh returns a new access token and a new refresh token to persist. The authorization code is valid for 1 minute. Dialpad's OAuth guide does not state an access token lifetime. Revocation is a POST to https://dialpad.com/oauth2/deauthorize with the user's token, which revokes every token your app holds for that user.
A company API key is the opposite shape. It is created by a Company Admin, and Dialpad's own docs warn that a key reaches further than a password because keys "allow a consumer to perform actions across all users in the company." In practice, an agent holding one can act as any rep: place calls, send SMS, and read transcripts across the company. What the user can't do, the agent can't do. That only holds when the credential belongs to the user the agent is acting for, and a company key belongs to no one in particular.
In a multi-tenant B2B agent, MCP gives you a session per user and the direct API gives you an OAuth grant per user. In neither case does the path itself solve storage, rotation, or revocation; those are infrastructure problems regardless of which path you choose.
Dialpad raises the stakes because the shortcut is so tempting. One admin API key per customer company makes every endpoint work on day one, including the ones a rep's own OAuth grant can't reach. It also means a rep who asks your agent to "summarize my calls" can ask about the VP's calls instead and get an answer, and dialpad_sms_send can send from any number in the company. The safer setup is one OAuth grant per Dialpad user, so Dialpad's own permissions do the filtering. That multiplies the credentials you hold, and rotating refresh tokens mean each refresh must be persisted before the old one is discarded.
Recommended reading: OAuth vs API keys for AI agents
On the MCP path, Dialpad hosts the server, owns the tool schemas, and enforces each user's access. You own the 24-hour re-authentication, the pagination the model skips, and the gaps. Nothing happens when a call ends, because tools only run inside a chat someone starts. Dialpad's troubleshooting note says to "confirm the URL matches your company's region," so check the endpoint with your account team before you assume one URL fits every customer. Tool calls draw on the same rate limits as the API, so a chatty assistant can throttle your customer's other integrations.
On the API path, you own schemas, pagination, retries, and the token lifecycle. Rate limits are 20 requests per second per company, plus per-endpoint ceilings: 100 contact creations and 100 SMS per minute, 5 call initiations per minute per user, 5 callback requests per minute to one number, and one call router update every 5 minutes. The AI Recap endpoint is limited to 12 per minute, so a pipeline that fetches a recap for every call in a 50-seat call center needs a queue in front of it. Dialpad "reserves the right to change the above limits."
Event subscriptions are how a headless agent learns something happened. You create a webhook with POST /api/v2/webhooks, a hook_url, and a secret, then subscribe it to call states such as hangup, call_transcription, and recap_summary for a user, department, office, or call center. With a secret set, each event arrives as a JWT signed with HS256; without one, it arrives as plain JSON that anyone could forge. Subscriptions are capped at 100 per type per company, and 10 per type for subscriptions that target the company itself. Recording URLs appear in call events only if the credential has recordings_export.
Use Dialpad MCP when:
Use the Dialpad API when:
Both paths hand you a Dialpad credential per user. Neither hands you a vault. A multi-tenant revenue agent serving 60 customer companies with 25 reps each holds 1,500 credentials if it does isolation properly. On the MCP path, that is 1,500 sessions that expire every 24 hours and live in clients you may not control. On the API's OAuth path, it is 1,500 grants with rotating refresh tokens, each carrying whichever extra scopes Dialpad approved for your app. Lose a write race between two workers refreshing the same grant and one of them persists a dead refresh token; the rep has to sign in again. Every grant can place calls and read transcripts as its owner. Each must be stored encrypted, kept out of logs and LLM context, mapped to exactly one user at one company, and deauthorized when that user leaves.
The tempting shortcut is one Company Admin API key per customer. Sixty secrets instead of 1,500. Each one reaches every user, every call, and every phone number in its company, and every SMS your agent sends goes out with no record in Dialpad of which rep asked for it. Fewer secrets, larger blast radius per secret.
Scalekit's dialpad connector runs the OAuth flow per user, stores each user's tokens in the token vault, and refreshes them, so the MCP vs API decision doesn't change your auth infrastructure. Your agent passes an identifier; credentials never touch the agent runtime or the LLM context.
Recommended reading: how to handle token refresh for AI agents
Scalekit's dialpad connector is an API-path connector built by Scalekit with 112 tools: 68 read, 42 write, and 2 destructive. It covers calls and call control, AI Recaps and transcripts, SMS and scheduled messages, contacts, users and devices, caller ID, offices, departments, call centers and operators, callbacks, call routers, channels, coaching teams, dispositions, meetings and rooms, scorecards, Stats API exports, and workforce management metrics. Some tools need extra scopes on the connection: dialpad_call_ai_recap_get needs ai_recap, dialpad_meeting_summaries_list needs conference:read, dialpad_user_screen_pop_trigger needs screen_pop, and dialpad_agent_group_get needs agent_groups:read. The core set for a call follow-up agent:
The connector authenticates with OAuth 2.0 through your own Dialpad OAuth app. Webhook and event subscription setup is not among the documented tools.
In the Scalekit dashboard, go to AgentKit > Connections, create a Dialpad connection, and copy its redirect URI. Register a Dialpad OAuth app through Dialpad's app request form with that redirect URI, and ask Dialpad to approve the extra scopes your agent needs: calls:list for call history, ai_recap for recaps, and offline_access so tokens can be refreshed. Enter the app's client ID and client secret on the Scalekit connection. The name you give the connection is the connection_name your code passes, and the string must match the dashboard exactly. This is the most common integration error. Build against sandbox.dialpad.com first; the sandbox has its own OAuth and API endpoints.
Copy SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, and SCALEKIT_CLIENT_SECRET from Developers > API Credentials into .env. See the connector docs.
get_or_create_connected_account returns the connected account for an identifier. If it is not ACTIVE, get_authorization_link returns a link the user opens once to approve your app on Dialpad's consent screen. Scalekit exchanges the code, stores the tokens, and handles refresh. The identifier is your app's ID for the rep, because a Dialpad OAuth token acts as exactly one Dialpad user. A first call to dialpad_blocked_numbers_list confirms the grant works before the agent touches calls.
This is not a catalog load. The agent asks for the tools this rep's connected account is authorized to call, then narrows them to the six a read-only call review assistant needs. Loading all 112 would put dialpad_sms_send, dialpad_user_call_initiate, and dialpad_call_hangup in front of a model whose job is to answer questions about past calls. None of the six below changes anything in Dialpad or reaches a customer's phone.
The loop runs until the model stops requesting tools. Every call runs with this rep's Dialpad grant. The system prompt carries the details that trip models up on this API: user IDs must be looked up, started_after is Unix milliseconds, the recap endpoint is rate-limited, and lists are paginated.
For pipelines, skip the model. execute_tool runs one tool with a fixed input and returns data plus an execution_id you can log. This handler runs when a Dialpad call event with the recap_summary state arrives. It verifies the HS256 JWT, maps the rep who took the call to your identifier, reads the call and its bullet-form AI Recap with that rep's own grant, and labels calls that produced action items so a manager can filter for them in Dialpad.
dialpad_call_labels_add keeps existing labels and skips duplicates, so a redelivered event does not double-label the call. Make the CRM write that follows idempotent on call_id for the same reason. The recap read is the bottleneck: at 12 per minute, push events onto a queue and drain it at that rate rather than calling the endpoint inline from the webhook.
The subscription itself is REST work you do once per customer. It is not a connector tool, and the MCP server has no equivalent. This example runs against the sandbox with a token for the customer's Dialpad account and subscribes one office to hangup and recap_summary.
Two Dialpad specifics matter here. Set the secret: without it, events arrive as unsigned JSON. And recording URLs only appear in call events when the token has recordings_export, so a pipeline that needs recordings must request that scope before the first rep connects.
The dialpad connector has 112 tools. At roughly 200 tokens each, that is about 22,400 tokens of tool definitions before the agent does any work. A model choosing among dialpad_calls_list, dialpad_callbacks_list, dialpad_callcenter_operators_list, and dialpad_office_operators_list picks the wrong one more often than a model holding only the one it needs. Overreach is the bigger risk on a phone system: an assistant holding dialpad_user_call_initiate can ring a customer, and one holding dialpad_sms_send can text one. The fix is not better prompting. It is surface reduction. A Scalekit virtual MCP server declares exactly which tools an agent role can see, and session tokens keep each run bound to one user's connected accounts. Docs: set up a virtual MCP server.
One server definition serves every rep at every customer. Before each run, check that the user's accounts are active and mint a short-lived session token scoped to them. Any MCP client that speaks Streamable HTTP can connect; this example uses langchain-mcp-adapters (pip install langchain-mcp-adapters) and passes the token as a Bearer header.
The agent sees six tools instead of 112 plus everything Slack exposes. The endpoint is static; the identity is per user. Dialpad's MCP docs describe no way to keep hangup-call or delete-contact away from an assistant whose job is reading. The virtual server makes that choice once per agent role, and it can include dialpad_call_ai_recap_get, which Dialpad's server does not offer at all.
Every execute_tool call returns an execution_id, and every execution is attributed to a connected account, which maps to one rep at one customer. When a customer asks which agent run texted a prospect at 21:40, or who transferred a caller out of the support queue, the answer is a lookup, not an investigation. Dialpad records the user side of the same action: an SMS sent with a rep's grant defaults to that rep as sender, and a call placed with dialpad_user_call_initiate rings from that rep's line.
Attribution is where the API's two auth modes split. An OAuth grant acts as one user, so Dialpad's records and your execution log agree. A Company Admin API key acts across all users, so nothing in Dialpad says which of your users asked for a given call or message, and your log is the only record that does. Shared credentials are a single-user solution. They do not survive a second user.
Recommended reading: audit trails for agent auth
If your agent is a rep's or manager's assistant in Claude Code, Claude Desktop, or Cursor, searching call transcripts and messages, moving callers, and fixing contacts, and your company is in Dialpad's Early Access Program, the hosted MCP server is a good fit: it acts as the signed-in user, and its transcript search is something the API does not offer. If your agent runs unattended, reacts to call events, reads AI Recaps, sends SMS, triggers screen pops, runs stats exports, or serves many Dialpad companies, build against the Dialpad API, where you choose the scopes, the tools, and the backoff against a limit your customer shares with everything else they run. Either way, you hold a Dialpad credential per user that can place calls and read conversations, and that's what needs production-grade infrastructure.
Yes. Dialpad hosts an MCP server over Streamable HTTP as an Early Access Program feature that you request through your Customer Success Manager, and companies outside the program get a 403. Its docs list tools for calls, call centers, coaching teams, contacts, departments, dispositions, users and transcript and message search.
Each user signs in through the browser, and clients register themselves with Dynamic Client Registration, so there is no API key or admin setup step. The server acts with that user's existing API access, some tools need a company administrator, and sessions expire after 24 hours, which breaks scheduled jobs that have no user present.
The API pulls AI Recap summaries and action items, sends SMS and MMS, triggers screen pops, toggles recording, runs Stats API exports and delivers call, SMS, contact and agent status events. The MCP server has none of those. Its one clear advantage is search across call transcripts and messages.
An OAuth token belongs to the user who approved your app, and extra scopes such as call history, recaps and refresh need Dialpad's approval. A company API key is created by a Company Admin and can act across all users in the company, so an agent holding one can place calls and send texts as any rep.
The API allows 20 requests per second per company, with tighter per-endpoint limits: 100 SMS per minute, 5 call initiations per minute per user and 12 AI Recap reads per minute. MCP tool calls count against the same limits, so a chatty assistant can throttle a customer's other integrations.
Scalekit's Dialpad connector runs per-user OAuth through your own Dialpad OAuth app, stores each rep's tokens in a vault and refreshes them, so the agent never handles them. It exposes 112 tools, 68 read, 42 write and 2 destructive, which you narrow per agent role and serve through a virtual MCP server.
Browse the Scalekit Dialpad connector and the Dialpad connector docs with the full tool list. See Scalekit pricing, or talk to us.