- Base URL:
https://api.textsetu.com/api/v1(self-host:<server>/api/v1) - OpenAPI spec:
/api/v1/openapi.json— use it for SDK/CLI/MCP codegen - Envelope: success →
{ "success": true, "data": … }; error →{ "success": false, "error": { "code", "message" } }
Authentication
Send your token as a bearer credential on every request:
Tokens are created from the TextSetu web app (never from the API itself) and the
secret is shown once at creation — store it immediately. Tokens are hashed at
rest; a leaked token can be revoked at any time.
Security. Put tokens in environment variables / CI secrets — never commit
them. Grant the least-privilege set of permissions the automation needs.
Permissions
Authorization is permission-based — there are no coarse read/write/manage scopes. When you create a token you pick an allow-list of RBAC permission keys (the same catalog your org’s roles are built from, e.g.translation_read,
translation_create, glossary_update). Each endpoint declares the permission
it requires; you can see it as x-permission on every operation in this
reference, and the token-creation screen lets you start from a role preset
(Viewer / Editor / Admin) and fine-tune.
A token’s effective access is its underlying authority ∩ its allow-list: a
PAT can never exceed the permissions its owner already holds, and a project token
is bound to its one project. Selecting a permission you don’t hold is rejected at
creation.
Organization-level resources
Glossaries and translation memories belong to an organization and are shared across its projects, so the API splits them in two:
Which glossaries and TMs apply to a project is resolved from the project’s own
assignments, so the project-scoped calls need no extra configuration — this is
the path CI pipelines and AI agents should use.
Management endpoints reject a project token with
403, because a token bound to
a single project must not mutate an asset that every other project also consumes.
Use a PAT, which carries its owner’s role-based permissions.
Rate limits
Requests are limited per token (per IP when unauthenticated). On exceeding the limit you receive429 with error.code = "RATE_001". Default: 600 requests/min
(configurable per deployment via API_V1_RATE_LIMIT).
Errors
Pagination
List endpoints (e.g. keys) acceptpage (default 1) and limit (default 50,
max 200) and return { keys, total, page, limit }.
Branch targeting
Every read and write over keys, values, stats,POST /sources, and
GET /translations accepts an optional ?branch=<branchId> query param, which
targets an open translation branch instead of the project’s main branch. The
branch must belong to the project, be open, and the project must have branching
enabled — otherwise the request is a 400.
Branch targeting is required when the project protects its main branch: a
direct-to-main write on such a project is rejected with 403, and the caller is
expected to import into a branch and merge it for review. Branch writes are plain
additive deltas — no approval workflow, no plurals (a plural value collapses to
its other form), and no cleanup.
Quickstart
Read stats
Import source strings
Export approved translations
Building on top of the API
Because the OpenAPI spec describes the entire surface, downstream tools generate against it:- CLI —
push/pullmap to/sourcesand/translations. - GitHub Action — a project token (repo secret) +
push-sources/pull-translations. - MCP server — a remote MCP server lets Claude and other AI agents manage translations in natural language; its tools proxy to these endpoints.
- SDKs — typed clients generated from the spec.

