Skip to content

Authentication

View .md

Every endpoint requires authentication. Comvi has two methods, and not every endpoint accepts both.

Create a key in app.comvi.io under Settings > API Keys, pick its scopes, and copy it once. Keys start with comvi_. Pass the key as a Bearer token.

Authorization: Bearer comvi_your_api_key_here
Terminal window
curl -H "Authorization: Bearer $COMVI_API_KEY" https://api.comvi.io/v1/project

GET /v1/project returns the project the key is bound to, which confirms the key works and which project it reaches. See API Keys for the response. The CLI reads the same key from .comvirc.json or COMVI_API_KEY.

Scope Grants
project:read Read project metadata, locales, and namespaces
translations:read Read and export translation keys, values, glossaries, translation memory, comments, and history
translations:write Create and update translation keys, values, namespaces, locales, glossary entries, comments, and imports. Also deletes a namespace and clears translation values
translations:review Mark translations reviewed
translations:delete Delete translation keys
schema:read Read key schema and type-generation metadata

Every key gets project:read, whether or not you ask for it, so the CLI, the fetch loader and the in-context editor can call GET /v1/project. You cannot grant a scope you do not hold: the attempt returns 403 FORBIDDEN with the message Cannot grant API key permissions that you do not have. Grant only the scopes an integration needs.

A key is bound to one project and is refused on every organization-scoped route, in one of two ways.

Routes Refusal
Organizations, organization members, invitations (session-only) 401 AUTHENTICATION_REQUIRED. The key never reaches the permission check
Organization translation-memory routes and the read-only organization glossary routes (term list, single term, three exports) 403 FORBIDDEN, message API keys cannot access organization-scoped routes, before scopes are looked at
Remaining organization glossary routes (session-only) 401 AUTHENTICATION_REQUIRED

A key used against a project other than its own, or whose creator has since lost the underlying permission, gets 403 FORBIDDEN. A key never has more access than its creator has right now.

Sign in with POST /v1/auth/login, sending email and password as JSON. The response is the current user and a session cookie. Login is rate-limited to 10 requests per minute.

Terminal window
curl -X POST -H "Content-Type: application/json" \
-d '{"email": "you@example.com", "password": "your-password"}' \
-c cookies.txt https://api.comvi.io/v1/auth/login
curl -b cookies.txt "https://api.comvi.io/v1/projects?organizationId=1"

The cookie is sessionId, and __Host-sessionId in production. It is HttpOnly, SameSite=Strict, Path=/, with no Domain attribute, so only api.comvi.io reads it. There are no CSRF tokens; SameSite=Strict plus the host-bound cookie is the defence.

Rule Accepts Where
Session only The session cookie Organizations, members, invitations, API key management, creating and deleting projects, adding and removing locales
Either Session cookie or Bearer key Reading and updating a project, namespaces, translation keys and values, machine translation, glossaries, translation memory, comments, history, webhooks
API key only Bearer key GET /v1/project, GET /v1/project/locales, the /v1/keys/ routes, type-generation
API key only, enforced in the handler Bearer key The three CLI import/export routes under /v1/projects/{projectId}/(export|import/validate|import/commit). The middleware accepts either; the handler refuses a session

A Bearer token sent to a session-only endpoint does not fall back. The Authorization header is never read there, so the request fails with 401 AUTHENTICATION_REQUIRED.

Status and code When
401 AUTHENTICATION_REQUIRED Missing or invalid credentials, or a Bearer token on a session-only endpoint. Message: Authentication required. Provide either a valid session or API key. A session-only route answers the shorter Authentication required
401 API_KEY_INVALID, API_KEY_DISABLED, API_KEY_EXPIRED, API_KEY_PERMISSIONS_REVOKED A malformed, disabled or expired key, or one whose creator lost the granted permissions, only on API-key-only routes. Routes that accept either method collapse every key failure into AUTHENTICATION_REQUIRED
401 UNAUTHORIZED No Bearer header on an API-key-only route (message API key required), or a session on a CLI import/export route (message API key authentication required)
403 FORBIDDEN Valid credentials, not enough access. meta.requiredPermission names the underlying permission, not the scope; map it back through the scope table. meta.hint suggests a new key
{
"code": "FORBIDDEN",
"message": "API key does not have required permission: translation.edit",
"meta": { "requiredPermission": "translation.edit", "hint": "Please create a new API key with the required permissions" }
}