Ringover MCP API

## Model Context Protocol The MCP endpoint exposes a **curated** set of Ringover operations to AI assistants (Claude, ChatGPT, Cursor, etc.) via the [Model Context Protocol](https://modelcontextprotocol.io/). It is not a 1:1 copy of the REST API: tools that are hard for an agent to fill, rarely useful, or unsafe are omitted, and related mutations are grouped (for example `calls.archive`, `channels.control`, `users.update`). Source of truth for names, argument schemas and titles is `tools/list`. This page lists the frozen catalogue. ### Useful links - [Model Context Protocol specification](https://modelcontextprotocol.io/specification/latest) - [Lifecycle & initialization](https://modelcontextprotocol.io/specification/latest/basic/lifecycle) - [Tools](https://modelcontextprotocol.io/specification/latest/server/tools) - [Streamable HTTP transport](https://modelcontextprotocol.io/specification/latest/basic/transports#streamable-http) ### How it works MCP is JSON-RPC 2.0 over HTTP using the [Streamable HTTP transport](https://modelcontextprotocol.io/specification/latest/basic/transports#streamable-http). All interactions use `POST /mcp` with a JSON-RPC body. The server is **stateless** — every request is independent. There is no session (`Mcp-Session-Id` is not used) and no `notifications/tools/list_changed`. ### Request headers Every `POST` must send: - `Content-Type: application/json` - `Accept: application/json, text/event-stream` — **both** media types are required (comma-separated, as MCP clients do). A request that omits `text/event-stream` is rejected with HTTP `400`. ### Response format Successful MCP calls return HTTP `200` with `Content-Type: application/json` and a **single JSON-RPC object** in the body. There is no SSE stream: the endpoint is stateless (one request, one response, no shared connection across tool calls), so Server-Sent Events would not add multiplexing here. ### JSON-RPC errors vs HTTP errors - **Supported methods** (`initialize`, `tools/list`, `tools/call`): invalid tool arguments, tool rate limits, and application failures on `tools/call` are returned with HTTP `200` (JSON-RPC `error` or a tool result with `isError: true`). - **HTTP transport rejections** (before the message is handled as MCP): invalid `Accept`, malformed JSON-RPC, unsupported method **name** (anything other than the three methods above), etc. → HTTP **`400`** with a **plain-text** body, not a JSON-RPC envelope. Example: `JSON RPC not handled: "monitor/unknown_method" unsupported`. - Missing or invalid credential → **`401`**. HTTP rate limit → **`429`**. ### Available JSON-RPC methods | Method | Purpose | |--------|---------| | `initialize` | Capability negotiation. Returns server info (`name: "ringover-public-api"`, `version: "v1.0.0"`) and capabilities. Optional — you can call `tools/list` or `tools/call` directly. | | `tools/list` | Returns the tools **this credential can use**, with `name`, `title`, `description`, `inputSchema` and `annotations`. | | `tools/call` | Execute a tool by `name` with `arguments`. | `tools/list` never returns a tool the caller cannot invoke. A write tool is listed only when the credential has the matching **write** grant. Calling a hidden name is refused (`forbidden`). ### Authentication The MCP endpoint accepts the same credentials as the rest of public-api: - a **Public API key** (raw, no `Bearer` prefix) - an **OAuth 2.0 access token** (`Authorization: Bearer `), when OAuth is enabled for the environment For API keys, three sources are tried in this **order** (first one set wins): | # | Source | Endpoint | Example | When to use | |---|--------|----------|---------|-------------| | 1 | URL path parameter | `POST /mcp/{token}` | `POST /mcp/abcd1234…` | Last resort for clients that cannot set headers or query strings. | | 2 | Query string `?token=` | `POST /mcp?token=…` | `POST /mcp?token=abcd1234…` | No-code / web tools that cannot set custom headers. | | 3 | `Authorization` header | `POST /mcp` | `Authorization: abcd1234…` | **Recommended** — same as REST. | The token is then normalized internally, so rate limiting, logging and permission checks behave the same regardless of source. > ⚠️ **Security note** — Tokens in the URL path or query string often appear in proxy logs, browser history and access logs. Prefer the `Authorization` header. If a token may have been exposed in a URL, **rotate it** from the Ringover Dashboard. ### Identifiers and JSON - MCP identifiers are **core IDs**. Do not apply the REST public offset (`+10000`). - Tool results use **snake_case** keys (`user_id`, `campaign_uuid`, `webhook_id`). - Write acknowledgements typically return `{"success": true}`. - `users.update`, `campaigns.update` and `conversations.update` may apply several upstream mutations in sequence. Validation runs first; an upstream error can still leave earlier fields updated. ### Cursor ```json { "mcpServers": { "ringover-public-api": { "url": "https://public-api.ringover.com/mcp", "headers": { "Authorization": "" } } } } ``` Use the US host `https://public-api-us.ringover.com/mcp` for US workspaces. ### Quick start Using the standard `Authorization` header (recommended): ``` POST /mcp Authorization: your-api-key-here Content-Type: application/json Accept: application/json, text/event-stream {"jsonrpc":"2.0","id":1,"method":"tools/list"} ``` Same call using the query string variant: ``` POST /mcp?token=your-api-key-here Content-Type: application/json Accept: application/json, text/event-stream {"jsonrpc":"2.0","id":1,"method":"tools/list"} ``` Same call using the URL path variant: ``` POST /mcp/your-api-key-here Content-Type: application/json Accept: application/json, text/event-stream {"jsonrpc":"2.0","id":1,"method":"tools/list"} ``` Example response: ```json {"jsonrpc":"2.0","id":1,"result":{"tools":[...]}} ``` ### Rate limiting The MCP endpoint has its own rate limiting, separate from the REST API: - **HTTP rate limit** (per API key): 1 request/second with a burst of 10. Returns HTTP `429` when exceeded. - **Tool rate limit** (per team + tool name): ~1 call every 3 seconds with a burst of 5. Returns a JSON-RPC error in the response body (HTTP status remains `200`). ### Request timeout Each request has a **30-second timeout**. If a tool call exceeds this duration, the request is cancelled and an error is returned. ### Error handling Transport errors use HTTP status codes. Application errors on `tools/call` use a tool result with `isError: true` (HTTP still `200`): | Situation | Response | |-----------|----------| | Missing or invalid API key | HTTP `401` | | HTTP rate limit exceeded | HTTP `429` | | Tool rate limit exceeded | HTTP `200` + JSON-RPC error: `"rate limit exceeded for tool X"` | | Insufficient permission | HTTP `200` + tool result `isError`: `"forbidden"` | | Invalid arguments | HTTP `200` + tool result `isError` (validation message) | | Resource not found | HTTP `200` + tool result `isError` (for example `"user not found"`) | | Team feature not enabled (transcription) | HTTP `200` + JSON-RPC error: `"transcription feature not enabled for team"` | | Upstream / internal failure | HTTP `200` + tool result `isError` (generic message) | ### Permissions and Monitoring MCP tools follow the **same permission and Monitoring rules** as the matching REST operations. Read tools need the category **Read** grant; write tools need **Write**. `tools/list` already hides tools the token cannot use. The **Monitoring** flag still controls data **scope** (own data vs team), not which tools exist. `team.get` is visible to every authenticated caller. --- ## Available tools (111) Tool names follow `{resource}.{action}` (optional sub-resource: `campaigns.numbers.add`). `R` = read, `W` = write. ### Contacts **Permission:** Contacts. Monitoring does not widen the address book. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `contacts.search` | R | Search contacts by name, phone number, or company. | `query`, `limit` (0–500), `offset` | | `contacts.get` | R | Get a contact by core ID. | `contact_id` | | `contacts.create` | W | Create 1–50 contacts (numeric contract). | contacts payload | | `contacts.replace` | W | Replace a contact's full desired state. | `contact_id` + payload | | `contacts.delete` | W | Delete a contact. | `contact_id` | ### Calls and callbacks **Permission:** Calls. Call listing is team-wide regardless of Monitoring (same as REST). | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `calls.search` | R | Search terminated calls. `summary`, `transcription` and `contact` are omitted unless `expand` asks for them. | `start_date`, `end_date`, `call_type`, `limit`, `offset`, `expand` | | `calls.get` | R | Get a terminated call. Unlike `GET /calls/{callId}`, summary, transcription and contact are omitted unless `expand` asks for them. | `call_id`, `expand` | | `calls.surveys.get` | R | Get post-call surveys. | `call_id` | | `calls.current.list` | R | List in-progress calls. | *(none / filters as advertised)* | | `calls.archive` | W | Archive a call, one channel, or logs. | `target` (`call` default, `channel`, `logs`), `call_id`, `channel_id`, `channel_ids`, `archive_cdr` | | `callbacks.create` | W | Create a callback. | user, destination number | | `callbacks.ivr.create` | W | Create a callback through an IVR. | IVR + destination | `expand` on `calls.search` and `calls.get` accepts `summary`, `transcription` and `contact`. Repeat values to combine them. The field states are the same as on REST (omitted, `null`, or object; a failed download stays a successful tool result and sets `error.code`). `contact` is included only when requested. Download URLs are not returned. ### Transcriptions **Permission:** Calls **and** the team transcription feature. Otherwise `"transcription feature not enabled for team"`. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `transcriptions.search` | R | List transcriptions, or semantic search when `query` is set. | `query`, `limit` (default 50), `offset`, `min_audio`, `max_audio` (`offset` / audio filters cannot be combined with `query`) | | `transcriptions.get` | R | Full transcript for a call. | `call_id` | ### Team **Permission:** none beyond a valid credential. Monitoring OFF returns a user-scoped view; ON returns the full team. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `team.get` | R | Team name, timezone, country, subscription. | *(none)* | ### Users, planning and snooze **Permission:** Users. Without Monitoring you only reach **your** user. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `users.list` | R | List team users. | *(none)* | | `users.get` | R | Get a user. | `user_id` | | `users.update` | W | Patch named identity fields. | `user_id` plus at least one of `email`, `first_name`, `last_name`, `job_title` | | `users.assign_profile` | W | Assign a permission profile. | `user_id`, `profile_id` | | `users.invite` | W | Invite users (per-item `created` / `failed`). | `users[]` (`email`, `number`, `plan_id`, names) | | `users.delete` | W | Delete or archive a user. | `user_id`, `type` (`DELETED` or `ARCHIVED`) | | `users.planning.get` | R | Weekly schedule. | `user_id` | | `users.planning.set` | W | Replace the weekly schedule. | `user_id`, slots | | `snoozes.list` | R | Available DND / snooze labels. | *(none)* | | `users.snooze.get_log` | R | Snooze history. | `user_id`, `limit`, `offset` | | `users.snooze.set` | W | Set or clear do-not-disturb. | `user_id`, label / duration | ### Groups **Permission:** Users. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `groups.list` | R | List ring groups. | *(none)* | | `groups.get` | R | Group with **all** members (not paginated). | `group_id` | | `groups.create` | W | Create a ring group. | name / members as advertised | | `groups.delete` | W | Delete a ring group. | `group_id` | | `groups.users.add` | W | Add members. | `group_id`, user IDs | | `groups.users.remove` | W | Remove members. | `group_id`, user IDs | ### Profiles **Permission:** Users. Profiles are team-wide. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `profiles.list` | R | List permission profiles. | *(none)* | | `profiles.get` | R | Get a profile. | `profile_id` | ### Numbers **Permission:** Numbers. Monitoring OFF returns numbers assigned to you. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `numbers.list` | R | List team numbers. | *(none)* | | `numbers.get` | R | Get a number. | `number` | | `numbers.reassign` | W | Reassign to a user, IVR or conference. | `number`, target | ### IVRs **Permission:** IVRs. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `ivrs.list` | R | List IVRs. | *(none)* | | `ivrs.get` | R | Get an IVR. | `ivr_id` | | `ivrs.scenarios.list` | R | Scenarios of one IVR. | `ivr_id` | | `ivrs.scenarios.get` | R | One scenario. | `ivr_id`, `scenario_id` | ### Conferences **Permission:** Calls (Monitoring typically required, same as REST). | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `conferences.list` | R | List conference rooms. | *(none)* | | `conferences.get` | R | Get a conference. | `conf_id` | | `conferences.pincode.update` | W | Change the PIN. | conference id, pin | ### Tags **Permission:** Tags (API keys often include this with IVR-related grants). | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `tags.list` | R | List tags. | *(none)* | | `tags.get` | R | Get a tag. | `tag_id` | | `tags.create` | W | Create a tag. | `name`, `color` | ### Presences **Mixed:** team presence typically requires Monitoring ON; user presence follows Users + Monitoring. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `presences.team.get` | R | Presence of all members. | *(none)* | | `presences.user.get` | R | Presence of one user. | `user_id` | ### Blacklist **Team list:** Numbers + Monitoring ON. **User list:** Users (own user without Monitoring). | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `blacklist.team.list` | R | Team-blocked numbers. | `limit`, `offset` | | `blacklist.team.check` | R | Is this number blocked for the team? | `number` | | `blacklist.team.add` | W | Block for the team. | `number` | | `blacklist.team.delete` | W | Unblock for the team. | `number` | | `blacklist.user.list` | R | User blacklist. | `user_id`, `limit`, `offset` | | `blacklist.user.check` | R | Is this number blocked for a user? | `user_id`, `number` | | `blacklist.user.add` | W | Block for a user. | `user_id`, `number` | | `blacklist.user.delete` | W | Unblock for a user. | `user_id`, `number` | ### Channels (live call) **Permission:** Conversations write (same resource as live channel REST). | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `channels.control` | W | Toggle mute, hold or recording, or hang up. | `channel_id`, `action` (`mute`, `hold`, `recording`, `hangup`) | | `channels.transfer` | W | Transfer to a number. | `channel_id`, `phone_number` | | `channels.dtmf.send` | W | Send one DTMF digit. | `channel_id`, `dtmf` (`0-9`, `#`, `*`) | ### Conversations and messages **Permission:** Conversations. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `conversations.list` | R | List SMS/chat conversations. | pagination / filters as advertised | | `conversations.get` | R | Get a conversation. | `conversation_id` | | `conversations.members.list` | R | List members. | `conversation_id` | | `conversations.messages.list` | R | List messages. | `conversation_id` | | `conversations.archive` | W | Archive (level 1). | `conversation_id` | | `conversations.unarchive` | W | Restore. | `conversation_id` | | `conversations.update` | W | Rename and/or set purpose. | `conversation_id`, `name` and/or `purpose` | | `conversations.messages.archive` | W | Archive a message. | conversation + message IDs | | `conversations.messages.unarchive` | W | Restore a message. | conversation + message IDs | ### SMS **Permission:** Conversations write. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `sms.send` | W | Send or schedule SMS. `mode=alphanumeric` uses the v1 sender contract. | `mode` (`standard` default, `alphanumeric`), `from_number` / `from_alphanum`, `to_number`, `content`, `user_id`, `user_id_forced`, `scheduled_at` | | `sms.opt_out.add` | W | Add a number to the team opt-out list. | `phone_number` | | `sms.opt_out.remove` | W | Remove a number from the opt-out list. | `phone_number` | ### WhatsApp **Permission:** Conversations. A valid key is enough on REST for some WhatsApp routes; MCP still lists only tools the credential can call. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `whatsapp.accounts.list` | R | List WhatsApp accounts. | *(none)* | | `whatsapp.templates.list` | R | List templates. | account as advertised | | `whatsapp.conversations.list` | R | List WhatsApp conversations. | filters as advertised | | `whatsapp.templates.send` | W | Send a template to a number. | template + destination | | `whatsapp.messages.send` | W | Send a message in a conversation. | conversation + body | ### Campaigns **Permission:** Campaigns (often granted on API keys by default). `campaigns.list` with `assigned_to_me=true` lists campaigns assigned to the caller; `ascending_order` and `is_running` cannot be combined with that flag. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `campaigns.list` | R | List calling campaigns. | `limit`, `offset`, `ascending_order`, `is_running`, `assigned_to_me` | | `campaigns.get` | R | Get a campaign. | `campaign_uuid` | | `campaigns.numbers.list` | R | Numbers in the campaign. | `campaign_uuid`, pagination | | `campaigns.groups.list` | R | Attached groups. | `campaign_uuid`, pagination | | `campaigns.users.list` | R | Attached users. | `campaign_uuid`, pagination | | `campaigns.logs.list` | R | Campaign logs. | `campaign_uuid` | | `campaigns.create` | W | Create a campaign. | `name`, `max_retry`, optional tags / IVR / dates | | `campaigns.start` | W | Start or schedule. | `campaign_uuid`, optional `start_date` | | `campaigns.stop` | W | Stop. | `campaign_uuid` | | `campaigns.reset` | W | Reset. | `campaign_uuid` | | `campaigns.update` | W | Patch name, retries, start date and/or script. Empty `script_uuid` unlinks the script. | `campaign_uuid` plus at least one of `name`, `max_retry`, `start_date`, `script_uuid` | | `campaigns.numbers.add` | W | Add numbers. | `campaign_uuid`, `to_numbers` | | `campaigns.numbers.delete` | W | Remove numbers. | `campaign_uuid`, `to_numbers` | | `campaigns.groups.add` | W | Attach groups. | `campaign_uuid`, `ids` | | `campaigns.groups.remove` | W | Detach groups. | `campaign_uuid`, `ids` | | `campaigns.users.add` | W | Attach users. | `campaign_uuid`, `ids` | | `campaigns.users.remove` | W | Detach users. | `campaign_uuid`, `ids` | | `campaigns.tags.add` | W | Add one tag without dropping existing tags. | `campaign_uuid`, `tag_id` | | `campaigns.tags.remove` | W | Remove one tag. | `campaign_uuid`, `tag_id` | CSV column editing is **not** exposed on MCP. ### Empower and tasks **Permission:** Empower. Visibility also follows Empower roles (admin / supervisor / user). | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `empower.calls.list` | R | Search analysed calls. | filters as advertised | | `empower.calls.get` | R | Get an analysed call. | call UUID | | `empower.calls.get_moments` | R | Call moments. | call UUID | | `empower.calls.get_summary` | R | Call summary. | call UUID | | `empower.flags.list` | R | List flags. | *(none)* | | `empower.calls.delete` | W | Delete calls or only their media. | call UUIDs / media flag | | `empower.flags.associate` | W | Attach a flag. | call + flag | | `empower.flags.disassociate` | W | Detach a flag. | call + flag | | `tasks.list` | R | List team tasks. | filters as advertised | | `tasks.create` | W | Create a batch of tasks. | task payload | ### Webhooks **Permission:** webhooks / integrations (`webhooks:manage` on OAuth). There is no separate read-only webhook scope: list/get appear with the same grant as mutations. | Tool | Access | Description | Main parameters | |------|--------|-------------|-----------------| | `webhooks.list` | R | List subscriptions with stable `webhook_id`. | *(none)* | | `webhooks.get` | R | Get one subscription. | `webhook_id` | | `webhooks.create` | W | Create or merge by target URL. | `target_url`, `events` | | `webhooks.events.add` | W | Union extra events onto a subscription. | `webhook_id`, `events` | | `webhooks.delete` | W | Delete a subscription. | `webhook_id` | Event names: `call.started`, `call.answered`, `call.ended`, `call.missed`, `call.voicemail`, `call.aftercall`, `sms.sent`, `sms.received`, `sms.delivery_receipt`, `fax.received`, `contact.call`, `contact.search`. `contact.call` and `contact.search` accept a single target URL each: attaching one to a second URL fails and nothing is saved. Their keys are returned in `event_signing_keys`. Replacing the whole event set is REST-only (`PUT`).

