API reference
One base URL, one header, JSON in and JSON out. This page is the part every other page assumes.
- Base URL
- https://api.murusai.com
- Authentication
- Authorization: Bearer cw_live_…
- Format
- JSON in, JSON out. E.164 numbers, UTC times.
- Limits
- 600 reads a minute per key; 1,200 events a minute per account.
Base URL
https://api.murusai.comEvery path starts with /v1. We have not broken /v1 and do not intend to. New fields appear in responses without notice, so parse leniently and ignore what you do not know; a field that exists today will not change type or disappear.
API keys
Authenticate with a bearer token. Your account's key was shown once when the account was made; more can be made, with labels and scopes, under Settings → API keys in the dashboard.
BASE=https://api.murusai.com
curl "$BASE/v1/account" \
-H "Authorization: Bearer $MURUSAI_KEY"const BASE = "https://api.murusai.com";
const KEY = process.env.MURUSAI_KEY;
const url = new URL("/v1/account", BASE);
const res = await fetch(url, {
headers: {
Authorization: `Bearer ${KEY}`,
},
});
const data = await res.json();import os, requests
BASE = "https://api.murusai.com"
KEY = os.environ["MURUSAI_KEY"]
r = requests.get(
f"{BASE}/v1/account",
headers={"Authorization": f"Bearer {KEY}"},
)
data = r.json()X-Murusai-Key: cw_live_… is accepted in place of the Authorization header, for platforms whose webhook configuration will not let you set one.
Scopes
- cw_live_…full
- Reads and writes. Your account's original key is one of these.
- cw_read_…read
- Reads only. A write answers
403 read_only_key. Use one of these anywhere the key leaves your own infrastructure.
Ingest tokens
Some things are posted to us by a system you do not fully control: a platform's webhook, a carrier's voice URL, a pipeline that has no secrets store. For those there is a second kind of credential: a token that lives in the path and can do exactly one thing.
POST /v1/events/lv_4Qx9…A token issued for the events path can post events on that path and nothing else: it cannot read a call, list a number, or post on another path. Leaving it in a platform's settings is safe, and each one rotates on its own under Settings → Live events. The gate's per-number token works the same way; see Twilio.
Conventions
Phone numbers
E.164, with the + and the country code: +14155550100. We parse most of what people actually send and everything we hand back is normalised. Anything we cannot read is a 400, not a guess. In a path, encode the plus: /v1/reputation/%2B14155550100.
Times
ISO 8601 with a timezone, always UTC: 2026-09-21T02:14:07.000Z.
Errors
A failure is a non-2xx status and a body with an error field holding a short stable string, sometimes with context beside it. See errors and limits.
{ "error": "invalid_caller" }Sending something twice
Events are keyed on your own call_id. Posting the same call start again returns what we decided the first time with "duplicate": true rather than scoring it twice, so a webhook you are not sure was delivered is always safe to retry.
Every endpoint
Endpoints that need a signed-in person rather than a key (creating keys, changing plans, alert channels, the trusted list) are not listed; they are the dashboard's, and are noted where they touch something here.