Errors & Rate Limits
How failures are shaped, the HTTP status codes you'll see, and exactly how requests are throttled.
Error response shape
Errors the app builds itself use the same envelope as everything else, with success: false:
{ "success": false, "message": "Human-readable description of what went wrong." }A validation failure (HTTP 422) comes from Laravel’s own validator and has a slightly different, framework-standard shape — field names map to an array of messages:
{
"message": "The name field is required. (and 1 more error)",
"errors": {
"name": ["The name field is required."],
"wireguard_config": ["The wireguard config field is required when wireguard enabled is true."]
}
}Some hand-built 422s use the app’s own
{success, message} shape instead of the framework’s {message, errors} shape — check for errors before assuming it’s present, and always read message, which is populated either way.HTTP status codes
| 200 | OK | Success. |
| 201 | Created | A resource was created (monitor, project, integration, etc). |
| 401 | Unauthorized | Missing, invalid, or expired bearer token. |
| 403 | Forbidden | Token doesn't have the required ability, plan doesn't allow this action, or the account is suspended. |
| 404 | Not Found | The resource doesn't exist, or exists but isn't owned by your account — these are deliberately indistinguishable, so a token can never probe for the existence of another account's data. |
| 422 | Unprocessable Entity | Validation failed, or a plan/business-rule limit was hit (monitor limit, integration limit, etc). |
| 429 | Too Many Requests | Rate limit exceeded — see below. |
| 502 | Bad Gateway | Used specifically by Server Sources Sync Now when the upstream fetch itself fails. |
Rate limits
Limits are enforced per named bucket, returned via standard X-RateLimit-Limit / X-RateLimit-Remaining headers, and a Retry-After header on a 429.
| Public endpoints | 60 / min | Plans, probe list, status pages — keyed by IP. |
| Authenticated API | 120 / min | Everything under Bearer auth — keyed by user id, so one noisy account can't degrade others. |
| Probe/VPS agent endpoints | 60 / min | Heartbeat and job-polling — keyed by probe/VPS id, not exposed to normal API consumers. |