Skip to content

API Keys

API keys authenticate automation — the CLI, CI/CD pipelines, webhook receivers calling back into Comvi, custom scripts. Every key is scoped to a single project and carries its own set of API scopes. At runtime, access is also bounded by the creator’s current project access.

Humans authenticate with sessions instead. For the full picture of the two paths, see the auth diagram in Roles & Permissions.

  • Running comvi push / comvi pull from a developer machine or CI
  • Triggering exports or imports from a build system
  • Admin scripts that manage projects, keys, namespaces programmatically
  • Any server-to-server integration calling the REST API

If your use case is “load published translations into an app”, you do not need an API key — the production CDN is unauthenticated. Keys are for authoring and tooling.

An API key is a string that looks like comvi_<random>. On every request you pass it in the X-API-Key header. Comvi checks:

  1. The key exists and is active
  2. The key is not expired (if expiresAt was set)
  3. The key has the specific permission the endpoint requires

Only then is the request authorized. API keys use project-scoped scopes that map to the API operations they can perform. The supported scopes are project:read, translations:read, translations:write, and schema:read.

Follow the principle of least privilege — grant only what the integration genuinely needs. Common bundles:

IntegrationScopes
comvi pull (read only)project:read, translations:read, schema:read
comvi push (write)above + translations:write
Import/export automationproject:read, translations:read, translations:write
Schema/type generationschema:read
Read-only reporting scriptsproject:read, translations:read

The REST API docs under Authentication show which scope each API-key endpoint requires. In the dashboard, the create-key UI groups scopes into categories so you tick the rows you need instead of typing strings.

  1. Open API Keys

    Project Settings → API Keys.

  2. Create

    Click Create API Key. Give it a descriptive name — the name shows up in logs and “last used” tracking, so pick something like github-actions-release or support-agent-admin-script rather than key1.

  3. Pick permissions

    Tick only the rows you need. You can refine later.

  4. (Optional) Set an expiration

    Keys can auto-expire on a date you pick. Strongly recommended for CI keys and any non-permanent integration.

  5. Copy the key

    Comvi shows the full key once. Copy it now into your secrets manager or environment variable store. You cannot view it again after closing the dialog.

Keys start with the comvi_ prefix so they are easy to spot in logs, config files, and leaked secrets scanners.

Terminal window
export COMVI_API_KEY=comvi_…
comvi pull

Or via a config file that you keep out of git (or use environment substitution):

{
"apiKey": "comvi_…",
"apiBaseUrl": "https://api.comvi.io",
"translationsPath": "./src/locales"
}
Terminal window
curl -H "X-API-Key: comvi_…" \
https://api.comvi.io/api/v1/projects/<id>/translations

API-key requests do not need CSRF tokens (sessions do). This makes server-to-server integration cleaner.

Store the key as a CI secret and inject it as an env var.

- run: npx @comvi/cli pull
env:
COMVI_API_KEY: ${{ secrets.COMVI_API_KEY }}

See CI/CD Integration for complete pipeline examples.

Rotate on a schedule, after a team member departure, or if you suspect leakage.

  1. Create a new key with the same permissions and an expiration that gives you a rollover window.

  2. Update every consumer — CI secrets, deployed services, local .env files.

  3. Verify the new key works — trigger one job or request.

  4. Revoke the old key

    Delete it in the dashboard. It becomes invalid immediately.

An API key is a project credential created by a user, not a browser session. Implications:

  • Keys are still bounded by the creator’s active account and current project permissions. If the creator is deleted, blocked, removed from the project, or loses required permissions, the key may stop working.
  • A Manager can create a key with only translations:read if that’s what the integration needs. If that Manager later loses translation read access, the key’s effective access is reduced too.
  • History entries and webhook deliveries attribute actions to the key, not to a user, so audit logs show “by API key github-actions-release” rather than a human name.
  • Environment variables or secret managers. Never hardcode or commit keys.
  • Least privilege. Resist the urge to grant translations:write when translations:read suffices.
  • One key per integration. Rotate and revoke independently; identify usage in “last used”.
  • Set expirations. Anything not explicitly permanent should auto-expire.
  • Watch for leakage. Public git mirrors, error logs, screen shares — all common leak surfaces. The comvi_ prefix makes keys easy for scanners to spot.
  • Rotate on departure. When someone who created or had access to a key leaves, rotate affected keys.
  • Scope: project-scoped only; there are no organization-level API keys today.
  • Header: X-API-Key only. No Authorization: Bearer form.
  • Display: the key value is shown once, on creation.

Verify the X-API-Key header is present and contains the full token. Check the key is active in the dashboard and has not expired.

The key is valid but lacks the specific permission for this endpoint. Compare the endpoint’s documented required permission to the key’s permissions and add what’s missing (edit the key — you don’t need to rotate for this).

You are probably looking at the wrong project. Keys are project-scoped.

Revoke it immediately. Create a replacement. Audit “last used” and webhook/delivery logs for unexpected activity. Rotate any downstream credentials the leak may have exposed.