Skip to content

System collections

_superusers, _mfas, _otps, _totps, _magicLinks, _externalAuths, _authOrigins, _teams, _team_members, _cron_jobs, _rpc, _webhooks, _audit_log, _push_subscriptions, _sessions, _bans, _emailTemplates, _mailLog, _emailTriggers, _emailAssets, _notifications, _channels, and the default users auth collection all ship with fixed, deterministic ids shared with PocketBase’s own equivalents where one exists — see Collections for the id-derivation formula that makes this consistent.

_sessions is a live-session table: one row per issued token, written by the login/refresh/impersonation handlers rather than through any rule-driven client write path (createRule/updateRule/deleteRule all stay superuser-only). listRule/viewRule let a record see its own rows: id, collectionRef, recordRef, tokenHash (hidden), kind (password | otp | oauth2 | impersonation | refresh), fingerprint, ip, userAgent, expiresAt, lastSeenAt, and revoked. Populated only when SESSION_TRACKING=true (the default). See REST API → Auth for the sessions/auth-signout endpoints that read and write it.

_bans is superuser-only end to end — never listable or viewable by the banned record itself, unlike _sessions/_authOrigins: id, collectionRef, recordRef, reason, expiresAt, bannedBy, with a unique index over (collectionRef, recordRef). Banning rotates the target’s signing key and revokes every one of its _sessions rows, so a ban takes effect on live sessions immediately, not just on the next login attempt. See REST API → Auth’s ban/{id} entry.

_rpc is superuser-only end to end, the same trust tier as _cron_jobs: id, name (unique slug), sql, params (json), rule (json — see Custom SQL RPC for why this is json and not text), readOnly, timeoutMs, maxRows. A definition’s own sql is superuser-authored and runs with no rule of this collection’s own in between; per-call authorization comes from the definition’s rule field instead, evaluated by POST /rpc/{name}, not by _rpc.createRule/viewRule/etc.

_totps holds TOTP 2FA state, at most one row per (collectionRef, recordRef) pair: id, collectionRef, recordRef, secret (hidden, encrypted with CB_ENCRYPTION when set), confirmed, backupCodes (hidden, a JSON array of hashed one-time codes — an entry is removed the moment it’s consumed), lastUsedStep (the TOTP replay guard). Owner-readable via listRule/viewRule; mutations only ever go through the dedicated .../totp/* routes, same reasoning as _sessions/_bans above.

_magicLinks is the token store for magic-link login — same shape and rules as _otps (owner-readable, otherwise superuser-only): id, collectionRef, recordRef, tokenHash (hidden, SHA-256 of the emailed token — looked up by exact match, like _sessions.tokenHash), sentTo, redirectUrl.

_emailTemplates is the editable template store Email → Templates covers: key (e.g. auth.verification, welcome), name, subject, html, text, locale, layout, description, sendRule (nullable — gates non-superuser access to POST /api/mails/send, see Email → Templates → sendRule), design/editor (dashboard-only, opaque to the server), unique on (key, locale). Superuser-only end to end.

_mailLog records every POST /api/mails/send/$mails.send/trigger attempt — see Email → Mail log: to (JSON array of {address, name}), subject, template, status (queued/sent/failed), error, messageId. Superuser-read-only, append-only like _audit_log, pruned by settings.logs.mailLogMaxDays.

_emailTriggers is the no-code trigger store Email → Triggers covers: collection, event (create/update/delete), template, toField, condition, enabled, dataMap. Superuser-only end to end, same trust tier as _webhooks.

_emailAssets backs the dashboard’s email-template visual editor’s image uploads: a single file field, up to 8MB, image mime types only. createRule/updateRule/deleteRule are superuser-only like every other system collection here, but the field itself is not protected — GET /api/files/{collectionId}/{recordId}/{filename} serves it to anyone with the URL regardless of a viewer’s session, which an emailed <img src> needs, since the recipient has no session to present at all.

_notifications is in-app notifications’ store: collectionRef/recordRef (the recipient, any auth collection), type, title, body, data (json), link, readAt (nullable), indexed on (collectionRef, recordRef, readAt, created). listRule/ viewRule/updateRule/deleteRule let a recipient see and act on their own rows; a non-superuser may only ever change readAt through the generic records API (enforced at the route layer, not expressible as a rule). createRule stays superuser/API-key only — the only intended writer is $notify.send/POST /api/notifications/send.

_channels configures realtime channels: name (an exact channel name or a prefix:* pattern), subscribeRule, publishRule (both nullable json, same null/“”/expr convention as _emailTemplates.sendRule). Superuser-only end to end. No row matching a given channel name disables it — the secure default.