Skip to main content
Collections define the structure of your data in PocketBase. Each collection has a type, fields, and various configuration options.

Collection types

PocketBase supports three collection types:
  • base - Standard collections for general data storage
  • auth - Collections with built-in authentication features
  • view - Read-only collections based on SQL queries

Creating collections

NewCollection()

Create a new collection with the specified type:
collection := core.NewCollection(core.CollectionTypeBase, "posts")

NewBaseCollection()

Create a base collection:
collection := core.NewBaseCollection("articles")

NewAuthCollection()

Create an auth collection:
users := core.NewAuthCollection("users")

NewViewCollection()

Create a view collection:
view := core.NewViewCollection("posts_stats")
view.ViewQuery = "SELECT id, COUNT(*) as total FROM posts GROUP BY category"

Finding collections

FindCollectionByNameOrId()

Find a collection by name or ID:
collection, err := app.FindCollectionByNameOrId("posts")
if err != nil {
    log.Fatal(err)
}

FindCachedCollectionByNameOrId()

Find a collection from the app cache (faster, but read-only):
collection, err := app.FindCachedCollectionByNameOrId("posts")
if err != nil {
    log.Fatal(err)
}
The cached collection should only be used for read-only operations. Modifying the cached collection affects the global cached value.

FindAllCollections()

Find all collections, optionally filtered by type:
// All collections
allCollections, err := app.FindAllCollections()

// Only auth collections
authCollections, err := app.FindAllCollections(core.CollectionTypeAuth)

// Auth and view collections
collections, err := app.FindAllCollections(
    core.CollectionTypeAuth,
    core.CollectionTypeView,
)

Collection properties

Basic properties

collection.Id          // Auto-generated ID
collection.Name        // Collection name (also the table name)
collection.Type        // base, auth, or view
collection.System      // System collection (cannot be deleted/renamed)
collection.Created     // Creation timestamp
collection.Updated     // Last update timestamp

Type checking

if collection.IsBase() {
    log.Println("This is a base collection")
}

if collection.IsAuth() {
    log.Println("This is an auth collection")
}

if collection.IsView() {
    log.Println("This is a view collection")
}

Managing fields

Adding fields

collection.Fields.Add(
    &core.TextField{
        Name: "title",
        Required: true,
        Max: 200,
    },
    &core.TextField{
        Name: "content",
    },
    &core.NumberField{
        Name: "views",
        Min: types.Pointer(0.0),
    },
)

Getting fields

// Get field by name
field := collection.Fields.GetByName("title")

// Get field by ID
field = collection.Fields.GetById("field_id")

// Get all field names
names := collection.Fields.FieldNames()

Removing fields

collection.Fields.RemoveById("field_id")
collection.Fields.RemoveByName("old_field")

API rules

Collections have API rules that control access:
// Allow anyone to list records
collection.ListRule = types.Pointer("")

// Only authenticated users can view individual records
collection.ViewRule = types.Pointer("@request.auth.id != ''")

// Only the record owner can update
collection.UpdateRule = types.Pointer("@request.auth.id = id")

// Only admins can delete
collection.DeleteRule = nil // nil means no access

// Anyone can create
collection.CreateRule = types.Pointer("")
API rules use PocketBase’s filter syntax. Use nil to deny all access, or an empty string "" to allow all access.

Auth collection options

Auth collections have additional configuration:
users := core.NewAuthCollection("users")

// Auth rule (who can authenticate)
users.AuthRule = types.Pointer("verified = true")

// OAuth2 providers
users.OAuth2.Providers = []core.OAuth2ProviderConfig{
    {
        Name: "google",
        ClientId: "your-client-id",
        ClientSecret: "your-client-secret",
        Enabled: true,
    },
}

// Password options
users.PasswordAuth.Enabled = true
users.PasswordAuth.IdentityFields = []string{"email", "username"}

// MFA options
users.MFA.Enabled = true
users.MFA.Duration = 1800 // 30 minutes

// OTP options
users.OTP.Enabled = true
users.OTP.Duration = 300 // 5 minutes

View collection options

View collections are based on SQL queries:
view := core.NewViewCollection("user_stats")

view.ViewQuery = `
    SELECT
        users.id,
        users.email,
        COUNT(posts.id) as total_posts
    FROM users
    LEFT JOIN posts ON posts.user = users.id
    GROUP BY users.id
`
View queries must include an id column. Wildcard columns are not supported to prevent accidentally exposing sensitive data.

Indexes

Adding indexes

// Create a unique index
collection.AddIndex(
    "idx_email",
    true, // unique
    "`email`",
    "", // no WHERE clause
)

// Create a composite index with WHERE clause
collection.AddIndex(
    "idx_active_users",
    false, // not unique
    "`status`, `created`",
    "`status` = 'active'",
)

Getting indexes

idx := collection.GetIndex("idx_email")
if idx != "" {
    log.Println("Index found:", idx)
}

Removing indexes

collection.RemoveIndex("idx_email")

Saving collections

Save a new collection

collection := core.NewBaseCollection("posts")

collection.Fields.Add(
    &core.TextField{Name: "title", Required: true},
    &core.TextField{Name: "content"},
)

if err := app.Save(collection); err != nil {
    log.Fatal(err)
}

Update an existing collection

collection, err := app.FindCollectionByNameOrId("posts")
if err != nil {
    log.Fatal(err)
}

collection.ListRule = types.Pointer("")

if err := app.Save(collection); err != nil {
    log.Fatal(err)
}

Deleting collections

collection, err := app.FindCollectionByNameOrId("posts")
if err != nil {
    log.Fatal(err)
}

if err := app.Delete(collection); err != nil {
    log.Fatal(err)
}
Deleting a collection also deletes all its records and associated files.

Collection references

Find all collections that reference a specific collection:
refs, err := app.FindCollectionReferences(collection)
if err != nil {
    log.Fatal(err)
}

for refCollection, fields := range refs {
    log.Printf("Collection %s references via fields:", refCollection.Name)
    for _, field := range fields {
        log.Printf("  - %s", field.GetName())
    }
}

Importing collections

Import collections from configuration data:
collectionsData := []map[string]any{
    {
        "name": "posts",
        "type": "base",
        "fields": []map[string]any{
            {"name": "title", "type": "text"},
        },
    },
}

err := app.ImportCollections(collectionsData, false)
if err != nil {
    log.Fatal(err)
}

Type signature

type Collection struct {
    Id         string
    Name       string
    Type       string
    System     bool
    Fields     FieldsList
    Indexes    types.JSONArray[string]
    ListRule   *string
    ViewRule   *string
    CreateRule *string
    UpdateRule *string
    DeleteRule *string
    Created    types.DateTime
    Updated    types.DateTime
}