Skip to content
Hypamoon
API docs

Start for free. Sign up without a card and you'll get a test project and a test key right away. Once your company (or, for a personal account, you) is verified, you can create a live key in the portal.

Authentication

API keys, scopes, rate limits, the error format and request IDs.

Every request to the API carries an API key as a bearer token:

curl https://api.hypamoon.com/api/v1/project \
  -H "Authorization: Bearer $HYPAMOON_API_KEY"
await fetch("https://api.hypamoon.com/api/v1/project", {
  headers: { Authorization: `Bearer ${process.env.HYPAMOON_API_KEY}` },
});
requests.get(
    "https://api.hypamoon.com/api/v1/project",
    headers={"Authorization": f"Bearer {os.environ['HYPAMOON_API_KEY']}"},
)

There's no other way to authenticate: no query parameter, no cookie. Keep keys on your server; never ship them in a browser or mobile app.

Keys

A key belongs to one project. A project has its own sites and apps, data, media, domains, email, numbers, call plan, assistant and calls; if you build two apps, use two projects.

Prefix Mode
hm_live_ Live Real numbers, real calls and SMS, real costs within your spending cap.
hm_test_ Test A test project that never reaches the phone network and costs nothing. Sites and data are real here too. Test numbers come from the fictional range +447700900000 to +447700900999. See Test mode.

New projects since October 2026 are one project: a hm_test_ key on it can never do anything real, and phone, outbound calls, SMS, email to other people, payments and buying domains each go live on their own at https://app.hypamoon.com/go-live. Older projects come as a pair, a test project and a live project, each with its own keys. When you sign up at https://app.hypamoon.com, you get your first test key right away, with every scope. You can create more keys in the portal under API keys: test keys at any time, and live keys once your company (or, for a personal account, you) is verified under Verification. A test key on the live project, or a live key on the test project, returns 403 with key_mode_mismatch.

The prefix is followed by 32 letters and digits. Anything else is rejected without a lookup.

We store only a hash of the key. You see the full key once, when it is created; after that we can only show its first characters (for example hm_live_4f9Q) to help you recognize it. Lost a key? Revoke it and create a new one. A revoked key returns 401 immediately.

Scopes

Each key has a list of scopes. The first test key has all of them. When you create a key in the portal, you select its scopes; the read scopes are enough for a dashboard.

Scope Allows Read-only
project:read GET /project, the balance, the agents, and the MCP server yes
numbers:read GET /numbers, GET /numbers/available, GET /numbers/{id}/call-plan yes
calls:read GET /calls, GET /calls/{id}, including transcripts, and POST /test/calls in test mode yes
messages:read SMS messages and emails, with their status yes
chat:read Chat conversations and chat widget tokens yes
sites:read Sites, their versions, domains, apps, the media library and sending domains yes
data:read Collections and their documents yes
project:write Setting the project's company details and managing agents no
numbers:write Claiming numbers and setting call plans no
assistant:write Configuring the voice AI assistant no
webhooks:write Creating, listing, deleting, enabling and testing webhook endpoints no
messages:write Sending SMS and email no
calls:write Outbound calls made by the assistant no
chat:write Starting chats and managing chat widget tokens no
sites:write Publishing sites, and managing domains, apps, the media library and sending domains no
data:write Creating collections and writing documents no

Give each key only what it needs. A key that only reads summaries for a dashboard doesn't need webhooks:write. A request without the right scope gets 403 with missing_scope.

Limit a key to some sites and apps

By default a key works on the whole project. In the portal, under API keys, an owner or admin can limit a key to selected sites and apps: when you create it, or later with Access next to the key. The app of a site comes along, and so does the data the site or app uses (the collections its forms post to, and the collections of the app). The limit holds on every route and every MCP tool, also for a key made by an owner:

  • lists (GET /sites, GET /apps, GET /collections) show only what the key may use;
  • a site, app or collection outside the limit returns 403 with forbidden and a user_message like "This API key is limited to: Newme2day site. An owner or admin can change that in the portal under API keys.";
  • anything for the whole project returns the same 403: billing and the balance, the team, domains, email, numbers and calls, webhooks, agents, secrets, a new site or app, a new collection, and working on a client project of an agency.

GET /project (get_project) tells the key what it is limited to, in access: null for the whole project, or the sites, apps and collections with limited_by (api_key, connection, or member when the person behind it is limited in the team). A limited key gets only the project's id, name, edition, mode and access there. A change to the limit applies from the next request.

Chats you connected with OAuth (Claude, ChatGPT, Grok) work the same way: limit each one in the portal under Connect your chat, after you connected it. If the person behind a key or connection is limited in the team too, the key gets what both allow.

Rate limits

Each key can make 120 requests per 60 seconds. If you go over the limit, you get 429 with a Retry-After header (in seconds):

HTTP
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json; charset=utf-8
Retry-After: 60
X-Request-Id: req_8Kq2mXvN4pR7tL1wZ9cB

Every authenticated request counts, even one that fails because of a missing scope. Wait the number of seconds in Retry-After before you try again. For a stream of events, use webhooks instead of polling GET /calls.

Errors

All errors use one format, RFC 9457 problem details, with the content type application/problem+json:

JSON
{
  "type": "https://hypamoon.com/docs/errors/missing_scope",
  "title": "Forbidden",
  "status": 403,
  "detail": "This API key lacks the 'webhooks:write' scope.",
  "request_id": "req_8Kq2mXvN4pR7tL1wZ9cB"
}
Field
type A URL to the page that explains this error and how to fix it. Branch on this, not on detail.
title The HTTP status in words.
status The HTTP status code, the same as on the response.
detail One human-readable sentence, specific to this request. The wording may change.
request_id The same value as the X-Request-Id header.

All error types are listed on the Errors page.

The checks run in a fixed order, so you always get the first one that fails: missing or unknown key (401), revoked key or deleted project (401), project not enabled for the API (403), rate limit (429), scope (403), then the request itself (400, 404, 409).

Request IDs

Every response, success or error, has an X-Request-Id header. Include it when you contact us; it's how we find your request in our logs.

You can send your own X-Request-Id, for example the ID your system already uses for the job. We use it if it's 1 to 64 characters long and contains only letters, digits, - and _. Otherwise, we generate one: req_ followed by 20 characters.

curl -i https://api.hypamoon.com/api/v1/calls \
  -H "Authorization: Bearer $HYPAMOON_API_KEY" \
  -H "X-Request-Id: sync-job-2026-10-01-0001"
const res = await fetch("https://api.hypamoon.com/api/v1/calls", {
  headers: {
    Authorization: `Bearer ${process.env.HYPAMOON_API_KEY}`,
    "X-Request-Id": "sync-job-2026-10-01-0001",
  },
});
console.log(res.headers.get("x-request-id"));
res = requests.get(
    "https://api.hypamoon.com/api/v1/calls",
    headers={
        "Authorization": f"Bearer {os.environ['HYPAMOON_API_KEY']}",
        "X-Request-Id": "sync-job-2026-10-01-0001",
    },
)
print(res.headers["X-Request-Id"])

Responses from the API are never cached (Cache-Control: no-store).

Hypamoon is the infrastructure your chat or agent builds on for a business. Hypamoon API, version 1.hypamoon.com