Errors & Status Codes
All errors return JSON with a consistent shape — a code string and a human-readable message:
Error Response Shape
{
"code": "unauthorized",
"message": "Invalid or missing token"
} The code field is always a stable, machine-readable string you can match on. The message is informational and may change between versions.
Error Codes
bad_requestunauthorizedforbiddenkv:write) or org membershipnot_foundconflictif_not_exists conflict — key already setrate_limitedRetry-After header secondsinternal_errorCommon Error Scenarios
409 Conflict — KV conditional write
Returned when you set a key with if_not_exists: true and the key already exists:
{
"code": "conflict",
"message": "Key already exists"
} 429 Rate Limited
Returned when you exceed your plan's request rate. Check the Retry-After and X-RateLimit-Reset headers:
{
"code": "rate_limited",
"message": "Rate limit exceeded. Retry after 2 seconds"
} Retry-After: 2
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1741218060 403 Forbidden — Missing scope
Returned when the token is valid but lacks the scope required by the endpoint:
{
"code": "forbidden",
"message": "Token missing required scope: kv:write"
} GET /core/tokens/me/scopes to inspect what scopes your current token has. This is useful when debugging 403 errors.
Rate Limits
Rate limits are per-project and per-plan. They're enforced at the edge and returned in response headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1741218060 Channel subscriptions (SSE/WebSocket connections) do not count against the request rate limit.
OpenAPI Specification
The complete API specification is available as OpenAPI 3.1 JSON. For route-level examples of every public meta endpoint, see Meta & Health.
Download OpenAPI spec (JSON) · Open full-screen Scalar →
curl https://api.saasignal.saastemly.com/api/openapi.json Interactive Playground
Try API endpoints directly in the browser. Add your API key, edit the request, and hit Send.
For a route-by-route browser console inside the product, open the dashboard API Console. For a complete grouped inventory of every route, see the Route Catalog.
AI-First Documentation
SaaSignal serves machine-readable and human-readable documentation directly from the API, powered by SWAgent. These endpoints are ideal for LLM agents, AI coding assistants, and developer tools. For browser-test steps and SDK snippets, see Meta & Health.
skills/saasignal — Canonical Agent Skill
A protocol-aware playbook for agents. Use this first when an assistant needs to decide whether to use MCP, REST, the TypeScript SDK, or the CLI, and when it needs a truthful summary of current MCP coverage.
curl https://api.saasignal.saastemly.com/skills/saasignal llms.txt — For AI Agents
A token-optimized compact representation of the entire API, ~60–75% smaller than the raw OpenAPI JSON. Designed to fit within LLM context windows efficiently.
curl https://api.saasignal.saastemly.com/llms.txt Send a HEAD request to check estimated token cost before downloading:
curl -I https://api.saasignal.saastemly.com/llms.txt
# X-Markdown-Tokens: 4200 (estimated token count) to-humans.md — Full Markdown Reference
Comprehensive markdown documentation with table of contents, authentication guide, parameter tables, and response schemas. Useful for rendering in wikis, GitHub READMEs, or developer portals.
curl https://api.saasignal.saastemly.com/to-humans.md Root Landing Page
The API root (/) serves as the discovery endpoint. Browsers receive an HTML landing page; agents that send Accept: text/markdown receive full markdown documentation instead.
# HTML for browsers:
curl https://api.saasignal.saastemly.com
# Markdown for agents:
curl -H "Accept: text/markdown" https://api.saasignal.saastemly.com Endpoint Summary
/text/html or text/markdown/skills/saasignaltext/markdown/llms.txttext/plain/to-humans.mdtext/markdown/api/openapi.jsonapplication/json/robots.txttext/plain/sitemap.xmlapplication/xmlAll endpoints support ETag caching and return 304 Not Modified when content hasn't changed.
Health Checks
Kubernetes-style liveness and readiness probes for monitoring and orchestration. The dedicated Meta & Health page also includes route-by-route SDK and dashboard testing guidance.
GET /livez{"status":"ok"}GET /readyz{"status":"ready","version":"...","checks":{"database":"ok"}}GET /healthz{"status":"healthy","version":"...","uptime":"PT120S","checks":{"database":"ok"}}/livez is a lightweight check that returns 200 without hitting any dependencies. /readyz verifies database connectivity and returns 503 with "status":"degraded" if any dependency is unreachable. /healthz combines both — it returns liveness status together with dependency checks and worker uptime, responding 503 with "status":"unhealthy" when degraded.
curl https://api.saasignal.saastemly.com/readyz
# {"status":"ready","version":"0.6.3","checks":{"database":"ok"}}