> ## Documentation Index
> Fetch the complete documentation index at: https://docs.robase.dev/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> For chatbots and coding agents, start at /guides/ai-agents.
> Hosted MCP: POST https://api.robase.dev/mcp (Streamable HTTP). Auth: Authorization: Bearer robe_… or robe_agent_….
> Phase 1 tools: get_pricing, send_otp, verify_otp, get_otp, send_sms, get_sms. No payment or top-up tools.
> Call get_pricing; treat listed:true as marketed markets (NG, GH, KE, ZA, GB, BJ, CI, US). Do not invent countries or delivery percentages.
> Prefer OTP-shaped tests such as "Your Robase test OTP is 123456". Do not send Hello or Good morning as tests. Match errors on error.type.

# Rate limits

> Limits per API key, per workspace, per destination phone and prefix, plus a per-IP flood net. 429 includes Retry-After.

Exceeding a limit returns `429` with `error.type: rate_limited` and a `Retry-After` header. `Retry-After` is the number of whole seconds until the counter that refused you resets (at least 1).

## Per API key and per workspace

Every `/v1` call, and every MCP tool call, counts against the API key that made it and against its workspace. These are the defaults:

| Counter | Default | Window |
| - | - | - |
| Per API key, sends (`POST /v1/otp/send`, `/v1/otp/verify`, `/v1/sms/send`) | 600 | 1 minute |
| Per API key, reads (`GET /v1/otp/{id}`, `GET /v1/sms/{id}`) | 1200 | 1 minute |
| Per workspace, all keys together | 3000 | 1 minute |

Each key has its own counters, so one busy key does not use up another key's allowance. A request refused by its key's limit does not count against the workspace. Different workspaces never share these counters. Contact support if your workspace needs different limits.

## Per destination prefix

`POST /v1/otp/send` is also counted per destination prefix: the first six digits of the E.164 number (country code plus the start of the network code). The default is **300 OTPs per prefix per hour** for each workspace. A sudden burst of codes to one number range is a common sign of SMS pumping.

## SMS pumping protection

SMS pumping is traffic that requests codes for numbers the attacker is paid for, not for real users. Robase has these controls against it:

* **Countries.** Each workspace has a list of countries it sends to, under [Settings → Countries](https://robase.dev/app/settings/countries). New workspaces start with their billing country. Workspaces that existed before this control started with every country they had sent to in the previous 90 days. For now, a send to a country that is off is logged but still sent. When enforcement starts, it will be refused with `403 country_not_enabled`.
* **Unusual prefix traffic.** Every five minutes, Robase checks each destination prefix. A prefix is flagged when, in the last hour, it had at least 30 OTPs, under 20% of them were verified, and the volume was at least three times the prefix's usual hourly volume over the last 7 days. The first time, the prefix is throttled for an hour: at most 10 OTPs an hour to that prefix. If it is flagged again within a day, it is blocked for your workspace. Sends to it return `403 prefix_blocked` until support lifts the block. These checks can miss some attacks and can flag real traffic. Contact support if a prefix you need is blocked.

## Per destination phone

These counters are kept per workspace and per E.164 number. Your traffic to a number never counts against another workspace sending to the same number.

| Endpoint | Limit | Window |
| - | - | - |
| `POST /v1/otp/send` | 3 | 10 minutes |
| `POST /v1/otp/verify` | 10 | 10 minutes |
| `POST /v1/sms/send` | 10 | 1 minute |

## Per client IP

A general bucket of **1200 requests per minute** per client IP covers `/v1` and the dashboard (`internal/router.go`). Auth endpoints and provider DLR callbacks have their own limiters and are exempt from this bucket.

Successful responses may include `X-RateLimit-Remaining`. On `/v1` it is the smaller of what is left for the key and for the workspace this minute.

## Back off

Honour `Retry-After`. Do not tight-loop a 429. OTP send is intentionally tight so a leaked key cannot flood a single number.

Over MCP, a rate-limited tool call returns `error.type: rate_limited` with `error.retry_after_seconds`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.