Business capability
Agent Tool Exposure AE-100.10

Operations 2

POST /mcp Model Context Protocol (MCP) endpoint #
POST /mcp/{token} Model Context Protocol (MCP) endpoint — token in URL path #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/ringover:ringover-mcp-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

ringover-mcp-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  license:
    name: Proprietary – Contact us for usage terms
    url: https://www.ringover.com/contact
  description: '# Ringover Public API


    Welcome to the Ringover Public API. This RESTful API lets you integrate Ringover telephony, messaging, contacts, and AI analytics into your applications. ## Base URL


    | Region | Base URL |

    |--------|----------|

    | Europe | `https://public-api.ringover.com/v2` |

    | United States | `https://public-api-us.ringover.com/v2` |


    ## Authentication


    All requests must include your API key in the `Authorization` header:


    ```

    Authorization: your-api-key-here

    ```


    To create an API key:

    1. Open the Ringover Dashboard. 2. Navigate to **Developer > API Keys**. 3. Click **Create an API key**, select a user, and set a label. 4. Configure the permissions for this key (see Permissions below). ## Permissions


    Each API key is associated with **7 permission categories**, each configurable as **None**, **Read**, **Write**, or **Read+Write**:


    | Category | Controls access to |

    |----------|-------------------|

    | **Calls** | Call history, archives, live call controls, callbacks |

    | **Contacts** | Contact CRUD and phone number management |

    | **Users** | User listing, plannings, presences, groups, user blacklists |

    | **Numbers** | Phone number listing, team blacklist |

    | **IVRs** | IVR/scenario listing, tag management |

    | **Conversations** | SMS/Chat conversations, messages, SMS sending |

    | **Empower** | AI call analysis, summaries, moments, analytics |


    ### The Monitoring flag (Supervision)


    In addition to R/W permissions, each API key has a **Monitoring** toggle that controls the **scope** of data returned:


    | Monitoring | Effect |

    |------------|--------|

    | **OFF** | Your permissions give access to **your own data only** (your calls, your numbers, your conversations…) |

    | **ON** | Your permissions give access to **the entire team''s data** (all users, all calls, all conversations…) |


    Monitoring does **not** grant additional permissions — it widens the scope of existing ones. Some routes **require** Monitoring to be enabled and will return `401` without it. Conversely, some routes may ignore the Monitoring flag entirely or apply it differently — unless stated otherwise in the endpoint documentation, the default behavior described above applies. > Each endpoint in this documentation specifies its exact permission and monitoring requirements. ### Special cases


    - **Campaigns, Tasks, WhatsApp**: These routes do not require specific token permissions. A valid API key is sufficient. - **Empower**: Uses its own role system (Admin / Supervisor / User) in addition to the Empower R/W permission. - **Transcriptions**: Access is controlled by a team-level setting, not by the token permissions. - **Conferences**: All conference routes require Monitoring enabled. ## Rate Limiting


    A **2-request-per-second** rate limit is applied per API key. Exceeding this limit returns `429 Too Many Requests`. ## Pagination


    List endpoints support offset-based pagination with two parameters:

    - `limit_count`: Maximum number of items to return (default: 100, max varies by endpoint). - `limit_offset`: Number of items to skip (default: 0). Some call-related endpoints also support cursor-based pagination via `last_id_returned`. ## Error Responses


    | HTTP Code | Meaning |

    |-----------|---------|

    | `400` | Bad request — invalid parameters or body |

    | `401` | Unauthorized — invalid/expired API key, or access denied by permission/monitoring checks on most endpoints |

    | `403` | Forbidden — authenticated request refused by specific endpoint logic (notably some Empower routes) or upstream forwarded services |

    | `402` | Payment required — feature not available on your plan |

    | `404` | Resource not found |

    | `429` | Rate limit exceeded |

    | `500` | Internal server error |


    ## SCIM 2.0 Provisioning


    Ringover exposes a **SCIM 2.0** server (RFC 7643 / RFC 7644) for automated user and group provisioning from your identity provider (Okta, Microsoft Entra ID, …). It reuses the **same API key** as the REST API (`Authorization` header).'
  version: 2.1.0
  title: Ringover Public MCP API
  x-logo:
    url: https://webcdn.ringover.com/app/img/misc/logo_app_redoc.png
    backgroundColor: '#FAFAFA'
    altText: Ringover Logo
  termsOfService: https://ringover.com/terms/
  contact:
    email: support@ringover.com
