Skip to content
DocsPocketBaseCollections & API Rules

Collections & API Rules

Collections are PocketBase’s tables. Each collection defines a schema (typed fields) and a set of API rules that control who can list, view, create, update, and delete its records. Getting the rules right is the single most important step in securing your app.

Creating a collection

Using the portal

  1. Open the admin panel at https://<instance-name>.pocketbasecloud.com/_/
  2. Click New collection
  3. Choose the type:
    • Base — regular data (posts, products, comments, …)
    • Auth — user accounts with login capability
    • View — read-only collection backed by a SQL SELECT
  4. Add fields and click Create

Using the CLI

Point pb at the instance once, log in as its superuser, and the collection commands work against it:

pb use https://<instance-name>.pocketbasecloud.com
pb login

Create an empty collection, or pass a full definition to create it with its fields in one step:

pb collections create tasks --type base

pb collections create '{"name":"posts","type":"base","fields":[
  {"name":"title","type":"text","required":true},
  {"name":"body","type":"editor"},
  {"name":"published","type":"bool"}]}'

Inspect and change them:

pb collections ls
pb collections get posts
pb collections update posts '{"fields":[…]}'
pb collections rm posts

pb use --name <profile> keeps several instances side by side (staging and production, say), and --profile <name> picks one per command. The same commands work against a local instance — pb use http://127.0.0.1:8090.

Field types

PocketBase supports the field types you’d expect:

Type Use for
text, editor, number, bool Basic values, rich text
email, url, date Validated formats
select One or more values from a fixed list
relation References to records in another collection
file File uploads
json Arbitrary structured data

Relations are expanded on demand with the expand query parameter:

const post = await pb.collection("posts").getOne("RECORD_ID", {
  expand: "author,comments_via_post",
});

API rules

Each collection has five rules — List, View, Create, Update, and Delete. A rule is a filter expression; the operation is allowed only when the expression matches.

Using the portal

Edit them from the lock icon on the collection page in the admin panel.

Using the CLI

pb rules get posts

pb rules set posts \
  --list-rule '@request.auth.id != ""' \
  --view-rule '@request.auth.id != ""' \
  --create-rule '@request.auth.id != ""' \
  --update-rule 'author = @request.auth.id' \
  --delete-rule 'author = @request.auth.id'

Pass null as a value to lock a rule back to superusers only:

pb rules set posts --delete-rule null

Three states matter, whichever way you set them:

  • Locked (superusers only) — the rule is null; only superusers via the admin panel or admin token can perform the operation
  • Empty string — anyone can perform the operation
  • Filter expression — allowed only when the expression evaluates to true

Common rule recipes

Only signed-in users can read:

@request.auth.id != ""

Users can only see and edit their own records (with an owner relation field pointing to users):

owner = @request.auth.id

Anyone can read published posts, authors see their drafts too:

status = "published" || author = @request.auth.id

Validate incoming data on create — e.g., force the owner field to the current user:

@request.auth.id != "" && @request.body.owner = @request.auth.id

Rules can reference the current record’s fields, @request.auth (the authenticated user), @request.body, @request.query, and even fields across relations (author.verified = true).

Working with records

Using the portal

Open a collection in the admin panel to browse, filter, edit, and create records.

Using the CLI

The same operations, handy for seeding data and for checking what a rule actually returns:

pb records ls posts --filter 'published = true' --sort '-created' --per-page 50
pb records get posts RECORD_ID
pb records create posts '{"title":"first","published":true}'
pb records update posts RECORD_ID '{"published":false}'
pb records rm posts RECORD_ID

Testing your rules

The admin panel’s API preview on each collection shows the exact REST endpoints and lets you copy example requests. A quick way to verify rules is to call the API without a token and confirm you get a 403 or filtered results, then repeat with a logged-in user.

From the terminal, pb records ls runs as the superuser (rules don’t apply to it), so test the rules themselves with an unauthenticated request:

curl https://<instance-name>.pocketbasecloud.com/api/collections/posts/records

Important: never leave Create/Update/Delete rules empty on a production collection unless you truly want them public. Locked-by-default is the safe starting point.

Moving a schema between instances

Once a schema is right on one instance, copy it to another — staging to production, or a local instance to the cloud.

Using the portal

The project’s Collections page has Export and Import dialogs, and the admin panel has its own under Settings → Import collections.

Using the CLI

pb use https://staging.pocketbasecloud.com && pb login
pb collections export --out collections.json

pb use https://production.pocketbasecloud.com && pb login
pb collections import collections.json

--delete-missing makes the import an exact mirror by dropping collections not present in the file — it asks for confirmation first, and it drops their data with them.

Next steps