Every request — REST or MCP — is limited to 300 requests per minute, keyed to your personal access token rather than your IP address. The limit is shared across your whole token: REST calls and MCP tool calls draw from the same 300-per-minute budget, not separate ones.
Exceeding the limit returns 429 Too Many Requests in the same RFC 7807 shape every other error uses — see Rate limited below.
POST /api/v1/monitors/{id}/check and the MCP trigger_check tool share a second, separate limit: one manual trigger per monitor per 60 seconds. This is keyed to the monitor, not your token — if you trigger a check from the dashboard, the REST API, and MCP in quick succession, only the first one goes through, regardless of which surface it came from.
A rejected trigger returns 429 with a Retry-After header set to the number of seconds until the lock clears.
Every error response — from either surface — uses the same RFC 7807 Problem Details shape:
{
"type": "https://api.stector.app/errors/<code>",
"title": "<short title>",
"status": <http status code>,
"detail": "<what went wrong>",
"instance": "<the request path>"
}The type URL's final path segment is a stable, machine-readable code you can switch on — it never changes even if the title or detail wording does.
400 — the request body failed schema validation: a required field is missing, a value is out of range, or a field has the wrong type. detail carries the first failing field's message.
{
"type": "https://api.stector.app/errors/validation",
"title": "Validation Error",
"status": 400,
"detail": "Name is required",
"instance": "/api/v1/monitors"
}401 — the Authorization header is missing, the token doesn't match the expected format, or the token doesn't match any active PAT (including a revoked one). All four cases return this identical response — Stector never reveals which check failed.
{
"type": "https://api.stector.app/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "Invalid or missing credentials",
"instance": "/api/v1/teams/current"
}403 — your token authenticated fine, but your team role doesn't have permission for this action. See each endpoint's Roles line on the Endpoints page for which roles can call it.
{
"type": "https://api.stector.app/errors/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "You do not have permission to perform this action.",
"instance": "/api/v1/monitors/00000000-0000-0000-0000-000000000000"
}404 — the resource doesn't exist, or it belongs to a different team than the one your token authenticates. Both cases return the same response, so a valid token can't be used to probe whether another team's resource exists.
{
"type": "https://api.stector.app/errors/not-found",
"title": "Not Found",
"status": 404,
"detail": "The requested resource does not exist.",
"instance": "/api/v1/monitors/00000000-0000-0000-0000-000000000000"
}429 — you've exceeded the 300-per-minute limit, or hit the 60-second check-trigger lock on a specific monitor. Both cases use this same error code; the detail text tells you which one applies, and the check-trigger case adds a Retry-After header.
{
"type": "https://api.stector.app/errors/rate-limited",
"title": "Rate limit exceeded",
"status": 429,
"detail": "Rate limit of 300 requests per 1 minute exceeded. Retry after 1 minute.",
"instance": "/api/v1/monitors"
}500 — something went wrong on Stector's end. detail is always the same generic message — the real cause is logged server-side, never included in the response, so it can't leak internal details.
{
"type": "https://api.stector.app/errors/internal",
"title": "Internal Server Error",
"status": 500,
"detail": "An unexpected error occurred.",
"instance": "/api/v1/teams/current"
}