Skip to content

API Keys

API keys provide server-to-server authentication for the Comvi API. Each key is scoped to a specific project and can be restricted to a set of API scopes.


Returns all API keys for a project. The actual key value is never returned after creation — only the key prefix is shown for identification.

GET /api/v1/projects/:projectId/api-keys

Path parameters

ParameterTypeRequiredDescription
projectIdintegerYesProject ID

Example request

Terminal window
curl -X GET \
-H "X-API-Key: tlk_your_api_key" \
https://api.comvi.io/api/v1/projects/5/api-keys

Example response

[
{
"id": 1,
"projectId": 5,
"name": "CI/CD Pipeline",
"description": "Used by GitHub Actions for pulling translations",
"keyPrefix": "tlk_a1b2",
"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"
}
]

Response fields

FieldTypeDescription
idintegerAPI key ID
projectIdintegerProject this key belongs to
namestringDescriptive name for the key
descriptionstring | nullOptional description
keyPrefixstringFirst characters of the key for identification (e.g., tlk_a1b2)
lastUsedAtstring | nullISO 8601 timestamp of last usage, or null if never used
expiresAtstring | nullExpiration date, or null for non-expiring keys
isActivebooleanWhether the key is currently active
permissionsstring[]List of API scopes granted to this key
createdAtstringISO 8601 creation timestamp
updatedAtstringISO 8601 last update timestamp

Create a new API key for a project. The full key value is returned only in the creation response — store it securely.

POST /api/v1/projects/:projectId/api-keys

Path parameters

ParameterTypeRequiredDescription
projectIdintegerYesProject ID

Request body

FieldTypeRequiredDescription
namestringYesDescriptive name (1-255 characters)
descriptionstringNoOptional description (up to 2000 characters)
expiresAtstringNoISO 8601 expiration date
permissionsstring[]NoAPI scopes to grant. If omitted, Comvi derives the scopes the creating user can grant for this project.

Available API scopes

ScopeDescription
project:readRead project metadata, locales, and namespaces
translations:readRead and export translation keys and values
translations:writeCreate and update translation keys, values, namespaces, and imports
schema:readRead key schema/type-generation metadata

Example request

Terminal window
curl -X POST \
-H "X-API-Key: tlk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "CI/CD Pipeline",
"description": "Used by GitHub Actions",
"permissions": ["project:read", "translations:read", "schema:read"]
}' \
https://api.comvi.io/api/v1/projects/5/api-keys

Example response

{
"id": 2,
"projectId": 5,
"name": "CI/CD Pipeline",
"description": "Used by GitHub Actions",
"keyPrefix": "tlk_x9y8",
"lastUsedAt": null,
"expiresAt": null,
"isActive": true,
"permissions": ["project:read", "translations:read", "schema:read"],
"createdAt": "2025-03-25T10:00:00Z",
"updatedAt": "2025-03-25T10:00:00Z",
"token": "tlk_x9y8z7w6v5u4t3s2r1q0p9o8n7m6l5k4"
}

Permanently delete an API key. Any requests using this key will immediately start returning 401 Unauthorized.

DELETE /api/v1/api-keys/:id

Path parameters

ParameterTypeRequiredDescription
idintegerYesAPI key ID

Example request

Terminal window
curl -X DELETE \
-H "X-API-Key: tlk_your_api_key" \
https://api.comvi.io/api/v1/api-keys/2

Response

Returns 204 No Content on success.


Update an API key’s name, description, active status, expiration, or scopes.

PUT /api/v1/api-keys/:id

Path parameters

ParameterTypeRequiredDescription
idintegerYesAPI key ID

Request body

FieldTypeRequiredDescription
namestringNoUpdated name
descriptionstringNoUpdated description
isActivebooleanNoEnable or disable the key
expiresAtstring | nullNoSet or remove expiration
permissionsstring[]NoUpdated API scopes

Example request

Terminal window
curl -X PUT \
-H "X-API-Key: tlk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Sync Key",
"isActive": true,
"permissions": ["project:read", "translations:read", "translations:write", "schema:read"]
}' \
https://api.comvi.io/api/v1/api-keys/1

Example response

{
"id": 1,
"projectId": 5,
"name": "Production Sync Key",
"description": "Used by GitHub Actions for pulling translations",
"keyPrefix": "tlk_a1b2",
"lastUsedAt": "2025-03-20T14:00:00Z",
"expiresAt": null,
"isActive": true,
"permissions": ["project:read", "translations:read", "translations:write", "schema:read"],
"createdAt": "2025-01-15T10:00:00Z",
"updatedAt": "2025-03-25T11:00:00Z"
}

  • Use the principle of least privilege. Only grant the scopes your integration actually needs.
  • Set expiration dates for keys used in temporary environments (staging, feature branches).
  • Rotate keys periodically. Create a new key, update your integrations, then revoke the old one.
  • Store keys in environment variables, never in source code or config files committed to version control.
  • Monitor usage in the Comvi dashboard — each key logs its last usage time.

StatusError CodeDescription
400UNIQUE_CONSTRAINTAn API key with this name already exists in the project
400INVALID_INPUTInvalid scopes or payload
403FORBIDDENCannot grant scopes you do not have, or insufficient access
404API_KEY_NOT_FOUNDThe specified API key does not exist