Skip to main content
POST
Click-to-call exchanges a contact for a short-lived, signed dialer URL. Your agent opens that URL and Ringee handles caller ID selection, credit checks and the WebRTC call.
Click-to-call is the fastest way to add calling to an existing CRM: one server-side request, one redirect, no frontend SDK. If you want the dialer to live inside your own UI instead of a Ringee tab, use the Dialer SDK.
Your frontend only needs dialerUrl and expiresAt. Never return sessionToken to the browser, never persist it, and never write it to logs — it authorizes a call on the agent’s behalf.

Agent resolution

Take agentEmail from your authenticated session, not from a value the browser sent. Otherwise any user could place calls as any colleague.
ownerExternalId is accepted in the payload but is not yet wired to a resolution strategy — sending it without agentEmail returns 422. Use agentEmail.

Caller ID resolution

When you do not send fromNumber, Ringee picks one in this order:
  1. the agent’s first active verified caller ID in that workspace;
  2. any purchased number on the workspace;
  3. otherwise the request fails with 422 No caller ID or purchased number is available for this workspace.

Wiring the button

1

Keep the call server-side

The request must be made by your backend (or an Edge Function). The cik_live_ key must never reach the browser.
2

Pre-open the tab

Open a blank tab before the async request so popup blockers do not swallow it, then navigate it once you have the URL.
3

Guard the button

Disable it when the contact has no valid phone number, or when the contact is on the Do Not Call list. Ringee blocks DNC numbers server-side too, but failing early is a better experience.
4

Never auto-dial

Do not request a dialer URL on page load. Calls must start from a real click.

Errors

Next steps

Receive the call back

Log the call in your CRM when it ends

Embed the dialer instead

Keep agents inside your own UI

Authorizations

X-Ringee-Api-Key
string
header
required

The cik_live_ secret key of a Custom Integration. Shown once at creation. Server-side only.

Body

application/json
contactExternalId
string

The contact's id in your CRM. Resolves to a Ringee contact if you previously synced it with contact.upserted.

Example:

"ext_contact_42"

phoneNumber
string

Destination number. Required unless contactExternalId resolves to a contact that already has one.

Example:

"+14155550123"

agentEmail
string

Email of the Ringee user who will place the call. Required for organization workspaces. Take it from your authenticated session, never from a value the browser sent.

Example:

"rep@example.com"

fromNumber
string

Caller ID to use. Defaults to the agent's first active verified caller ID, then any purchased number on the workspace.

Example:

"+14155550100"

ownerEmail
string

Alias for agentEmail, used when your CRM models this as a record owner.

ownerExternalId
string

Accepted but not yet wired to a resolution strategy. Sending it without agentEmail returns 422 — use agentEmail.

Response

A dialer session was created.

contactId
string | null
required

The Ringee contact, when contactExternalId resolved to one. null otherwise.

Example:

"6b2f8f1e-6a2e-4f1c-9a3d-2d1b0c7e4a55"

agentUserId
string
required

The Ringee user who will place the call.

Example:

"a91c4d77-1f0b-4a2e-8c3d-77b1e2f4a9c0"

toNumber
string
required

Normalized destination in E.164.

Example:

"+14155550123"

fromNumber
string
required

The caller ID Ringee selected.

Example:

"+14155550100"

dialerUrl
string<uri>
required

The URL to open. Valid for 5 minutes.

Example:

"https://app.ringee.io/dashboard/dialer?session=eyJhbGciOi...&to=%2B14155550123&from=%2B14155550100"

sessionToken
string
required

The signed session, already embedded in dialerUrl. Never return it to the browser, persist it, or write it to logs — it authorizes a call on the agent's behalf.

expiresAt
string<date-time>
required

Expiry of the dialer session.

Example:

"2026-05-23T14:35:00.000Z"