servers:
- url: https://public-api.ringover.com/v2
  description: Production server (Europe)
- url: https://public-api-us.ringover.com/v2
  description: Production server (United States)
security:
- Authorization: []
tags:
- name: MCP
  description: '## Model Context Protocol


    The MCP endpoint exposes a **curated** set of Ringover operations to AI assistants (Claude, ChatGPT, Cursor, etc.) via the Model Context Protocol. It is not a 1:1 copy of the REST API: tools that are hard for an agent to fill, rarely useful, or unsafe are omitted, and related mutations are grouped (for example `calls.archive`, `channels.control`, `users.update`). Source of truth for names, argument schemas and titles is `tools/list`. This page lists the frozen catalogue. ### Useful links


    - Model Context Protocol specification

    - Lifecycle & initialization

    - Tools

    - Streamable HTTP transport


    ### How it works


    MCP is JSON-RPC 2.0 over HTTP using the Streamable HTTP transport. All interactions use `POST /mcp` with a JSON-RPC body. The server is **stateless** — every request is independent. There is no session (`Mcp-Session-Id` is not used) and no `notifications/tools/list_changed`. ### Request headers


    Every `POST` must send:


    - `Content-Type: application/json`

    - `Accept: application/json, text/event-stream` — **both** media types are required (comma-separated, as MCP clients do). A request that omits `text/event-stream` is rejected with HTTP `400`. ### Response format


    Successful MCP calls return HTTP `200` with `Content-Type: application/json` and a **single JSON-RPC object** in the body. There is no SSE stream: the endpoint is stateless (one request, one response, no shared connection across tool calls), so Server-Sent Events would not add multiplexing here. ### JSON-RPC errors vs HTTP errors


    - **Supported methods** (`initialize`, `tools/list`, `tools/call`): invalid tool arguments, tool rate limits, and application failures on `tools/call` are returned with HTTP `200` (JSON-RPC `error` or a tool result with `isError: true`). - **HTTP transport rejections** (before the message is handled as MCP): invalid `Accept`, malformed JSON-RPC, unsupported method **name** (anything other than the three methods above), etc. → HTTP **`400`** with a **plain-text** body, not a JSON-RPC envelope. Example: `JSON RPC not handled: "monitor/unknown_method" unsupported`. - Missing or invalid credential → **`401`**. HTTP rate limit → **`429`**. ### Available JSON-RPC methods


    | Method | Purpose |

    |--------|---------|

    | `initialize` | Capability negotiation. Returns server info (`name: "ringover-public-api"`, `version: "v1.0.0"`) and capabilities. Optional — you can call `tools/list` or `tools/call` directly. |

    | `tools/list` | Returns the tools **this credential can use**, with `name`, `title`, `description`, `inputSchema` and `annotations`. |

    | `tools/call` | Execute a tool by `name` with `arguments`. |


    `tools/list` never returns a tool the caller cannot invoke. A write tool is listed only when the credential has the matching **write** grant. Calling a hidden name is refused (`forbidden`). ### Authentication


    The MCP endpoint accepts the same credentials as the rest of public-api:


    - a **Public API key** (raw, no `Bearer` prefix)

    - an **OAuth 2.0 access token** (`Authorization: Bearer `), when OAuth is enabled for the environment


    For API keys, three sources are tried in this **order** (first one set wins):


    | # | Source | Endpoint | Example | When to use |

    |---|--------|----------|---------|-------------|

    | 1 | URL path parameter | `POST /mcp/{token}` | `POST /mcp/abcd1234…` | Last resort for clients that cannot set headers or query strings. |

    | 2 | Query string `?token=` | `POST /mcp?token=…` | `POST /mcp?token=abcd1234…` | No-code / web tools that cannot set custom headers. |

    | 3 | `Authorization` header | `POST /mcp` | `Authorization: abcd1234…` | **Recommended** — same as REST. |


    The token is then normalized internally, so rate limiting, logging and permission checks behave the same regardless of source. > ⚠️ **Security note** — Tokens in the URL path or query string often appear in proxy logs, browser history and access logs. Prefer the `Authorization` header.'
