---
title: API keys and scopes
description: How to create API keys, choose scopes, keep keys safe, and rotate or revoke them when something leaks.
group: Start here
order: 2
keywords: [api key, authentication, bearer token, scopes, api security, rotate key]
---

# API keys and scopes

Every request from your code carries an API key. The key says who you are and what you
may do. There are no other credentials to manage.

## Create a key

**Settings → API keys → Create API key.** You choose:

- a **name**, so you recognise it later (`website production`, `import script`);
- the **scopes** it gets — tick only what the app needs;
- optionally an **expiry date**;
- optionally the **collections** it may touch.

The key is shown once, immediately after creation. It is stored as a hash, so nobody —
including us — can read it back afterwards.

Keys start with `pb_live_` or `pb_test_`. The two behave identically and use the same
data; the prefix is a label so you can tell a production key from a scratch one at a
glance.

## Use a key

Send it as a bearer token:

```bash
curl -s "https://www.wrongnotebook.com/v1/me" \
  -H "Authorization: Bearer pb_live_your_key_here"
```

```js
fetch(url, { headers: { Authorization: `Bearer ${process.env.BAAS_KEY}` } });
```

`GET /v1/me` is the quickest way to check a key: it returns the key's workspace, scopes
and allowed collections.

## Scopes

A scope is one permission. A key with `records:read` can read records and nothing else.

| Scope                | What it allows                                                    |
| -------------------- | ----------------------------------------------------------------- |
| `collections:read`   | List collections and read their settings                          |
| `collections:create` | Create collections                                                |
| `collections:update` | Change collection settings                                        |
| `collections:delete` | Move collections to the trash, restore them, delete them for good |
| `records:read`       | Read and query records, and export them                           |
| `records:create`     | Add records                                                       |
| `records:update`     | Change records                                                    |
| `records:delete`     | Move records to the trash and restore them                        |
| `schemas:read`       | Read schema versions                                              |
| `schemas:write`      | Create and activate schema versions                               |
| `files:read`         | Download files                                                    |
| `files:write`        | Upload, attach and delete files                                   |

Any record, schema or file scope also lets the key read that collection's basic details.

**Things keys can never do**, no matter the scopes: invite or remove people, manage other
keys, service accounts or webhooks, transfer ownership, permanently delete records, manage
indexes, or read the audit log. Those need a signed-in person, which means a leaked key
cannot be used to take over an account.

## A key is never stronger than you

When you create a key, every scope you ask for must be something _you_ can already do in
that workspace. The key is also re-checked against your current role on every request, so
if your access is reduced later, the key's access shrinks at the same moment.

## Keeping keys safe

- **Server-side only.** A key in browser JavaScript, a mobile app bundle, or a public Git
  repository is a key anyone can copy. Keep it in an environment variable on your server
  or in your hosting provider's secret settings.
- **One key per app.** When you retire a project you revoke its key alone.
- **Smallest scope that works.** A form that only writes needs `records:create` — not
  `records:read`, and certainly not delete.
- **Set an expiry** for anything temporary, like a key for a workshop or a contractor.

If you only need to publish read-only data, do not hand out a key at all. Make the
collection [public](/docs/collections#public-and-unlisted-collections) and let anyone read
it without credentials.

## Rotate a key

Rotating issues a new secret for the same key, keeping its name and scopes.

Use the **⋯ menu → Rotate secret** on the API keys page. You can let the old secret keep
working for a grace period (up to seven days) so you have time to deploy the new one.
Choose **Immediately** if the old secret has leaked.

## Revoke a key

**⋯ menu → Revoke key.** It stops working at once and cannot be brought back. Do this the
moment a key appears somewhere public.

Afterwards, check **Settings → Audit log** to see what that key did while it existed.

## Service accounts

A service account is a machine user for an integration, so an automation does not depend
on one person's account. Create one in **Workspace → Service accounts**, give it a role,
and issue keys for it. If the person who set up the integration later leaves, nothing
breaks.

## Next steps

- [Collections](/docs/collections) — where records live.
- [Errors](/docs/errors) — what `401` and `403` mean and how to fix them.
