---
title: "Centrifugo Token"
method: POST
path: "/v1/auth/centrifugo-token"
tags: ["auth"]
---

# Centrifugo Token

`POST /v1/auth/centrifugo-token`

## Request

- Base URL: `https://api.sonenta.dev`
- URL: `https://api.sonenta.dev/v1/auth/centrifugo-token`
- Auth: none declared

Mint a Centrifugo connection JWT scoped to ONE project channel.

`kind` selects which per-project channel (`translations` default, used
by `@sonenta/react-i18next` with `liveUpdates: true`; or `missing`,
used by the client-admin missing-key dashboard). Auth: Bearer JWT
(user) OR Bearer ApiKey, associated with the requested project
(membership for users, scope/project_uuid for keys).

Tenant isolation (task 583): the client supplies only `project_uuid`
and `kind`. The route 403s unless the principal is authorized on that
project, then derives `org_uuid` + the exact channel from the
SERVER-SIDE project doc and binds it via the JWT `channels` claim.
A client can never obtain a token for an org/project it is not a
member of, nor for an arbitrary channel.

## Request body

- CentrifugoTokenIn
  - `project_uuid` string, required
  - `kind` 'translations' | 'missing' | 'feedback' | 'translation_jobs' | 'agent'
  - `version_uuid` string, nullable

## Response `200`

Successful Response

- CentrifugoTokenOut
  - `token` string, required
  - `channel` string, required
  - `expires_at` integer, required
  - `ttl_seconds` integer, required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/sonenta/apis/sonenta-api.md) · [All operations](https://skmtc.dev/sonenta/apis/sonenta-api/llms.txt) · [OpenAPI document](https://skmtc.dev/sonenta/apis/sonenta-api/revisions/f853ea49fb05?raw)
