API
REST over the shared oRPC contract. Scalar and OpenAPI live on the api service.
The HTTP API is the api app, not this docs site. It hosts an oRPC
OpenAPI handler at /api.
| Path | What |
|---|---|
/api | RPC / REST operations |
/api/docs | Scalar reference |
/api/openapi.json | OpenAPI 3.2 document generated from the contract |
Locally that is https://api.localhost/api/docs. Production uses the same
paths on the shared host (/api is rewritten to the api service).
Auth
User procedures expect Authorization: Bearer with a Supabase user access
token (JWKS / ES256). Cron and internal routes use a named secret key plus
CRON_SECRET for Vercel Cron. There is no anon / service_role key on
the server.
What you can call
The contract covers me, organizations, signals (list, get, reprocess, ignore),
projects, companies (including enrich), opportunities (create, sync),
sources (list, create, update, run), integrations, and settings (industry
profile, scoring, AI). Each procedure has OpenAPI metadata and Valibot
examples.
Workflow-starting mutations (ingest, reprocess, sync) run only on apps/api.
The app calls those procedures through the oRPC client; it does not start
workflows itself.
Errors
Every error response is RFC 9457 Problem Details with content type
application/problem+json:
{
"type": "https://signaldock.dev/docs/api/errors#not-found",
"title": "Not Found",
"status": 404,
"detail": "No such route.",
"code": "NOT_FOUND"
}code is the stable machine-readable value; branch on it rather than on
title or detail. Some errors add a typed data object, described per
operation in the OpenAPI document.
Reference
Every operation has a page under API → Reference, generated from the
committed apps/api/openapi.json, with parameters, request and response
schemas, and code samples. Regenerate the spec with
pnpm --filter @signaldock/api openapi:generate; CI fails when it drifts from
the contract.
Related
- Product help for MCP tools: MCP
- Interactive requests: Scalar at
/api/docs
Last updated on