API Keys
An API key authenticates server-to-server calls. Each key is scoped to one project and carries a set of scopes.
Managing keys is session-only: the first five endpoints take a session cookie, and a Bearer key sent to them returns 401 AUTHENTICATION_REQUIRED. The last two take a Bearer key and nothing else.
Key object
Section titled “Key object”| Field | Type | Meaning |
|---|---|---|
id |
integer |
API key ID |
projectId |
integer |
Project the key belongs to |
name |
string |
Descriptive name |
description |
string | null |
Optional description |
keyPrefix |
string |
The first 12 characters of the key, such as comvi_a1b2c3. The full value is never returned after creation |
lastUsedAt |
string | null |
ISO 8601 time of last use, null if never used |
expiresAt |
string | null |
Expiration, null for non-expiring keys |
isActive |
boolean |
Whether the key is active |
permissions |
string[] |
Scopes granted |
createdAt, updatedAt |
string |
ISO 8601 timestamps |
{ "id": 1, "projectId": 5, "name": "CI/CD Pipeline", "description": "Used by GitHub Actions for pulling translations", "keyPrefix": "comvi_a1b2c3", "lastUsedAt": "2025-03-20T14:00:00Z", "expiresAt": null, "isActive": true, "permissions": ["project:read", "translations:read", "schema:read"], "createdAt": "2025-01-15T10:00:00Z", "updatedAt": "2025-01-15T10:00:00Z"}GET /v1/projects/{projectId}/api-keys
Section titled “GET /v1/projects/{projectId}/api-keys”List a project’s keys.
Session cookie, with api_key.view on the project.
| Parameter | In | Type | Required | Meaning |
|---|---|---|---|---|
projectId |
path | integer |
Yes | Project ID |
curl -b cookies.txt https://api.comvi.io/v1/projects/5/api-keysReturns an array of key objects.
GET /v1/api-keys/{id}
Section titled “GET /v1/api-keys/{id}”Read one key. The caller must have access to the key’s project.
Session cookie.
| Parameter | In | Type | Required | Meaning |
|---|---|---|---|---|
id |
path | integer |
Yes | API key ID |
curl -b cookies.txt https://api.comvi.io/v1/api-keys/1Returns one key object.
POST /v1/projects/{projectId}/api-keys
Section titled “POST /v1/projects/{projectId}/api-keys”Create a key. The full value comes back once, as token; store it before closing the connection.
Session cookie, with api_key.create on the project.
| Parameter | In | Type | Required | Meaning |
|---|---|---|---|---|
projectId |
path | integer |
Yes | Project ID |
name |
body | string |
Yes | 1 to 255 characters |
description |
body | string |
No | Up to 2000 characters |
expiresAt |
body | string |
No | ISO 8601 expiration |
permissions |
body | string[] |
Yes | Scopes to grant, at least one. Omitting it returns 422 |
| 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 |
project:read is added to every key whether or not you request it, so the CLI and SDK loaders can call GET /v1/project. Granting a scope you do not hold returns 403 FORBIDDEN.
curl -X POST -b cookies.txt -H "Content-Type: application/json" \ -d '{"name": "CI/CD Pipeline", "permissions": ["translations:read", "schema:read"]}' \ https://api.comvi.io/v1/projects/5/api-keysReturns 201 Created with the key object plus token.
{ "id": 2, "projectId": 5, "name": "CI/CD Pipeline", "keyPrefix": "comvi_9f2c1a", "isActive": true, "permissions": ["project:read", "translations:read", "schema:read"], "token": "comvi_9f2c1a7b4e6d80351c2b3a4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f"}PUT /v1/api-keys/{id}
Section titled “PUT /v1/api-keys/{id}”Update a key’s name, description, active status, expiration or scopes.
Session cookie.
| Parameter | In | Type | Required | Meaning |
|---|---|---|---|---|
id |
path | integer |
Yes | API key ID |
name |
body | string |
No | 1 to 255 characters |
description |
body | string | null |
No | Up to 2000 characters |
isActive |
body | boolean |
No | Enable or disable the key |
expiresAt |
body | string | null |
No | Set or remove expiration |
permissions |
body | string[] |
No | Replacement scopes. If present, at least one |
curl -X PUT -b cookies.txt -H "Content-Type: application/json" \ -d '{"name": "Production Sync Key", "permissions": ["translations:read", "translations:write", "schema:read"]}' \ https://api.comvi.io/v1/api-keys/1Returns the updated key object.
DELETE /v1/api-keys/{id}
Section titled “DELETE /v1/api-keys/{id}”Revoke a key. Requests using it fail immediately.
Session cookie.
| Parameter | In | Type | Required | Meaning |
|---|---|---|---|---|
id |
path | integer |
Yes | API key ID |
curl -X DELETE -b cookies.txt https://api.comvi.io/v1/api-keys/2Returns 204 No Content.
GET /v1/project
Section titled “GET /v1/project”Read the project the key is bound to. Make this call first with a new key: it confirms the key works and which project it reaches.
Bearer key only, with project:read, which every key has. No parameters.
curl -H "Authorization: Bearer $COMVI_API_KEY" https://api.comvi.io/v1/project{ "id": 5, "organizationId": 1, "name": "my-web-app", "description": "Main web application translations", "sourceLocale": "en" }| Field | Type | Meaning |
|---|---|---|
id |
integer |
Project ID |
organizationId |
integer |
Organization the project belongs to |
name |
string |
Project name |
description |
string | null |
Project description |
sourceLocale |
string |
Source locale code |
GET /v1/project/locales
Section titled “GET /v1/project/locales”Read the source locale and every locale attached to the key’s project. A creator with language restrictions sees only the locales they can access.
Bearer key only, with project:read. No parameters.
curl -H "Authorization: Bearer $COMVI_API_KEY" https://api.comvi.io/v1/project/locales{ "sourceLocale": "en", "locales": [ { "id": 1, "code": "en", "name": "English", "nativeName": "English", "isCustom": false, "flagEmoji": "🇺🇸" }, { "id": 2, "code": "uk", "name": "Ukrainian", "nativeName": "Українська", "isCustom": false, "flagEmoji": "🇺🇦" } ]}Errors
Section titled “Errors”| Status and code | When |
|---|---|
400 UNIQUE_CONSTRAINT |
A key with this name already exists in the project |
400 INVALID_INPUT |
Unrecognised scopes, or a malformed payload |
401 AUTHENTICATION_REQUIRED |
No session cookie, or a Bearer key sent to a management endpoint |
401 API_KEY_INVALID |
The Bearer key is malformed or does not exist |
401 API_KEY_DISABLED |
The key has been deactivated |
401 API_KEY_EXPIRED |
The key has passed its expiration date |
401 API_KEY_PERMISSIONS_REVOKED |
The key’s creator no longer holds the permissions it was granted |
403 FORBIDDEN |
No access to the key or project, or granting scopes you do not have |
403 READ_ONLY_MODE |
The organization is read-only. Applies to key creation |
404 API_KEY_NOT_FOUND |
The key does not exist |
404 PROJECT_NOT_FOUND |
The key’s project no longer exists |
422 FIELD_REQUIRED |
permissions or name is missing |
Next steps
Section titled “Next steps”- Authentication for scopes, sessions and which endpoints accept which
- API keys in the platform to manage keys from the dashboard
- CLI to use a key with the Comvi CLI