paths:
  /mcp:
    post:
      operationId: mcpEndpoint
      tags:
      - MCP
      summary: Model Context Protocol (MCP) endpoint
      description: 'JSON-RPC 2.0 endpoint implementing the Model Context Protocol.

        The server is **stateless** — each request is independent, no session management.


        Supported methods: `initialize`, `tools/list`, `tools/call`.

        The tool catalogue is **curated** (read and write). `tools/list` returns only the tools this credential can call. Names use `{resource}.{action}` (for example `contacts.search`).


        ### Authentication


        Three accepted sources (first one set wins):


        1. URL path parameter — `POST /mcp/{token}` (see the dedicated operation below)

        2. Query string — `POST /mcp?token=…`

        3. `Authorization` header — `POST /mcp` (recommended)


        See the **mcp** tag description for transport headers (`Accept`), JSON responses, HTTP `400` transport errors, the tool catalogue, parameters, and permission requirements.'
      x-permissions:
        required: Depends on the tool called (see mcp tag description)
      security:
      - Authorization: []
      - AuthorizationQuery: []
      parameters:
      - name: Accept
        in: header
        required: true
        description: 'Must include **both** `application/json` and `text/event-stream` (comma-separated).

          Example: `application/json, text/event-stream`.

          '
        schema:
          type: string
          example: application/json, text/event-stream
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JsonRpcRequest'
            examples:
              initialize:
                summary: Initialize (optional in stateless mode)
                value:
                  jsonrpc: '2.0'
                  id: 1
                  method: initialize
                  params:
                    protocolVersion: '2025-06-18'
                    capabilities: {}
                    clientInfo:
                      name: my-client
                      version: 1.0.0
              tools_list:
                summary: List available tools
                value:
                  jsonrpc: '2.0'
                  id: 2
                  method: tools/list
              tools_call:
                summary: Call a tool
                value:
                  jsonrpc: '2.0'
                  id: 3
                  method: tools/call
                  params:
                    name: contacts.search
                    arguments:
                      query: John
                      limit: 10
      responses:
        '200':
          description: 'JSON-RPC response (`Content-Type: application/json`). On success, the `result` field contains the method output.


            For supported methods, protocol and tool errors use HTTP `200`: JSON-RPC `error` (for example tool rate limit) or a `tools/call` result with `isError: true` (forbidden, not found, invalid input). Unknown method names and other transport-level failures are **not** included here — they return HTTP `400` (see below).

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonRpcResponse'
              examples:
                tools_list_response:
                  summary: tools/list response (truncated)
                  value:
                    jsonrpc: '2.0'
                    id: 2
                    result:
                      tools:
                      - name: contacts.search
                        description: Search contacts by name, phone number, or company.
                        inputSchema:
                          type: object
                          properties:
                            query:
                              type: string
                              description: Search by name, phone number, or company
                            limit:
                              type: integer
                              description: Max results to return (1-500, default 50)
                tools_call_response:
                  summary: tools/call response
                  value:
                    jsonrpc: '2.0'
                    id: 3
                    result:
                      content:
                      - type: text
                        text: '{"contact_id": 123, "firstname": "John", "lastname": "Doe"}'
                error_response:
                  summary: JSON-RPC error (e.g. rate limit exceeded)
                  value:
                    jsonrpc: '2.0'
                    id: 3
                    error:
                      code: -32603
                      message: rate limit exceeded for tool contacts.search
        '400':
          description: 'HTTP transport rejection before MCP handles the message: invalid or incomplete `Accept` header,

            malformed JSON-RPC, unsupported method name (only `initialize`, `tools/list`, and `tools/call` are supported),

            or similar. The body is **plain text**, not JSON-RPC (for example `JSON RPC not handled: "foo" unsupported`).

            '
        '401':
          description: Missing or invalid API key.
        '429':
          description: HTTP rate limit exceeded (1 req/s per API key, burst 10).
  /mcp/{token}:
    post:
      operationId: mcpEndpointWithToken
      tags:
      - MCP
      summary: Model Context Protocol (MCP) endpoint — token in URL path
      description: 'Same JSON-RPC 2.0 endpoint as `POST /mcp`, but the Public API token is supplied **as a path parameter** instead of through the `Authorization` header or the `?token=` query string.


        This variant exists because some MCP clients cannot set custom HTTP headers nor query strings. Behavior is otherwise **strictly identical** to `POST /mcp`:


        - same JSON-RPC methods (`initialize`, `tools/list`, `tools/call`)

        - same Streamable HTTP transport (`Accept`, JSON responses, HTTP `400` transport errors — see the **mcp** tag)

        - same rate limiting (1 req/s per token, burst 10)

        - same permission and Monitoring rules

        - same stateless behavior (no `Mcp-Session-Id`)


        > ⚠️ **Security note** — The token is part of the URL and will likely be logged by proxies, browsers and access logs. Use this variant only when neither the `Authorization` header nor the `?token=` query string is available, and rotate any token that may have leaked.


        OpenAPI 3.0 cannot declare an `apiKey` security scheme located in `path`, so this operation is documented with the `AuthorizationPath` scheme (declared as `query` for tooling compatibility — the actual transport is the URL path shown by the `token` path parameter below).'
      x-permissions:
        required: Depends on the tool called (see mcp tag description)
      security:
      - AuthorizationPath: []
      parameters:
      - name: token
        in: path
        required: true
        description: Your Public API token (same value as the `Authorization` header).
        schema:
          type: string
          example: your-public-token
      - name: Accept
        in: header
        required: true
        description: 'Must include **both** `application/json` and `text/event-stream` (comma-separated).

          Example: `application/json, text/event-stream`.

          '
        schema:
          type: string
          example: application/json, text/event-stream
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JsonRpcRequest'
      responses:
        '200':
          description: 'JSON-RPC response (`Content-Type: application/json`). Same as `POST /mcp`.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonRpcResponse'
        '400':
          description: HTTP transport rejection (invalid `Accept`, unsupported method name, malformed JSON-RPC, etc.). Plain-text body — see `POST /mcp`.
        '401':
          description: Missing or invalid API key.
        '429':
          description: HTTP rate limit exceeded (1 req/s per API key, burst 10).
