DietlyAPI developer guide. Last reviewed: July 2026

API key hygiene: rotation, scopes, expiry and 2FA

The single highest-value change you can make is to stop using one key for everything. One key per service, each with the narrowest scope that still works, means a leak is a contained incident rather than a full compromise: you rotate the one key, the one service has a short blip, and nothing else on your account notices. Everything else on this page is a refinement of that idea. DietlyAPI supports named access keys with independent scopes, expiry dates and per-key rate caps, so the good structure is available without any extra tooling.

The checklist: one key per service, read scope unless you need writes, an expiry date on anything temporary, a per-key rate cap so one service cannot starve the others, 2FA on the account itself, and a rotation you have practised before you need it.

One key per service

Name keys after where they run: web-prod, worker-prod, ci, laptop-dev. This costs nothing and pays back the first time something goes wrong, because it turns two impossible questions into easy ones. Which service is generating that traffic spike? The one whose key shows the usage. What do I have to redeploy after this key leaked? The one service that used it. A single shared key makes both questions unanswerable, and it means every rotation is a coordinated outage across your whole stack.

The same logic applies to environments. A development key on a laptop, in a shell history and in half a dozen scratch scripts is the likeliest key on your account to leak, and it should never be the same key that serves production traffic.

Use read scope unless you need more

Keys carry a scope. A read-scope key can perform GET requests and nothing else; if it is used for any other method the API refuses with a clear 403:

{"detail":"This API key is read-only. Use a full-access key for this endpoint."}

Most integrations only ever look data up, so read scope is the correct default rather than a hardened configuration. It also converts an entire class of incident into a non-event: a leaked read-only key exposes public catalog data that anyone can already query anonymously. Reach for a full-access key only for the specific service that genuinely needs to write, and keep that key's blast radius as small as you can.

Put an expiry on anything temporary

Access keys accept an expiry, set in days. Anything you create for a contractor, a demo, a spike or a one-off migration should have one, because the failure mode of temporary credentials is that they are never temporary. An expiry converts "someone should remember to delete this" into a guarantee. The dashboard warns you before a key expires, so the honest tradeoff is a scheduled, visible interruption against an unbounded credential that outlives the reason it was created. Long-lived production keys can stay open-ended; everything else should have a date on it.

Set a per-key rate cap

Each access key can carry its own rate limit below your plan's ceiling. This is a stability feature more than a security one. A batch job that suddenly loops does not just fail; it consumes the whole account's per-minute budget and starves the user-facing service that shares it. Give the batch worker a cap it cannot exceed and the blast radius of that bug is the batch job alone. A useful default is to cap background workers at something well under half your plan limit and leave interactive traffic uncapped.

Rotate before you need to, and practise it

Rotation issues a new secret for an existing key, keeping its name, scope, expiry and cap. That matters because it means rotating does not require rebuilding your configuration; only the secret changes.

POST /auth/access-keys/{id}/rotate

The reason to rehearse is that the hard part is never the rotate button. It is discovering, at the worst possible moment, that the key is hardcoded in a config file nobody has touched in a year, or that three services read it from an environment variable set by hand on a box that predates your deployment pipeline. Rotate one non-critical key deliberately, on a quiet afternoon, and find out how long it actually takes. Do that once and a real incident becomes a twenty-minute job instead of an evening.

If a key is exposed publicly, in a repository, a client bundle or a log, rotate rather than delete. Rotation keeps the key's identity and settings while invalidating the leaked secret, so you get the security outcome without also losing the configuration.

Turn on 2FA for the account

All of the above protects individual keys. None of it helps if someone signs in to the dashboard, because from there they can mint new keys at will. DietlyAPI supports TOTP two-factor authentication with any standard authenticator app, plus recovery codes for the day you lose your phone. Store the recovery codes somewhere that is not the same password manager you use to log in, and regenerate them if you ever use one. This is a two-minute setup that sits underneath every other control on this page.

Keep keys out of the places they leak from

Watch the audit log and the usage numbers

The dashboard records account security events and shows per-key usage. Two habits make that data useful rather than decorative. First, look at per-key usage occasionally and confirm each key's shape matches what that service is supposed to do; a development key with steady round-the-clock traffic is telling you something. Second, check the audit log after anything unexpected, because it is the only record that distinguishes "our batch job misbehaved" from "someone else has account access". Both questions are answerable in about thirty seconds if you know where to look, and unanswerable if you have one shared key.

What good looks like

A tidy small-team setup is four keys and one 2FA enrolment. A read-scope web-prod key with no expiry and no per-key cap, serving user traffic. A read-scope worker-prod key capped at a fraction of the plan limit, running scheduled syncs. A read-scope ci key with a 90-day expiry. A read-scope laptop-dev key per developer, also expiring, and rotated without ceremony whenever anyone feels like it. Nothing in that list is difficult, and together they mean any single leak costs you one rotation and no downtime. If you also cache aggressively, as the caching guide describes, the capped worker will rarely come close to its limit either.

Common questions

What is the safest default scope for an API key?

Read. A read-scope key can only perform GET requests, and anything else returns a 403 explaining that the key is read-only. Most integrations only look data up, and a leaked read-only key exposes catalog data that can already be queried anonymously.

Should I rotate or delete a leaked key?

Rotate. Rotation issues a new secret while keeping the key's name, scope, expiry and rate cap, so the leaked secret stops working without you having to rebuild the configuration around it.

Why set a per-key rate limit?

To contain bugs rather than attackers. A looping batch job on a shared key consumes the whole account's per-minute budget and starves user-facing traffic. A cap on the worker means the blast radius is the worker alone.

Can I put an API key in my mobile app?

No. Anything shipped in a client bundle is public, including values inlined at build time. Call the API from your own server. Prototypes can use the public read endpoints, which need no key at all.