PocketBase API Rules

SkillAI & models

PocketBase API Rules is a skill that helps an AI agent write permission rules and filter expressions for controlling access to a PocketBase database. It covers all five rule types, filter syntax, operators, request and collection macros, and field modifiers. Use it when setting permissions, configuring who can access what, or debugging 403 and 404 responses.

Use PocketBase API Rules in Claude, ChatGPT or Ahel Desktop

Free. Sign in, add PocketBase API Rules and connect your AI. About a minute.

Also: Claude Code · Cursor · Codex

Then ask your AI: use the PocketBase API Rules skill

Details

Instructions available. Your AI can read the instructions. Execution depends on the setup they require.

Have a PocketBase instance and an AI agent that can load skills.

PocketBase API RulesStart free

What your AI can do with it

  • Write PocketBase API rules for all five rule types
  • Build filter expressions with operators and macros
  • Use request and collection macros in rules
  • Apply field modifiers in filter expressions
  • Debug 403 and 404 responses from access rules

Getting started

  1. Have a PocketBase instance and an AI agent that can load skills.
  2. Add the PocketBase API Rules skill to the agent's available skills.
  3. Ask the agent to write or review a rule for a specific collection.
  4. Test the rule against your PocketBase instance and adjust as needed.

What this skill tells your AI

The instructions your AI receives, as published by davila7/claude-code-templates in cli-tool/components/skills/pocketbase/pb-api-rules/SKILL.md and read by ahel’s review.

Rule Types

Each collection has 5 rule types. Each rule is a filter expression that must evaluate to true for the request to proceed.

RuleControlsLocked =Empty string =
ListGET /api/collections/{name}/recordssuperusers onlyeveryone can list
ViewGET /api/collections/{name}/records/{id}superusers onlyeveryone can view
CreatePOST /api/collections/{name}/recordssuperusers onlyeveryone can create
UpdatePATCH /api/collections/{name}/records/{id}superusers onlyeveryone can update
DeleteDELETE /api/collections/{name}/records/{id}superusers onlyeveryone can delete

Critical: null/locked means only superusers can perform the action (regular users and guests are denied). Empty string "" means EVERYONE including guests. Superusers always bypass API rules entirely — see below.

Superuser Bypass

Superusers (formerly admins) always bypass API rules. Rules only apply to regular auth records and guests.

Filter Syntax

Operators

OperatorMeaningExample
=Equalstatus = "active"
!=Not equalstatus != "draft"
>Greater thancount > 5
>=Greater or equalcount >= 5
<Less thancount < 10
<=Less or equalcount <= 10
~LIKE (contains)title ~ "hello"
!~NOT LIKEtitle !~ "spam"
?=Any/has (array contains)tags ?= "TAG_ID"
?!=None (array not contains)tags ?!= "TAG_ID"
?>Any greater thanscores ?> 90
?>=Any greater or equalscores ?>= 90
?<Any less thanscores ?< 10
?<=Any less or equalscores ?<= 10
?~Any LIKEemails ?~ "@gmail.com"
?!~Any NOT LIKEemails ?!~ "@test.com"

Critical: use ?= (not =) for multi-valued fields (multi-select, multi-relation, multi-file). = checks the raw JSON string, ?= checks individual values.

Logical Operators

status = "active" && author = @request.auth.id
status = "active" || status = "featured"

Parentheses for grouping: (a = 1 || b = 2) && c = 3

Values

  • Strings: "value" or 'value'
  • Numbers: 123, 45.67
  • Booleans: true, false
  • null — empty/missing value
  • Identifiers: field names, macros

Request Macros (@request.*)

Access the current request context in rules:

MacroTypeDescription
@request.auth.idstringCurrent auth record ID (empty if guest)
@request.auth.emailstringCurrent auth record email
@request.auth.verifiedboolWhether email is verified
@request.auth.collectionIdstringAuth collection ID
@request.auth.collectionNamestringAuth collection name
@request.auth.*anyAny field from the auth record
@request.body.fieldNameanyField value from request body
@request.query.paramNamestringURL query parameter
@request.headers.namestringRequest header (lowercase key)
@request.methodstringHTTP method (GET/POST/PATCH/DELETE)

Auth record relations

You can traverse relations on the auth record:

@request.auth.team.owner = @request.auth.id

Collection Macros (@collection.*)

Cross-collection lookups without explicit joins:

@collection.memberships.user ?= @request.auth.id &&
@collection.memberships.team ?= team

This checks if a record exists in the memberships collection where the user matches the current auth user and the team matches the current record's team field.

Note: @collection.* performs an implicit EXISTS subquery. It's powerful but can be slow on large datasets — add indexes.

Field Modifiers

Use in create/update rules to validate specific field behaviors:

ModifierWorks onDescription
:isset@request.body.*True if the field was sent in the request (even if empty)
:changedrecord fieldTrue if the field value differs from current stored value (update only)
:lengthstring/arrayReturns the length
:eacharrayApplies the condition to each element
:lowerstringLowercased value

Examples

// Only allow changing status if user is owner
status:changed = false || author = @request.auth.id

// Prevent setting role on create
@request.body.role:isset = false

// Require at least 2 tags
@request.body.tags:length >= 2

// Check each tag is from allowed list
@request.body.tags:each ?= @collection.allowed_tags.id

Datetime Macros

MacroExample output
@now2024-01-15 10:30:00.000Z
@second2024-01-15 10:30:00.000Z
@minute2024-01-15 10:30:00.000Z
@hour2024-01-15 10:00:00.000Z
@day2024-01-15 00:00:00.000Z
@month2024-01-01 00:00:00.000Z
@year2024-01-01 00:00:00.000Z
@todayStart2024-01-15 00:00:00.000Z
@todayEnd2024-01-15 23:59:59.999Z
@monthStart2024-01-01 00:00:00.000Z
@monthEnd2024-01-31 23:59:59.999Z
@yearStart2024-01-01 00:00:00.000Z
@yearEnd2024-12-31 23:59:59.999Z

Arithmetic: @now - 7d, @now + 1h, @now - 30m

geoDistance()

For location-based filtering:

geoDistance(lat, lon, 40.7128, -74.0060) <= 10000

Arguments: geoDistance(latField, lonField, targetLat, targetLon) — returns meters.

Common Patterns

Owner-only access

// View/Update/Delete rule:
author = @request.auth.id

Authenticated users only

@request.auth.id != ""

Verified users only

@request.auth.verified = true

Role-based access

@request.auth.role = "admin" || author = @request.auth.id

Team membership

@collection.team_members.user ?= @request.auth.id &&
@collection.team_members.team ?= team

Public read, owner write

// List/View: ""  (empty = everyone)
// Create: @request.auth.id != ""
// Update/Delete: author = @request.auth.id

Prevent field modification

// Update rule: prevent changing `owner` after creation
owner:changed = false

Time-limited access

expires > @now

Signals

GitHub stars
32k
Forks
4k
Last commit
Oct 2026

Questions

What are the five rule types?
The skill covers all five PocketBase rule types: list, view, create, update, and delete. Each controls access to a specific operation on a collection.
How do I debug a 403 or 404 response?
The skill helps trace which rule blocked the request. Check the rule for the operation and collection, then verify the filter expression and macros match the request.
Can it help with filter syntax?
Yes. It covers filter syntax, operators, request and collection macros, and field modifiers used in PocketBase rules.
Does it work with any PocketBase version?
The skill describes PocketBase API rules and filter expressions. It does not state version-specific behavior.
Advanced
Item type
skill
Key
pocketbase-api-rules
Source
github.com/davila7/claude-code-templates