Work with records and queries
Create, list, filter, sort, expand, update, and delete PocketBase records safely.
This guide uses the JavaScript SDK to complete the record lifecycle against a posts collection. Replace YOUR_RECORD_ID with an ID returned by your own create or list operation. You need a running PocketBase server, a collection whose schema includes title, and credentials or API rules that permit the operation.
listRule, viewRule, createRule, updateRule, and deleteRule. A valid request can still be denied or filtered by those rules.Run the create request with title: 'Release notes'. The response contains the generated record ID; keep it as YOUR_RECORD_ID.
Run getList(1, 50) with the documented filter, sort, and expand values. The result contains permitted items and pagination totals.
Pass YOUR_RECORD_ID to update with title: 'Release notes — updated'. The response contains the updated title.
List the collection again to confirm the updated title, or pass the confirmed ID to delete only when removal is intended. A successful delete returns an empty response.
Create a record
Create a record with the smallest schema-valid body.
import PocketBase from 'pocketbase';
const pb = new PocketBase('http://127.0.0.1:8090');
const record = await pb.collection('posts').create({
title: 'Release notes',
});
console.log(record.id);The response contains the generated record ID, collection name, and timestamps. Save that ID as YOUR_RECORD_ID for the next operations. PocketBase also accepts JSON or multipart form data; use multipart when uploading files.
List, filter, sort, and expand
List the first page and request only records whose title contains Release:
const result = await pb.collection('posts').getList(1, 50, {
filter: 'title ~ "Release"',
sort: '-created,id',
expand: 'author',
});
console.log(result.items, result.totalItems);page defaults to 1 and perPage defaults to 30 when omitted. Sort fields use - for descending and + or no prefix for ascending. expand adds permitted related records under expand; nested expansion supports up to six levels. Use getFullList({ sort: '-created' }) when you need all matching records, or getFirstListItem('title = "Release notes"') for one match.
Update a record
Update only the fields that should change:
const updated = await pb.collection('posts').update('YOUR_RECORD_ID', {
title: 'Release notes — updated',
});
console.log(updated.title);The PATCH operation addresses /api/collections/{collectionIdOrName}/records/{recordId} and returns the updated record. The update must satisfy the collection's update rule and field validation.
Delete a record
Delete only an ID you have confirmed is safe to remove:
await pb.collection('posts').delete('YOUR_RECORD_ID');
console.log('Deleted');The delete operation returns an empty response on success. It can fail when the record is still required by a relation; resolve that supported data dependency before retrying. Treat deletion as irreversible unless your application provides its own recovery process.
Verify and troubleshoot
Confirm that the created or updated title appears in a list query, that result.items contains only records permitted by the list rule, and that an expanded relation appears only when the requesting user can view it. An invalid filter produces a 400 response. A locked rule produces 403 for non-superusers, while an operation denied by a non-locked view, update, or delete rule can appear as 404.
If a query returns no items, first inspect the filter and then inspect the collection's list rule; an empty successful list can be the intended security result. If deletion fails because of a required relation, keep the record and review that relation before attempting another destructive operation.
Next, see the Records API reference for HTTP parameters and response shapes, or continue with API rules and filters to adjust authorization.