components:
  schemas:
    JsonRpcError:
      type: object
      required:
      - code
      - message
      properties:
        code:
          type: integer
          description: 'JSON-RPC error code. Standard codes: -32700 (parse error), -32600 (invalid request), -32601 (method not found), -32602 (invalid params), -32603 (internal error).'
        message:
          type: string
          description: Human-readable error message.
        data:
          description: Optional additional error data.
    JsonRpcResponse:
      type: object
      required:
      - jsonrpc
      properties:
        jsonrpc:
          type: string
          const: '2.0'
        id:
          oneOf:
          - type: string
          - type: integer
          - type: 'null'
          description: Echoed request identifier, or null for notifications.
        result:
          type: object
          description: Present on success. Content depends on the method called.
        error:
          $ref: '#/components/schemas/JsonRpcError'
    JsonRpcRequest:
      type: object
      required:
      - jsonrpc
      - method
      properties:
        jsonrpc:
          type: string
          const: '2.0'
          description: JSON-RPC protocol version. Must be "2.0".
        id:
          oneOf:
          - type: string
          - type: integer
          description: Request identifier. The server echoes it back in the response.
        method:
          type: string
          description: 'The JSON-RPC method to call: `initialize`, `tools/list`, or `tools/call`.'
          enum:
          - initialize
          - tools/list
          - tools/call
        params:
          type: object
          description: Method-specific parameters. Required for `initialize` and `tools/call`, optional for `tools/list`.
  securitySchemes:
    Authorization:
      description: "We use API keys for authentication to authorize API requests. First, you need to create a public access token (API key) and select the appropriate rights for each user. To do so:\n  1. Open the Ringover Dashboard.\n  2. Go to the **Developer** section.\n  3. Click the **Create an API key** button.\n  4. Select a user in the drop-down menu and enter a label for the key and click the **Create** button.\n  5. Click the **Edit** button corresponding to the API key and select the appropriate rights.\n\nOnce you've created a public access token, you can use it in the `Authorization` header to authenticate your HTTP request.\n\n```\nAuthorization: <your-public-token>\n```\n\nThis is the **recommended authentication method** and the only one supported by the REST and SCIM endpoints.\n"
      type: apiKey
      name: Authorization
      in: header
    AuthorizationQuery:
      description: '**Alternative authentication method, only available on the MCP endpoint (`/mcp`).**


        Pass your Public API token via the `token` query string parameter:


        ```

        POST /mcp?token=<your-public-token>

        ```


        Useful for clients (no-code platforms, browser tools, etc.) that cannot set custom HTTP headers.


        See the **mcp** tag for details on the three accepted authentication sources and their precedence.

        '
      type: apiKey
      name: token
      in: query
    AuthorizationPath:
      description: '**Alternative authentication method, only available on the MCP endpoint (`/mcp/{token}`).**


        Pass your Public API token directly inside the URL path:


        ```

        POST /mcp/<your-public-token>

        ```


        Most permissive variant — works with any HTTP client, including those that strip custom headers and query strings.


        > ⚠️ The token appears in URLs and is therefore likely to be logged by proxies, browsers and access logs. Prefer the `Authorization` header whenever your client supports it, and rotate any token that may have leaked.


        OpenAPI 3.0 does not support `apiKey` in `path`, so this scheme is declared in `query` for tooling compatibility — the actual transport is the URL path. See the **mcp** tag for details.

        '
      type: apiKey
      name: token
      in: query
x-tagGroups:
- name: Ringover Public API
  tags:
  - How to paginate?
  - teams
  - groups
  - users
  - numbers
  - ivrs
  - tags
  - conferences
  - calls
  - campaigns
  - channels
  - contacts
  - conversations
  - messages
  - sms
  - profiles
  - presences
  - blacklist
  - webhook
  - callbacks
  - surveys
  - snoozes
  - transcriptions
  - cdn
  - empower
  - whatsapp
  - task
  - mcp
- name: SCIM 2.0 Provisioning
  tags:
  - scim