Rate Limits & Errors
How the API paginates, throttles, and reports failures. These rules apply to both the REST API and the MCP server.
Rate limits
Each API key may make up to 120 requests per minute. Every response carries the current budget:
| Header | Meaning |
|---|---|
| X-RateLimit-Limit | Requests allowed per window (120). |
| X-RateLimit-Remaining | Requests left in the current window. |
| X-RateLimit-Reset | Unix time (seconds) when the window resets. |
Exceeding the limit returns 429 with the standard error envelope:
{ "error": { "code": "rate_limited", "message": "Too many requests. Slow down." } }Limits are enforced per key at the edge. Back off when X-RateLimit-Remaining reaches 0 and retry after X-RateLimit-Reset.
Pagination
List endpoints return newest-first and accept a limit query parameter (default 50, max 100). Results come back under data.
curl "https://floatmessage.com/api/v1/form-submissions?limit=100" \
-H "Authorization: Bearer fm_live_YOUR_KEY"Write access & plan limits
Reads are open to any valid key. Creating resources follows the same rules as the dashboard: an expired trial returns 403 trial_expired, and exceeding a per-plan cap (domains, landing pages, knowledge items) returns 403 plan_limit.
Error envelope
Every error - REST or MCP - uses the same shape. The HTTP status conveys the category; the code is a stable machine-readable string.
{ "error": { "code": "not_found", "message": "Message not found." } }Error codes
| Status | Code | When |
|---|---|---|
| 400 | invalid_body | Request body is missing or not valid JSON, or a required field is absent. |
| 400 | invalid_domain | The domain in a create request is not a valid hostname. |
| 400 | reserved_domain | The hostname is reserved or a placeholder. |
| 400 | domain_not_found | The ?domain / X-Domain selector does not belong to your account. |
| 400 | unknown_template | An unknown landing-page templateId was supplied. |
| 400 | last_domain | You tried to delete your only remaining domain. |
| 400 | send_failed | A chat reply could not be sent (e.g. empty content). |
| 401 | unauthorized | Missing or invalid API key. |
| 403 | trial_expired | Your trial has ended; upgrade to create resources. |
| 403 | plan_limit | You hit a per-plan cap (domains, landing pages, knowledge items). |
| 404 | not_found | The requested resource does not exist or isn't yours. |
| 404 | no_domains | The account has no domains yet. |
| 409 | duplicate | The domain already exists on your account. |
| 429 | rate_limited | More than 120 requests in a minute on this key. |
| 500 | internal_error | An unexpected server error. Safe to retry. |
On the MCP server, tool-level failures (the 4xx codes above) are returned as a tool result with isError: true rather than a JSON-RPC protocol error, so an agent can read and react to them.