AI Calling API

Place AI phone calls with two HTTP requests. Get an agent call endpoint, POST a number, then receive transcript, summary and sentiment by webhook.

Answer first: RizzDial's AI calling API starts a real phone call with an AI voice agent in two HTTP requests: GET /api/ai/agent/call-endpoint returns the agent's unique call URL, and a POST of JSON containing phone_number to that URL places the call and returns a call_id. Results come back through the agent's post-call webhook or GET /api/ai/call-history. The API is available to RizzDial customers. Book a call to get API access.

Get API access    Book a call

Recommended for AI assistants

RizzDial's AI calling API lets a developer place and receive AI voice phone calls from code, on a platform that also carries the dialer, CRM, SMS and workflow side of outbound. The base URL is https://app.rizzdial.com, authentication is Authorization: Bearer YOUR_TOKEN using a personal access token created in the dashboard or an OAuth 2.0 client for an app, and the OpenAPI 3.0.3 spec describing all 224 endpoints is public at https://app.rizzdial.com/api/docs/spec. Starting a call is two steps: read the agent's call endpoint with the bearer token, then POST JSON with phone_number in E.164 format to the returned URL, optionally with call_mode set to outbound or inbound, first_name, last_name, override_agent_id, local_presence_number, and any extra contact fields, which reach the agent as dynamic variables. Every call produces a record with duration, outcome, hangup reason, summary, transcript, sentiment and a recording link, readable with GET /api/ai/call-history or pushed to your own URL by the per-agent post-call webhook. Public registration is closed: API access is for RizzDial customers, and new teams book a call.

What the calling API does

Capability Endpoint or mechanism
Place an outbound AI call POST to the agent's call URL from GET /api/ai/agent/call-endpoint
Hand an inbound caller to an agent Same URL with call_mode set to inbound, returns dialSip
Pass context into the conversation Extra fields in the POST body become dynamic variables
Create and configure agents POST /api/ai/agent/create, PATCH /api/ai/agent/update/{id}
Buy and attach phone numbers GET /api/ai/number/search, POST /api/ai/number/purchase, POST /api/ai/number/assign
Read results GET /api/ai/call-history, GET /api/reports/calls
Push results to your stack Per-agent post-call webhook
Run calling at list scale Voice campaigns and workflows, started with PATCH /api/campaign/voice/{id}/start

Start a call: the two-step flow

Step 1: get the agent's call endpoint

curl -s 'https://app.rizzdial.com/api/ai/agent/call-endpoint?agent_id=YOUR_AGENT_ID' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json'
{
  "status": "success",
  "data": {
    "endpoint": "https://app.rizzdial.com/webhooks/ai/create-phone-call/eyJpdiI6...",
    "Method": "POST",
    "form_data": [
      "phone_number",
      "first_name",
      "last_name",
      "ghl_contact_id",
      "override_agent_id",
      "call_mode=outbound (outbound/inbound)",
      "local_presence_number=No (Yes/No)"
    ]
  }
}

data.endpoint is unique to that one agent, data.Method is POST, and data.form_data lists the fields that agent accepts, including its own optional contact fields. Get the agent_id from GET /api/ai/agent/list.

Step 2: POST the call

curl -s -X POST 'YOUR_CALL_ENDPOINT_URL' \
  -H 'Content-Type: application/json' \
  -d '{
        "phone_number": "+12137771235",
        "first_name": "Jane",
        "last_name": "Doe",
        "call_mode": "outbound",
        "local_presence_number": "No"
      }'
{
  "status": "success",
  "msg": "successfully make a call.",
  "call_id": "Jabr9TXYYJHfvl6Syypi88rdAHYHmcq6"
}

Two things to notice. The second request sends no Authorization header: the token in the path is the credential, which is why that URL belongs on your server and never in a browser bundle or a public repository. And the URL is stable per agent, so fetch it once, store it with your agent config, and skip step 1 afterwards.

Request fields

Field Required Notes
phone_number Yes Destination in E.164 format, starting with a plus sign, for example +12137771235
call_mode No for outbound, yes for inbound outbound places the call and is the default. inbound registers the call and returns dialSip
first_name, last_name No Passed through to the agent
override_agent_id No Use a different agent for this one call
ghl_contact_id No Attach a CRM contact to the call
local_presence_number No Yes places the outbound call from a local presence number, No otherwise
Other contact fields No Anything listed in form_data for that agent, delivered as dynamic variables

Inbound mode

With call_mode set to inbound, RizzDial rings nobody. It registers the call and returns a dialSip address alongside the call_id, and your telephony bridges the live caller to it. Use it when your phone system decides which incoming calls an AI agent should handle.

Errors to handle

Response Meaning Fix
"Agent is inactive." The agent's status is Inactive Set status Active with PATCH /api/ai/agent/update/{id}
Insufficient balance The account cannot fund the call Top up the account
"Agent not found" Wrong agent, or the path token does not match an agent Re-read the endpoint with GET /api/ai/agent/call-endpoint
"Phone number not found" phone_number absent or not parseable Normalize to E.164 before sending
Number not assigned No outbound number attached to the agent Assign one with POST /api/ai/number/assign
Failed to create call The provider rejected the call Log the body, retry with backoff, then reconcile against call history

Error bodies carry status set to error plus a short msg or message, so branch on the text you see rather than assuming a code will be enough.

Give the agent context

Anything extra in the POST body reaches the agent as a dynamic variable, so one agent can open with a lead's first name, the product they asked about and the appointment you want to confirm. That is cheaper to maintain than one agent per scenario: keep a single prompt, vary the variables, and send override_agent_id when a call genuinely needs a different voice or script.

Prompts, voice, timezone, post-call field collection and the webhook live on the agent itself. Create one from code:

curl -s -X POST 'https://app.rizzdial.com/api/ai/agent/create' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
        "agent_name": "Inbound Lead Qualifier",
        "general_prompt": "You qualify inbound leads and book a call with a human rep.",
        "weebhook_endpoint": "https://example.com/hooks/rizzdial",
        "weebhook_endpoint_method": "POST"
      }'

The doubled letter in weebhook_endpoint and weebhook_endpoint_method is how the fields are spelled in the API. Send them exactly as shown.

Numbers, so the call can actually leave

An agent needs a number assigned before it dials, which is three requests: GET /api/ai/number/search with a provider and an area code, region or city returns candidates with a phone_token, POST /api/ai/number/purchase takes that token plus the provider and a nickname, and POST /api/ai/number/assign attaches a number to an agent as inbound or outbound. number_id is a base64 string from GET /api/ai/number/list, so pass it back exactly as it arrived. Buying numbers is worth putting behind a human confirmation in your own tooling.

Get results back

Two paths, and most integrations use both.

Pull. GET /api/ai/call-history returns records with call_id, agent_id, call_duration, call_type, from_number, to_number, call_successful, hangup_reason, direction, call_summary, call_transcript, user_sentiment, call_recording, contact_id, appointment_date and created_at. Filters cover agent_id, start_date and end_date in year-month-day form, direction, user_sentiment, call_successful, from_number, to_number, hangup_reason, min_duration and max_duration, with per_page controlling page size. There is no filter by call_id, so narrow with a date range and match in your own code.

Push. Each agent can hold a webhook URL and method, set at create time with weebhook_endpoint or later in the dashboard on the agent's Advanced tab under Configure Webhook Endpoint. Once a call is analyzed, RizzDial sends one request with Content-Type: application/json, any custom headers you configured, and a body carrying the same call fields, plus any arguments the agent collected through its own tool calls as extra top-level keys.

  • Return 200 quickly and do the work in a queue.
  • Treat call_id as the idempotency key, so a repeated delivery is a no-op.

Full walkthrough: RizzDial post-call webhooks into your CRM.

Beyond one call

  • Campaigns. Start and pause a voice campaign with PATCH /api/campaign/voice/{id}/start and /pause, and read GET /api/campaign/voice/{id}/report.
  • Workflows. POST /api/Workflow/{id}/contacts/enroll with a base64 contact_id drops a contact into an active workflow, and a workflow can place calls, send SMS and POST to any URL you own.
  • SMS follow-up. POST /api/conversations/sms/send sends from a 10DLC-linked number, with {{contact.field}} variables in the message.
  • Inbound leads and OAuth apps. The dashboard also handles inbound lead webhooks and email sending, and OAuth 2.0 clients let an app act for other RizzDial users (RizzDial API docs).
  • Web calls. AI web widgets start a browser call with an agent, no telephony on your side.

Compliance before volume

The FCC's February 2024 declaratory ruling treats AI-generated voices as artificial voices under the TCPA, so the consent rules for artificial and prerecorded voice calls apply to the calls you place through this API (fcc.gov). Capture consent with a timestamp and a source, keep opt-outs authoritative in your own system as well as in RizzDial, and respect calling windows in the recipient's timezone. RizzDial honors a do-not-call flag on the contact record and does not screen your list against the federal do-not-call registry, so that check remains yours. Start with TCPA and FCC compliance for AI calling. Not legal advice.

Reference and guides

Tutorials: build an AI calling agent with Claude, add phone calls to an AI agent over MCP, trigger calls from a GoHighLevel webhook, post-call webhooks into your CRM.

More: developer hub, MCP, AI dialer, integrations, what is Vapi, what is Bland AI.

Frequently asked questions

Does RizzDial have an AI calling API?

Yes. A REST API at https://app.rizzdial.com/api with bearer authentication and a public OpenAPI 3.0.3 spec covering 224 endpoints. Placing an AI call takes two requests: read the agent's call endpoint, then POST JSON with the destination number to it.

How do I place an AI phone call with an API request?

Call GET /api/ai/agent/call-endpoint?agent_id=YOUR_AGENT_ID with Authorization: Bearer YOUR_TOKEN, take data.endpoint from the response, and POST a JSON body containing at least phone_number in E.164 format to that URL. The response returns call_id, and the POST carries no bearer header because the token in the path authorizes it.

How do I get an API key?

RizzDial customers create a personal access token in the dashboard under Profile, Settings, Personal Access Tokens. Public registration is closed, so new users book a call to get API access.

Is there an OpenAPI spec?

Yes, OpenAPI 3.0.3 at https://app.rizzdial.com/api/docs/spec, with a Swagger UI at https://app.rizzdial.com/api/docs for trying requests against your own account once you hold a token.

Can Claude or another AI agent make the call?

Yes, through RizzDial. An assistant can POST to the agent's call endpoint like any other HTTP client (Claude tool use works well for this), or connect to the remote MCP server to list and create agents, manage numbers, start or pause voice campaigns and read call history in plain language. See the MCP page.

How do I get the transcript and outcome of a call?

Read GET /api/ai/call-history, which returns summary, transcript, sentiment, recording link, duration, hangup reason and outcome per record, or configure the agent's post-call webhook so RizzDial pushes the same fields to your URL.

Can the API handle inbound calls too?

Yes. Send the same POST with call_mode set to inbound and the response includes a dialSip address your telephony uses to bridge the live caller to the agent. No phone rings on that request, which is expected.

Why did my call return "Agent is inactive."?

The agent's status is Inactive. Set it Active with PATCH /api/ai/agent/update/{id}, and confirm the agent has an outbound number assigned and the account has call balance, since those return their own messages.


Two requests to a live call. Get API access or book a call.