Search docs ⌘K
esc
Type to search across all documentation pages

Errors & Status Codes

All errors return JSON with a consistent shape — a code string and a human-readable message:

Error Response Shape

json — error response
{
  "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

HTTP status
code
When it happens
400
bad_request
Invalid request body, missing required fields, or malformed JSON
401
unauthorized
Missing or invalid API key / session token
403
forbidden
Token lacks the required scope (e.g. kv:write) or org membership
404
not_found
Resource doesn't exist or was deleted
409
conflict
KV if_not_exists conflict — key already set
429
rate_limited
Request rate exceeded plan limit. Retry after Retry-After header seconds
500
internal_error
Unexpected server error — safe to retry with backoff

Common Error Scenarios

409 Conflict — KV conditional write

Returned when you set a key with if_not_exists: true and the key already exists:

json — 409 Conflict
{
  "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:

json — 429 Too Many Requests
{
  "code": "rate_limited",
  "message": "Rate limit exceeded. Retry after 2 seconds"
}
http response headers
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:

json — 403 Forbidden
{
  "code": "forbidden",
  "message": "Token missing required scope: kv:write"
}
Tip: Use 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:

http response headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1741218060
Plan
Requests/s
Burst
Free
10 req/s
50
Pro
100 req/s
500
Scale
1,000 req/s
5,000
Enterprise
custom
custom

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
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.

Scalar API Reference Open in new tab

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
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
curl https://api.saasignal.saastemly.com/llms.txt

Send a HEAD request to check estimated token cost before downloading:

curl
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
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.

curl
# HTML for browsers:
curl https://api.saasignal.saastemly.com

# Markdown for agents:
curl -H "Accept: text/markdown" https://api.saasignal.saastemly.com

Endpoint Summary

Endpoint
Content-Type
Purpose
/
text/html or text/markdown
Landing page with content negotiation
/skills/saasignal
text/markdown
Canonical agent skill for protocol and scope-aware discovery
/llms.txt
text/plain
Token-optimized compact notation for LLMs
/to-humans.md
text/markdown
Full markdown reference documentation
/api/openapi.json
application/json
Raw OpenAPI 3.1 specification
/robots.txt
text/plain
Crawler directives with Sitemap reference
/sitemap.xml
application/xml
XML sitemap of all public endpoints

All 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.

Endpoint
Purpose
Response
GET /livez
Liveness probe — is the worker process alive?
{"status":"ok"}
GET /readyz
Readiness probe — can it serve traffic? Pings D1.
{"status":"ready","version":"...","checks":{"database":"ok"}}
GET /healthz
Combined check — liveness + dependency status in one call.
{"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
curl https://api.saasignal.saastemly.com/readyz
# {"status":"ready","version":"0.6.3","checks":{"database":"ok"}}