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.
Errors
Every error from the Hypamoon API is application/problem+json:
{
"type": "https://hypamoon.com/docs/errors/company_details_missing",
"title": "Unprocessable Content",
"status": 422,
"detail": "Set the company details first with PUT /api/v1/project/company. Missing: registration_number.",
"request_id": "req_4fT0aQ...",
"missing": ["registration_number"]
}type points to the section below with the same name. detail says what went
wrong in this request. Some errors carry extra fields: errors (a list of
{ path, message }), missing or current_version. Every response has an
X-Request-Id header; mention it when you contact support.
Every error also has user_message: one calm sentence in plain English that a
chat or app can show the user as it is, without technical terms. Some errors
add next_step: what the chat or agent itself should do next. When an error
looks like an outage, GET /api/v1/status (MCP: get_status) says whether
Hypamoon has a reported problem; the public page is https://status.hypamoon.com.
All error types
| Status | Type | |
|---|---|---|
| 400 | bad_request |
The request could not be understood. |
| 400 | invalid_json |
The body is not valid JSON. |
| 400 | invalid_parameter |
A query parameter or header has a value we cannot use, for example limit=500 on GET /api/v1/calls, a cursor you did not get from us, or an If-Match that is not a version. |
| 422 | validation_failed |
The body is JSON, but some fields are wrong or missing. |
| 401 | unauthorized |
The request has no valid API key or OAuth access token. |
| 401 | missing_api_key |
There is no Authorization header. |
| 401 | invalid_api_key |
We do not recognize this key. |
| 401 | api_key_revoked |
This key was revoked. |
| 401 | project_deleted |
The project of this key no longer exists. |
| 403 | forbidden |
The key is valid but is not allowed to do this. |
| 403 | project_not_enabled |
The key belongs to an account that is not an API project. |
| 403 | missing_scope |
The key lacks the scope this route needs; detail names it. |
| 403 | key_mode_mismatch |
The key and its project are in different modes: a test key (hm_test_) on a live project, or a live key (hm_live_) on a test project. |
| 403 | test_key_required |
This route only exists in test mode, for example POST /api/v1/test/calls. |
| 422 | test_number_limit_reached |
A test project has at most a few test numbers. |
| 404 | not_found |
The resource in the URL does not exist, or it belongs to another project. |
| 405 | method_not_allowed |
The path exists, but not with this method, for example DELETE /api/v1/project. |
| 409 | conflict |
The request clashes with the current state. |
| 409 or 412 | version_conflict |
Someone changed this resource after you read it. |
| 409 | confirmation_required |
The change would replace or delete something that is live now (a DNS record on an active domain, an old record on a subdomain, a nameserver switch that does not match yet). |
| 429 | rate_limited |
Too many requests: the limit is 120 per minute per key. |
| 402 | payment_required |
Billing blocks this request. |
| 402 | payment_mandate_missing |
The project has no way to pay yet: no saved card and no prepaid balance. |
| 402 | billing_blocked |
This month's spending cap is reached. |
| 402 | insufficient_balance |
Your prepaid balance is too low for this request: sending this SMS, ordering this number, answering this chat message or starting this outbound call would take the balance below zero, so nothing was sent, ordered, answered or called. |
| 402 | voice_ai_not_enabled |
The call plan sends calls to the assistant, but voice AI is not available for this project. |
| 422 | company_details_missing |
A phone number is registered to a business or a person, and the project's details are incomplete. |
| 422 | business_required |
A personal account asked for a national number. |
| 422 | account_type_change_blocked |
PUT /api/v1/project/company with account_type: "personal" for a project that has a national number. |
| 422 | vat_number_invalid |
PUT /api/v1/project/company for a company in the EU outside the Netherlands, and VIES (the VAT number check of the European Commission) says the vat_number is not valid. |
| 422 | country_not_supported |
PUT /api/v1/project/company with an address.country where Hypamoon does not provide its services, because of sanctions that apply to us or to our telecom and payment providers: Russia (RU), Belarus (BY), North Korea (KP), Iran (IR), Syria (SY) and Cuba (CU). |
| 422 | spend_cap_missing |
The project has no spending cap. |
| 422 | regulatory_documents_missing |
A number with a local area code (type: "geographic") needs documents: proof of address, a copy of an ID and, for a business, an extract from the business register (a personal account needs no extract). |
| 403 | verification_required |
This needs a verification level the project does not have yet. |
| 409 | number_unavailable |
Someone else got this number between your search and your order. |
| 409 | number_already_yours |
This number is already in your project. |
| 403 | number_limit_reached |
During the beta a live project has at most three numbers (released numbers do not count). |
| 422 | no_numbers_available |
There are no free numbers for this area right now. |
| 502 | order_status_unknown |
The carrier did not answer the order in time, or answered with an error on its side. |
| 409 | number_release_not_supported |
DELETE /api/v1/numbers/{id} only releases test numbers, with a test key. |
| 503 | telephony_unavailable |
Searching or ordering numbers, sending SMS or making an outbound call is not available at the moment. |
| 400 | idempotency_key_missing |
POST /api/v1/numbers and POST /api/v1/calls need an Idempotency-Key header: 1 to 255 visible characters without spaces, for example a UUID. |
| 400 | idempotency_key_invalid |
The Idempotency-Key header is there but cannot be used: it must be 1 to 255 visible ASCII characters without spaces, for example a UUID. |
| 409 | idempotency_key_reused |
You used this Idempotency-Key before with a different body. |
| 409 | idempotency_request_in_progress |
The first request with this Idempotency-Key is still running. |
| 422 | assistant_not_configured |
The call plan sends calls to the assistant (ai_agent), you started a chat (POST /api/v1/conversations), or you asked the assistant to make a call (POST /api/v1/calls), but the project's assistant was never set up. |
| 422 | team_targets_not_allowed |
A forward node has a target with kind: "user": a team member of the Hypamoon apps. |
| 422 | forward_target_not_allowed |
A forward node points to a phone number we do not forward to. |
| 400 | invalid_webhook_endpoint |
The webhook URL or events are not usable. |
| 409 | webhook_limit_reached |
A project has at most ten webhook endpoints. |
| 409 | webhook_endpoint_disabled |
This endpoint was switched off after 50 failed deliveries in a row. |
| 422 | destination_not_allowed |
We do not send an SMS to this number. |
| 422 | message_too_long |
The text is more than six SMS segments. |
| 422 | sender_not_allowed |
The from of the message is not a sender we can use. |
| 429 | message_limit_reached |
The project sent its maximum number of messages for today (200 during the beta). |
| 422 | number_required |
The assistant calls from one of your project's numbers, so the person sees who is calling and can call back, and the project has no active number yet. |
| 422 | outside_calling_hours |
It is outside the calling hours of the person you want to call, so nobody was called. |
| 403 | consent_required |
You asked for a call with purpose set to marketing, and this project has no recorded consent from this person. |
| 429 | concurrent_call_limit |
Too many outbound calls are running at the same time. |
| 429 | call_limit_reached |
The project started its maximum number of outbound calls for today (100). |
| 409 | conversation_closed |
The conversation is closed and takes no more messages. |
| 409 | conversation_busy |
The assistant is still answering an earlier message in this conversation, or the conversation closed at that moment. |
| 409 | conversation_turn_limit_reached |
The conversation reached its maximum number of turns (max_turns, 30). |
| 429 | conversation_limit_reached |
The project started its maximum number of conversations for today: 1000 for a live project during the beta, 25 for a test project. |
| 402 | test_free_replies_used |
In test mode the assistant gives real replies. |
| 402 | test_free_calls_used |
Not an HTTP response: a run of an agent in a test project is logged as skipped with this reason (GET /agents/{id}/runs). |
| 401 | invalid_chat_token |
A /api/v1/public route of the chat widget got no public chat token, one that does not look like hm_pub_... |
| 401 or 409 | chat_token_revoked |
The public chat token was revoked. |
| 403 | origin_not_allowed |
The page that called a /api/v1/public route is not on the list of allowed origins of the public chat token, or the request had no Origin header. |
| 403 | turnstile_failed |
The check that the visitor is a person failed, expired or was missing when the widget started a conversation. |
| 401 | invalid_conversation_token |
A request about a conversation of the chat widget had no X-Conversation-Token, a wrong one, or one older than 6 hours. |
| 429 | public_chat_limit_reached |
The chat widget reached a daily limit: the number of new conversations per day of this public chat token (default 200, up to 1000, set per token), or the daily spending limit of the project's public chat (default 5 euro of replies per day, up to 1000, set in the portal; 0 turns the live widget off). |
| 503 | chat_unavailable |
The chat widget cannot chat right now, and the visitor is not told why. |
| 422 | site_limit_reached |
A project can have 3 sites, and this one has 3 already. |
| 402 or 409 | plan_limit_reached |
With 402 the project is on the Free plan, and this call would go above what Free includes: 3 sites per project, 10 MB of data, 100 MB of files, one team member, and phone numbers and payments in test mode only. |
| 413 | app_too_large |
The modules of the app are larger than the plan allows for one app. |
| 422 | app_blocked |
We check every app deploy before it goes live, and this one was not published. |
| 422 | migration_failed |
A migration from apply_app_migration (POST /api/v1/apps/{id}/migrations) reached the app's database but SQLite refused it, for example a syntax error, a table that already exists or a column that is missing. |
| 413 | file_too_large |
The file an app requested an upload link for is larger than one file may be on this plan (max_bytes). |
| 422 | query_failed |
The read-only query from query_app_db (POST /api/v1/apps/{id}/query) reached the app's database but SQLite refused it, for example a table or column that does not exist or a syntax error. |
| 409 | slug_taken |
Another site already has this slug, so https:// |
| 422 | slug_reserved |
This slug is reserved, like www, api, app, docs, test, demo or anything that starts with hypamoon. |
| 422 | site_too_large |
The site is larger than a site can be: at most 50 files, 1 MB per file and 5 MB for all files together (after base64 decoding). |
| 422 | site_blocked |
We check every deploy before it goes live, and this one was not published. |
| 403 | site_offline |
Hypamoon took this site offline because of abuse. |
| 429 | deploy_limit_reached |
This project deployed too often in the last hour: 120 deploys per hour, 30 in the first week of a project (until its first top-up or an approved verification). |
| 422 | upload_not_received |
deploy_site names a file by sha256 and bytes, an upload link was created for it with create_upload_urls (POST /sites/uploads), but the bytes never arrived: nothing was PUT to the upload_url (it is valid for 15 minutes). |
| 403 | phone_verification_required |
Publishing a public site (no password, not unlisted) or connecting your own domain needs a verified phone number on the account, or a payment method on the project. |
| 403 | mail_not_enabled |
Email is an extra module, and it is not turned on for this project. |
| 403 | email_paused |
Sending is paused for this project because too many recent emails bounced (more than 5% of the last 200) or someone marked one as spam (more than 0.1%). |
| 403 | recipient_not_allowed |
The address is not in this project: not in a form submission, a document, a chat conversation or a sign-in of one of your apps, and the owner did not confirm it. |
| 429 | email_limit_reached |
The project reached its daily email limit (limit in the error), or the limit on new recipients that only appear in documents your app wrote (reason: "new_recipients_limit", with used_today). |
| 422 | email_blocked |
The content check stopped this email: it looked like phishing or contained something email clients and spam filters treat as an attack (a form, a script, a link that hides where it goes, a link shortener, a known bad link). |
| 409 | email_domain_not_verified |
The from address is not on a verified sending domain of this project. |
| 413 | attachment_too_large |
The attachments of this email are over the limit: at most 10 attachments, and at most 10 MB together (limit_bytes). |
| 422 | attachment_not_allowed |
This attachment cannot be sent. |
| 422 | email_address_invalid |
Nothing was sent: before the first email to an address we check that it can receive email, and this one did not pass. |
| 409 | bimi_not_ready |
The logo in the inbox (BIMI) needs DMARC with p=quarantine or p=reject for all mail (no pct below 100), and this domain does not have that yet. |
| 403 | dedicated_ip_not_available |
A dedicated sending IP is available on the Business and Enterprise plans; this project is on another plan, so nothing was requested. |
| 422 | collection_limit_reached |
This project has reached the number of collections its plan allows: 20 on Free, 50 on Online, 100 on Reachable, 200 on Business. |
| 409 | collection_name_taken |
This project already has a collection with this name. |
| 422 | document_limit_reached |
The collection already has 10,000 documents, the maximum. |
| 422 | document_too_large |
A document can be at most 64 kB as JSON (UTF-8). |
| 422 | schema_mismatch |
The document does not match the JSON Schema of its collection. |
| 403 | collection_not_public |
A website tried to write to or read from a collection that does not allow it. |
| 500 | internal_error |
Something went wrong on our side. |
| 502 | upstream_error |
The carrier refused the request, or did not answer a search. |
| 503 | service_unavailable |
This part of the API is temporarily unavailable. |