API reference
135 endpoints across 18 resources. Every entry below is generated from the route handlers themselves, including the permission each one enforces — so this page cannot drift from what the server actually does.
Base URL https://rialingo.cloud. Send Authorization: Bearer <token> and, when you are not using a tenant subdomain, X-Tenant: <slug>. Errors are RFC 7807 problem documents.
How the pieces fit
A tenant owns projects. A project owns keys, each carrying one translation per enabled language. Keys live on a branch; releases group them for shipping; an export turns the published result into an immutable bundle in object storage.
Authenticate
API tokens inherit the issuing user's permissions, intersected with the scopes declared at creation. Each endpoint below lists the permission it requires.
meGet notified
Subscribe a URL to events and RiaLingo posts an HMAC-signed body when content changes. The webhook tells you something moved, not what.
webhooksPull the change
The delta endpoint answers what moved since your last sync — changed values and removed keys — behind one opaque token. That pair is how OTA content updates work.
delta syncKeeping a client in sync
Ask once with no token to get a snapshot, then replay the token you were handed.
# First run — full snapshot, no cursor
GET /api/v1/projects/{projectId}/delta
# Every run after — only what moved
GET /api/v1/projects/{projectId}/delta?sync_token=<token from last response>The response carries changes (new values), removals (keys to drop, whether deleted or archived) and a fresh sync_token. Store the token, apply the rest locally, and read from your local copy — no call per lookup. When has_more is true, call again immediately with the new token.
- Treat the token as opaque. It encodes a position in two streams; parsing it will break when the shape changes.
- Apply removals. A key that was deleted or archived stops appearing in bundles; skip removals and your client serves a string nobody can edit any more.
- Drafts never appear. The delta carries published values only, so unreleased copy cannot reach users.
admin
1 read1 writeTenant-admin surfaces that are not part of the general REST contract.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/admin/metrics | Admin-only operational read-out. Exposes the size of audit-style tables | audit log:view |
| POST | /api/v1/admin/tenant/branding/assets | multipart/form-data: | user:create |
audit
2 reads0 writesAppend-only record of who changed what.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/audit | tenant audit trail, filterable and cursor-paginated. | audit log:view |
| GET | /api/v1/audit/export.zip | full tenant audit export as a single zip | audit log:view |
cli
2 reads0 writesEndpoints the `rialingo` Go CLI depends on, including its own release manifest.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/cli/download/{platform} | stream a CLI binary. | session |
| GET | /api/v1/cli/releases | list downloadable CLI binaries with sizes | session |
exports
1 read0 writesBundle builds. An export is an async job that produces an immutable artifact in object storage; poll the job, then fetch the signed URL.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/exports/{jobId} | poll a bundle build. Returns the job status and, | export bundle:view |
health
1 read0 writesLiveness and queue depth. Unauthenticated.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/health | Health check. | session |
imports
2 reads2 writesThe inbound half of exports — upload a bundle or file set and reconcile it against existing keys.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/imports | list recent jobs. | project:view |
| POST | /api/v1/imports | start a smart import. | project:view |
| GET | /api/v1/imports/{jobId} | poll an import job's status and per-key results. | project:view |
| POST | /api/v1/imports/zip-preview | Multipart upload of a Lokalise-shaped zip bundle. Parses and | session |
me
1 read1 writeThe calling identity — who am I, and what may I do.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/me | current caller identity + effective permissions. | session |
| POST | /api/v1/me/ws-token | Mint a short-lived JWT for the WebSocket gateway. Authenticated | session |
notifications
1 read2 writesIn-app notification feed.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/notifications | the caller's in-app inbox plus an unread count. | session |
| POST | /api/v1/notifications/{id}/read | mark one notification as read. | session |
| POST | /api/v1/notifications/read-all | mark the caller's whole inbox as read. | session |
ops
0 reads1 writePlatform-admin only, cross-tenant. Authenticated by a platform bearer token, not a tenant session.
| Method | Path | Description | Requires |
|---|---|---|---|
| POST | /api/v1/ops/tenants | platform-admin-only tenant provisioning. | platform: platform:tenant:provision |
permissions
1 read0 writesThe catalogue of permission strings the RBAC layer understands.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/permissions | the catalogue of permission strings the RBAC layer | session |
projects
35 reads65 writesA project is the unit of content: it owns keys, the languages those keys are translated into, and everything layered on top (releases, tasks, screenshots, glossary). Almost every other resource hangs off a project id.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/projects | list tenant's projects | project:view |
| POST | /api/v1/projects | create a new project (delegates to Server Action) | project:view |
| GET | /api/v1/projects/{projectId}/branches | branches in the project. | branch:view |
| POST | /api/v1/projects/{projectId}/branches | cut a new branch from the default. | branch:view |
| GET | /api/v1/projects/{projectId}/comments | Project-wide list of key comments. Cursor-paginated. | comment:view |
| GET | /api/v1/projects/{projectId}/custom-fields | list (cursor-paginated) | custom_field:view |
| POST | /api/v1/projects/{projectId}/custom-fields | create | custom_field:view |
| GET | /api/v1/projects/{projectId}/custom-fields/{id} | read one custom-field definition. | custom_field:view |
| PATCH | /api/v1/projects/{projectId}/custom-fields/{id} | update the definition. | custom_field:view |
| DELETE | /api/v1/projects/{projectId}/custom-fields/{id} | remove the definition. | custom_field:view |
| GET | /api/v1/projects/{projectId}/custom-statuses | list (cursor-paginated) | custom_status:view |
| POST | /api/v1/projects/{projectId}/custom-statuses | create | custom_status:view |
| GET | /api/v1/projects/{projectId}/custom-statuses/{id} | read one custom status. | custom_status:view |
| PATCH | /api/v1/projects/{projectId}/custom-statuses/{id} | update the status. | custom_status:view |
| DELETE | /api/v1/projects/{projectId}/custom-statuses/{id} | remove the status. | custom_status:view |
| GET | /api/v1/projects/{projectId}/delta | OTA delta sync since last sync. | ota bundle:view |
| GET | /api/v1/projects/{projectId}/export-schedules | list | export schedule:view |
| POST | /api/v1/projects/{projectId}/export-schedules | create | export schedule:view |
| GET | /api/v1/projects/{projectId}/export-schedules/{id} | read one scheduled export. | export schedule:view |
| PUT | /api/v1/projects/{projectId}/export-schedules/{id} | update its cron expression or bundle params. | export schedule:view |
| DELETE | /api/v1/projects/{projectId}/export-schedules/{id} | remove the schedule. | export schedule:view |
| GET | /api/v1/projects/{projectId}/exports | Cursor-paginated list of export jobs. Filterable by status. | export bundle:view |
| DELETE | /api/v1/projects/{projectId}/exports/{jobId} | Cancel a queued/running export job. | export bundle:create |
| POST | /api/v1/projects/{projectId}/exports/{jobId}/retry | Clone a failed export job's params into a new queued job. | export bundle:create |
| POST | /api/v1/projects/{projectId}/figma/frame-manifest | Accepts a Figma frame manifest (up to 500 text layers) and returns a | figma:link:write |
| POST | /api/v1/projects/{projectId}/figma/frame-screenshots | Accepts a multipart PNG upload + frame metadata JSON, runs the image | screenshot:create |
| GET | /api/v1/projects/{projectId}/figma/links | list node→key bindings for a file | figma:link:read |
| POST | /api/v1/projects/{projectId}/figma/links | upsert bindings (partial-batch, per-op savepoints) | figma:link:read |
| PATCH | /api/v1/projects/{projectId}/figma/links/{id} | update text_hash on a binding | figma:link:write |
| DELETE | /api/v1/projects/{projectId}/figma/links/{id} | remove a binding | figma:link:write |
| GET | /api/v1/projects/{projectId}/figma/render-pack | Returns published translations only, keyed by node_id, for a given | figma:link:read |
| POST | /api/v1/projects/{projectId}/figma/sync | Accepts a Figma frame manifest (up to 500 text layers) and returns the | figma:sync |
| POST | /api/v1/projects/{projectId}/files/download | Async export trigger; accepts the legacy-flag set so existing CI | session |
| POST | /api/v1/projects/{projectId}/files/upload | Single-JSON upload (Lokalise legacy-flag-compatible). The body is one | session |
| GET | /api/v1/projects/{projectId}/glossary | list (cursor-paginated, includes translations) | glossary term:view |
| POST | /api/v1/projects/{projectId}/glossary | create term (optional inline translations) | glossary term:view |
| GET | /api/v1/projects/{projectId}/glossary/{termId} | read one glossary term. | glossary term:view |
| PUT | /api/v1/projects/{projectId}/glossary/{termId} | update the term. | glossary term:view |
| DELETE | /api/v1/projects/{projectId}/glossary/{termId} | remove the term. | glossary term:view |
| PUT | /api/v1/projects/{projectId}/glossary/{termId}/translations/{lang} | set the term's approved wording in one language. | glossary term:update |
| DELETE | /api/v1/projects/{projectId}/glossary/{termId}/translations/{lang} | `lang` is the language code (e.g. `en_US`). The `corridor` qualifier | glossary term:update |
| GET | /api/v1/projects/{projectId}/glossary/export.csv | Stream the project's glossary as CSV, attaching one column per | glossary term:view |
| GET | /api/v1/projects/{projectId}/import-schedules | list | import schedule:view |
| POST | /api/v1/projects/{projectId}/import-schedules | create | import schedule:view |
| GET | /api/v1/projects/{projectId}/import-schedules/{id} | read one scheduled import. | import schedule:view |
| PUT | /api/v1/projects/{projectId}/import-schedules/{id} | update its cron expression or source. | import schedule:view |
| DELETE | /api/v1/projects/{projectId}/import-schedules/{id} | remove the schedule. | import schedule:view |
| GET | /api/v1/projects/{projectId}/imports | Cursor-paginated list of import jobs. Filterable by status. | project:view |
| DELETE | /api/v1/projects/{projectId}/imports/{jobId} | Cancel a queued/running import job. Phase 4 / M4 Batch 1.2. | project:update |
| POST | /api/v1/projects/{projectId}/imports/{jobId}/retry | Clone a failed import job's params into a new queued job. | project:update |
| POST | /api/v1/projects/{projectId}/imports/zip | Multipart upload of a Lokalise-shaped zip bundle. | session |
| GET | /api/v1/projects/{projectId}/keys | list keys (paginated, filterable) | key:view |
| POST | /api/v1/projects/{projectId}/keys | create a key on the default branch | key:view |
| PUT | /api/v1/projects/{projectId}/keys | bulk update (Phase 2 / M2) | key:view |
| DELETE | /api/v1/projects/{projectId}/keys | bulk hard-delete (Phase 2 / M2) | key:view |
| GET | /api/v1/projects/{projectId}/keys/{keyId} | single key read | key:view |
| PUT | /api/v1/projects/{projectId}/keys/{keyId} | single key update | key:view |
| DELETE | /api/v1/projects/{projectId}/keys/{keyId} | single key hard-delete | key:view |
| GET | /api/v1/projects/{projectId}/keys/{keyId}/comments | list key comments | comment:view |
| POST | /api/v1/projects/{projectId}/keys/{keyId}/comments | create one | comment:view |
| DELETE | /api/v1/projects/{projectId}/keys/{keyId}/comments/{commentId} | Hard-delete a key comment. FK cascade clears thread children. | comment:delete |
| GET | /api/v1/projects/{projectId}/keys/{keyId}/segments/{lang} | Path-style alias for the per-language translation row. | translation:view |
| PUT | /api/v1/projects/{projectId}/keys/{keyId}/segments/{lang} | Set the live value (Phase 2 / M2 Batch 5.3). Stub-creates the | translation:view |
| GET | /api/v1/projects/{projectId}/keys/{keyId}/translations | list translations for a key (one per enabled language). | translation:view |
| GET | /api/v1/projects/{projectId}/languages | list enabled languages | language:view |
| POST | /api/v1/projects/{projectId}/languages | enable a language | language:view |
| GET | /api/v1/projects/{projectId}/languages/{code} | read one enabled language. | language:view |
| PUT | /api/v1/projects/{projectId}/languages/{code} | enable the language or update its overrides. | language:view |
| DELETE | /api/v1/projects/{projectId}/languages/{code} | disable the language for this project. | language:view |
| GET | /api/v1/projects/{projectId}/releases | releases for the project. | release:view |
| POST | /api/v1/projects/{projectId}/releases | open a new release. | release:view |
| POST | /api/v1/projects/{projectId}/releases/{releaseId}/cancel | abandon the | session |
| POST | /api/v1/projects/{projectId}/releases/{releaseId}/check | run the | session |
| POST | /api/v1/projects/{projectId}/releases/{releaseId}/keys | add keys to the | release:update |
| POST | /api/v1/projects/{projectId}/releases/{releaseId}/ship | publish the | session |
| GET | /api/v1/projects/{projectId}/screenshots | list with signed URLs. | screenshot:view |
| POST | /api/v1/projects/{projectId}/screenshots | multipart upload. | screenshot:view |
| GET | /api/v1/projects/{projectId}/screenshots/{id} | read one screenshot and its key links. | screenshot:view |
| PUT | /api/v1/projects/{projectId}/screenshots/{id} | rename it or relink keys. | screenshot:view |
| DELETE | /api/v1/projects/{projectId}/screenshots/{id} | remove it. | screenshot:view |
| GET | /api/v1/projects/{projectId}/snapshots | list (cursor-paginated) | snapshot:view |
| POST | /api/v1/projects/{projectId}/snapshots | create (triggers export under hood) | snapshot:view |
| GET | /api/v1/projects/{projectId}/snapshots/{id} | read one point-in-time snapshot. | snapshot:view |
| DELETE | /api/v1/projects/{projectId}/snapshots/{id} | remove the snapshot. | snapshot:view |
| POST | /api/v1/projects/{projectId}/snapshots/{id}/restore | Replay a snapshot's bundle through the import pipeline. | snapshot:restore |
| GET | /api/v1/projects/{projectId}/tasks | list (cursor-paginated) | task:view |
| POST | /api/v1/projects/{projectId}/tasks | create | task:view |
| GET | /api/v1/projects/{projectId}/tasks/{taskId} | read one translation task. | task:view |
| PUT | /api/v1/projects/{projectId}/tasks/{taskId} | update assignee, due date or status. | task:view |
| DELETE | /api/v1/projects/{projectId}/tasks/{taskId} | remove the task. | task:view |
| POST | /api/v1/projects/{projectId}/tasks/{taskId}/keys | Add key ids to a task. Validates each key belongs to the project; | task:update |
| DELETE | /api/v1/projects/{projectId}/tasks/{taskId}/keys/{keyId} | Remove one key from a task. | task:update |
| GET | /api/v1/projects/{projectId}/translations | project-wide translation list. | translation:view |
| GET | /api/v1/projects/{projectId}/translations/{translationId} | Single-translation read (Phase 2 / M2). | translation:view |
| PUT | /api/v1/projects/{projectId}/translations/{translationId} | Set the live value (Phase 2 / M2). Equivalent to publish with override. | translation:view |
| PATCH | /api/v1/projects/{projectId}/translations/{translationId} | Save a draft (default), or publish via ?publish=true. | translation:view |
| PUT | /api/v1/projects/{projectId}/translations/{translationId}/custom-status | Set or clear the translation's per-project custom status overlay. | translation:update |
| DELETE | /api/v1/projects/{projectId}/translations/{translationId}/draft | discard the staged draft, leaving the live value untouched. | session |
| POST | /api/v1/projects/{projectId}/translations/{translationId}/publish | promote the staged draft to the live value. | session |
| POST | /api/v1/projects/{projectId}/translations/find-and-replace | Bulk literal/regex substitution on `translation.text`. | session |
role-assignments
0 reads1 writeBinds a role to a user, optionally scoped to one project.
| Method | Path | Description | Requires |
|---|---|---|---|
| POST | /api/v1/role-assignments | bind a role to a user, optionally scoped to | session |
roles
1 read1 writeNamed permission sets. A role holds `<resource>:<action>` strings; assignments bind them to users.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/roles | roles defined in the calling tenant. | role:view |
| POST | /api/v1/roles | create a custom role from a set of permission strings. | role:view |
search
1 read0 writesCross-resource lookup.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/search | cross-resource lookup over keys and translations. | session |
system
1 read0 writesPlatform-level metadata.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/system/languages | read-only system catalog. | session |
tenant
1 read1 writeSettings for the calling tenant.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/tenant | settings for the calling tenant. | tenant settings:view |
| PATCH | /api/v1/tenant | update SSO config or audit-retention policy. | tenant settings:view |
users
2 reads2 writesTenant members.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/users | members of the calling tenant. | user:view |
| GET | /api/v1/users/{userId} | fetch a single user in the tenant | user:view |
| PUT | /api/v1/users/{userId} | toggle disabled (body: { disabled: boolean }) | user:view |
| DELETE | /api/v1/users/{userId} | soft-delete by disabling the user | user:view |
webhooks
1 read4 writesOutbound notifications. Tells a listener that something changed; pair with the delta endpoint to find out what.
| Method | Path | Description | Requires |
|---|---|---|---|
| GET | /api/v1/webhooks | webhook subscriptions for the calling tenant. | webhook:view |
| POST | /api/v1/webhooks | subscribe a URL to a set of events. | webhook:view |
| PATCH | /api/v1/webhooks/{id} | update a subscription's URL or event set. | session |
| DELETE | /api/v1/webhooks/{id} | remove the subscription. | session |
| POST | /api/v1/webhooks/{id}/rotate-secret | issue a new HMAC signing secret. | session |