Authentication
Every /api/v1 request must include an API key in the Authorization header.
Bearer header
Authorization: Bearer ts_REPLACE_MEA request without Authorization, with a malformed Bearer token, or with a key that has been revoked returns 401 unauthenticated. A request whose key belongs to a user below the Team tier returns 403 forbidden. See the errors page for the full envelope.
Example
curl -sS https://api.trademarksentinel.app/api/v1/watches \ -H "Authorization: Bearer ts_a1b2c3d4e5f60718293a4b5c6d7e8f90" \ -H "Content-Type: application/json"{ "data": [], "pagination": { "nextCursor": null, "limit": 50 }}Issuance and rotation
API keys are minted from the dashboard. The end-to-end flow is:
- Sign in to the dashboard as a Team or Enterprise user.
- Open Settings → API keys → New key.
- Pick a human-readable name, choose the scopes (see below), and click Create.
- The plaintext key is shown once. Copy it immediately — the server only retains a SHA-256 hash and cannot reveal the key again.
- Store the key in a secret manager (AWS Secrets Manager, Doppler, Vault, GitHub Actions encrypted secrets, …). Do not commit it to source control.
To rotate:
- Create a new key with the same scopes.
- Roll your client config to the new key.
- Revoke the old key with
DELETE /api/v1/api-keys/{id}(see API key management).
There is no two-key overlap window enforced by the server — both keys remain valid until the old one is revoked, so rotation is zero-downtime if you sequence deploy → revoke.
Scopes
ApiKey.scopes is a String[] (Prisma schema, plan §3) that narrows what a key may do. A key only authorizes endpoints whose required scope is in its scope list. A request with an insufficient-scope key returns 403 forbidden.
The MVP scopes are:
| Scope | Grants |
|---|---|
watches:read | GET /watches, GET /watches/{id} |
watches:write | POST /watches, PATCH /watches/{id}, DELETE /watches/{id} |
alerts:read | GET /alerts, GET /alerts/{id} |
apikeys:read | (reserved) Read your own API key metadata via the dashboard. Not required for GET /api/v1/me. |
Notes:
watches:writedoes not implywatches:read. Grant both if your client lists watches before mutating them.- Alert state changes (mark-read, dismiss) are not yet exposed over the public REST API — only the in-app dashboard mutates alert state in MVP.
alerts:readis read-only. - The
DELETE /api-keys/{id}revocation endpoint is authenticated by session cookie from the dashboard, not by an API key, so no scope is needed for revocation. (You cannot revoke a key with itself.) GET /api/v1/meis callable with any valid key — no scope required — so SDK builders can introspect “what plan and scopes am I on” without provisioning extra grants.- Additional scopes (e.g.
watches:adminfor org-wide management,alerts:writefor bulk dismiss) will be introduced under their own names; existing keys keep working.
Choosing scopes
Default to least privilege. A read-only dashboard reads watches and alerts → watches:read, alerts:read. A CI integration that creates a watch per branch and never reads back → watches:write only.