Errors, limits & paging
Errors
Failed requests return a non-2xx status and a JSON body in the same shape every time:
{
"error": {
"message": "API key is missing the 'deploy' scope",
"code": "insufficient_scope",
"status": 403
}
}| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The body or query is missing or invalid. The message says which field. |
| 401 | unauthorized | No key, an unknown key, or a revoked or expired key. |
| 402 | plan_limit | Your plan does not allow this, e.g. one app too many. Upgrade and retry. |
| 403 | forbidden / insufficient_scope | The key lacks the endpoint's scope, or a public key was used from a disallowed origin. |
| 404 | not_found | The resource does not exist or belongs to another account. |
| 409 | conflict | It clashes with the current state, e.g. a deployment is already running. |
| 429 | rate_limited | Too many requests. Wait for Retry-After seconds. |
| 500 / 502 / 503 | server_error | A problem on our side or at an upstream (registry, server). Safe to retry with backoff. |
Rate limits
Limits are per key, over a rolling minute:
- Secret keys: 120 requests per minute.
- Public keys: 30 requests per minute.
Every response tells you where you stand:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1790000000 # Unix time the window resetsWhen you hit the limit you get 429 with a Retry-After header. Back off and retry after that many seconds.
Paging
List endpoints take limit (1-100, default 50) and offset, and return has_more:
GET https://api.newhost.co.za/v1/invoices?limit=100&offset=100
{ "data": [ ... ], "has_more": true }Fetch every page (Node.js)
async function all(path) {
const out = [];
for (let offset = 0; ; offset += 100) {
const res = await fetch(`https://api.newhost.co.za/v1${path}?limit=100&offset=${offset}`, {
headers: { Authorization: `Bearer ${process.env.NEWHOST_SECRET_KEY}` },
});
const page = await res.json();
out.push(...page.data);
if (!page.has_more) return out;
}
}Formats
- Money is a string with two decimals in rand (ZAR), e.g.
"114.99". Invoice amounts include VAT; plan and domain prices exclude it. - Dates are ISO 8601 in UTC, e.g.
2026-09-24T10:15:00.000Z. - Send request bodies as JSON with
Content-Type: application/json.