Skip to content

Restricted API Keys

An API key you create in the dashboard can do everything with its data by default. When a key goes somewhere you trust less, such as an AI agent, a reporting script, a contractor's tool or a page anyone can view, give it only what it needs. A key can be:

  • Read-only: it can read values, lists and files, but not change or delete anything.
  • Limited to one scope: it only reaches data in one project (and, if you choose, one domain and subdomain).
  • Set to expire: it stops working after a date you pick.

You can combine all three. A leaked or misused key can then do far less damage.

Creating one

In the dashboard, open API Keys, choose Add, and open Restrictions in the dialog:

  1. Tick Read-only to stop the key from changing anything.
  2. Fill in project (and optionally domain and subdomain) to limit it to that scope. Leave a field empty to not limit that level.
  3. Pick an Expires after date. The key works through the end of that day (UTC).

The key list shows each key's restrictions next to its name, and marks expired keys.

Restrictions can't be changed later

They are fixed when the key is made. To change them, create a new key with the restrictions you want and delete the old one.

Using a limited key

A key limited to a scope must name that scope in every request, exactly as it was set (letters in the same case). It isn't filled in for you, so it's always clear which data a request means.

// A key limited to project "reports"
const db = new PrefsDB(process.env.PREFSDB_KEY);
const res = await db.project("reports").key("total").read();     // works
await db.key("total").read();                                    // refused: no project named
# A key limited to project "reports"
curl -s -H "Authorization: Bearer $KEY" "https://prefsdb.com/api/v1/read/?total=&project=reports"   # works
curl -s -H "Authorization: Bearer $KEY" "https://prefsdb.com/api/v1/read/?total="                  # refused

Files work the same way: upload, download and delete them with the key's scope.

What a restricted key can't do

Restriction Refused with What it covers
Read-only KEY_READ_ONLY (403) Writing, deleting, undo, expiry changes, uploading or deleting files, publishing to channels, rotating or moving the key. Reading and following channels still work.
Scope SCOPE_NOT_ALLOWED (403) Any request that doesn't name exactly the key's scope. The error's scope field says what to send.
Expiry KEY_EXPIRED (403) Every request once the date has passed.

Channels aren't tied to a scope, so a scope limit doesn't affect them; a read-only key can follow a channel but not publish to it.

Good to know

  • Restrictions are for dashboard keys. Keys from getkey() belong to your app's users and work as before.
  • Rotating a key keeps its restrictions.
  • For AI agents, a read-only key, or one limited to a project made for the agent, is the simplest way to keep a mistake from touching the rest of your data.