API reference
The OpenAPI spec is served in production
Section titled “The OpenAPI spec is served in production”https://api.sonenta.dev/openapi.jsonMeasured on 2026-09-10: OpenAPI 3.1.0, 439 paths. Point Stoplight, Swagger UI, Insomnia, Postman or any OpenAPI-compatible tool at that URL.
The shape
Section titled “The shape”REST over HTTPS. JSON in, JSON out. Versioned at the path: /v1/....
Two authentication schemes exist, and the one you send declares what kind of principal you are:
Authorization: ApiKey <prefix>.<secret>for a programmatic caller;Authorization: Bearer <token>for a signed-in session.
Each route decides which kinds it accepts, so nothing can be inferred from the URL: most project routes take either, /v1/mcp/* takes API keys only, and account and staff routes take sessions only. Anything else returns 401.
An API key's scopes are mapped to a project role before the permission check: project:read becomes viewer, project:write or cdn:write becomes developer.
API keys come from Org Settings → API Keys in the dashboard.
curl https://api.sonenta.dev/v1/projects \ -H "Authorization: ApiKey snt_live_<prefix>.<secret>"Rate limits
Section titled “Rate limits”Rate limiting covers four surfaces: feedback, bundle, missing and MCP.
The first three share one header family, prefixed per surface: X-Feedback-RateLimit-Limit, -Remaining, -Reset, plus X-Feedback-Quota-Remaining when a monthly ceiling applies.
MCP has its own implementation and its own headers, X-MCP-RateLimit-* and X-MCP-Quota-Remaining, with the error code mcp_rate_limited.
In-context pairing has its own anti-bruteforce lockout: POST /v1/in-context/pair returns a 429 pairing_locked_out with Retry-After, counted per IP address.
There is no generic X-RateLimit-* header, and outside those surfaces no other /v1/ endpoint exposes a documented counter.
Two things you must not infer:
- Not every feedback write goes through the meter. Do not carry one route's behaviour over to another: read the headers on the response you actually get.
- A missing
X-Feedback-Quota-Remainingdoes not mean "no quota". The header is simply omitted when the plan carries no monthly ceiling.
Over the cap, the response is a 429 in application/problem+json carrying a code and a Retry-After in seconds.
Rate limits count per organisation, not per API key: issuing a second key does not raise your budget, it shares it.
Errors
Section titled “Errors”Errors follow RFC 7807 (application/problem+json): an object with type, title, status, code and detail, plus error-specific fields. The code is stable and meant for machine handling; the detail is meant for a human and may change.
CDN fallback
Section titled “CDN fallback”Published bundles are served from the CDN. If the CDN is unreachable, the API serves the same bundles as a fallback, under /cdn/v1/.... Your apps need do nothing: the SDKs switch over on their own.
The two paths carry distinct cache policies. No propagation delay is published here, because none has been timed end to end.
Resources
Section titled “Resources”| Resource | What it represents |
|---|---|
| Projects | Workspaces. Create, list, archive, transfer ownership. |
| Locales | The project-scoped locale set. Add, mark as default, enable or disable for clients. |
| Namespaces | Logical key buckets per project, for example checkout or common. |
| Keys | Translation keys with description, screenshots, max length, plural rules. |
| Translations | A key's value per locale, with its statuses and revision history. |
| Missing keys | The runtime SDK queue. List, group by frequency, mark triaged. |
Do you actually need the API?
Section titled “Do you actually need the API?”Almost everything you would call the API for is already exposed elsewhere, and often more conveniently:
@sonenta/cli: push, pull, import, export, releases. Covers most automation needs.- MCP: read keys, propose translations, publish, from any agent.
- SDK: read translations and capture missing keys at runtime.