How do I create and manage API keys?
API keys authenticate requests to Better i18n from your code, CLI, and integrations. There are two kinds, and they are created in different places for different jobs.
The two kinds of key #
| Key | Created in | Prefix | What it can do |
|---|---|---|---|
| Account key | Settings → API Keys | bi- | Acts as you: everything your account can do (CLI, CI, admin calls) |
| Content key | A project's Content settings | bi_pub_ | Reads content from the Content API. Read-only, per model |
The distinction that matters: an account key carries your own permissions, so it belongs on a server, in CI, or in your shell — never in a browser bundle. A content key is issued read-only by design and is the one you ship to the client.
Both are sent the same way — the x-api-key header:
curl "https://content.better-i18n.com/v1/content/acme/dashboard/models/help-article/entries?status=published" \
-H "x-api-key: bi_pub_..."Creating an account key #
- Go to Settings → API Keys
- Click "New API key"
- Enter a descriptive name (e.g., "Production frontend", "GitHub Actions CI")
- Pick an expiry — 90 days, 180 days, 365 days, or never
- Click Create
- Copy the key immediately — it is not shown again
There is no key-type choice here: an account key is an account key. Its scope is your account's access, which is why the expiry option is worth using.
Creating a content key #
Content keys are created per project, from the project's Content settings, and only by an organization admin. They:
- carry a
bi_pub_prefix so they are recognisable at a glance - expire after 365 days
- are read-only — a write permission requested on a public content key is reduced to read
- can be narrowed per content model, so a key can read
help-articleand nothing else
Permissions are expressed per model slug, not as global scopes:
{ "help-article": ["read"], "blog-post": ["read"] }Key management practices #
- One key per environment — separate keys for dev, staging, and production
- Descriptive names — include the environment and the use case:
prod-frontend,ci-deploy - Rotate on offboarding — an account key acts as the person who made it
- Never commit keys — use environment variables
- Ship content keys, not account keys — if a key reaches the browser, it must be a content key
Using a key with the CLI #
export BETTER_I18N_API_KEY=bi-...
better-i18n syncThe CLI reads BETTER_I18N_API_KEY from the environment by default, so the key never has to appear in better-i18n.config.ts.
Revoking a key #
- Go to Settings → API Keys
- Find the key
- Click Revoke and confirm
Revoking takes effect immediately: anything still using that key starts getting 401s. Deploy the replacement first. Content keys are managed from the project's Content settings rather than this list, so a key you cannot find here is probably a content key.
Rate limits #
API-key traffic is rate limited at the edge — on the order of 1000 requests per minute per account. A burst above that gets 429s; it does not revoke or degrade the key. If you are hitting it from a frontend, you are probably fetching per request where you could be caching: Content API responses are already cached at the edge for you.
Better I18N