> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/pocketbase/pocketbase/llms.txt
> Use this file to discover all available pages before exploring further.

# Collections

> Learn about PocketBase collections, the foundation of your database schema

Collections are the fundamental building blocks of your PocketBase database. Each collection defines a table structure with custom fields, validation rules, and API access permissions.

## Collection types

PocketBase supports three distinct collection types, each designed for specific use cases:

### Base collections

Base collections are the standard collection type for storing general-purpose data. They provide a flexible structure with customizable fields and automatic ID generation.

```go theme={null}
collection := core.NewBaseCollection("posts")
```

**Key characteristics:**

* Automatically includes an `id` field (15-character lowercase alphanumeric string)
* Supports all available field types
* Ideal for most data storage needs

### Auth collections

Auth collections are specialized for user authentication and management. They come with built-in authentication fields and support multiple authentication methods.

```go theme={null}
collection := core.NewAuthCollection("users")
```

**Built-in system fields:**

* `id` - Unique record identifier
* `email` - User email address (unique when not empty)
* `emailVisibility` - Controls whether email is publicly visible
* `verified` - Email verification status
* `password` - Hashed password (hidden from API responses)
* `tokenKey` - Internal token for session management (hidden)

<Note>
  Auth collection IDs are unique across all auth collections to prevent conflicts during authentication.
</Note>

**Authentication methods:**

* Password authentication
* OAuth2 (Google, Facebook, GitHub, etc.)
* One-time password (OTP)
* Multi-factor authentication (MFA)

### View collections

View collections are read-only collections based on SQL queries. They allow you to create virtual collections from complex queries without storing duplicate data.

```go theme={null}
collection := core.NewViewCollection("active_users")
collection.ViewQuery = "SELECT id, email FROM users WHERE verified = true"
```

**Limitations:**

* Read-only (cannot create, update, or delete records)
* Fields are auto-generated from the query result
* Cannot have file fields

## Collection structure

Every collection has the following core properties:

<CodeGroup>
  ```go Go (struct definition) theme={null}
  type Collection struct {
      Id      string      // Unique collection identifier
      Name    string      // Collection name (used as table name)
      Type    string      // "base", "auth", or "view"
      Fields  FieldsList  // List of collection fields
      Indexes []string    // Database indexes
      System  bool        // Prevents deletion/modification
      
      // API Rules
      ListRule   *string  // Controls list/search access
      ViewRule   *string  // Controls single record view access
      CreateRule *string  // Controls record creation
      UpdateRule *string  // Controls record updates
      DeleteRule *string  // Controls record deletion
      
      Created types.DateTime
      Updated types.DateTime
  }
  ```

  ```json JSON (API response) theme={null}
  {
    "id": "pbc_1234567890",
    "name": "posts",
    "type": "base",
    "system": false,
    "listRule": "@request.auth.id != ''",
    "viewRule": null,
    "createRule": "@request.auth.id != ''",
    "updateRule": "@request.auth.id = author",
    "deleteRule": "@request.auth.id = author",
    "fields": [
      {
        "id": "text1234567",
        "name": "title",
        "type": "text",
        "required": true
      }
    ],
    "indexes": [
      "CREATE INDEX idx_created_pbc_1234567890 ON posts (created)"
    ],
    "created": "2024-01-01 00:00:00.000Z",
    "updated": "2024-01-01 00:00:00.000Z"
  }
  ```
</CodeGroup>

## Fields

Collections contain fields that define the structure of your data. PocketBase supports various field types:

* **text** - Single-line text
* **editor** - Rich text with HTML support
* **number** - Integers and decimals
* **bool** - Boolean true/false
* **email** - Email with validation
* **url** - URL with validation
* **date** - Date and time
* **select** - Single or multiple choice from predefined options
* **json** - Structured JSON data
* **file** - File uploads (single or multiple)
* **relation** - References to records in other collections
* **autodate** - Automatically managed creation/update timestamps

<Tip>
  Each field has its own validation rules, constraints, and options. See the [Records](/concepts/records) page for more details on working with field values.
</Tip>

## Indexes

Indexes improve query performance for frequently accessed fields. You can add indexes programmatically:

```go theme={null}
collection.AddIndex(
    "idx_email",        // Index name
    true,               // Unique index
    "`email`",          // Column expression
    "email != ''",      // Optional WHERE clause
)
```

Auth collections automatically create unique indexes for `email` and `tokenKey` fields.

## System collections

System collections have the `System` flag set to `true`, which prevents:

* Renaming the collection
* Deleting the collection
* Modifying API rules (for some system collections)

Examples of system collections:

* `_superusers` - Admin users
* `_externalAuths` - OAuth2 authentication records
* `_mfas` - Multi-factor authentication data
* `_otps` - One-time password records

<Warning>
  Never manually modify system collections unless you understand the implications. They are essential for PocketBase's core functionality.
</Warning>

## Collection lifecycle

PocketBase provides hooks for intercepting collection operations:

```go theme={null}
app.OnCollectionCreate().Bind(&hook.Handler[*core.CollectionEvent]{
    Func: func(e *core.CollectionEvent) error {
        // Called before creating a collection
        return e.Next()
    },
})

app.OnCollectionAfterCreateSuccess().Bind(&hook.Handler[*core.CollectionEvent]{
    Func: func(e *core.CollectionEvent) error {
        // Called after successfully creating a collection
        return e.Next()
    },
})
```

**Available hooks:**

* `OnCollectionValidate` - Validation phase
* `OnCollectionCreate` / `OnCollectionUpdate` / `OnCollectionDelete` - Before operation
* `OnCollectionCreateExecute` / `OnCollectionUpdateExecute` / `OnCollectionDeleteExecute` - During database operation
* `OnCollectionAfterCreateSuccess` / `OnCollectionAfterUpdateSuccess` / `OnCollectionAfterDeleteSuccess` - After success
* `OnCollectionAfterCreateError` / `OnCollectionAfterUpdateError` / `OnCollectionAfterDeleteError` - After error

## Working with collections

### Creating collections

```go theme={null}
collection := core.NewBaseCollection("articles")

// Add fields
collection.Fields.Add(
    &core.TextField{
        Name:     "title",
        Required: true,
        Max:      200,
    },
    &core.EditorField{
        Name:     "content",
        Required: true,
    },
)

// Set API rules
collection.ListRule = types.Pointer("")
collection.ViewRule = types.Pointer("")
collection.CreateRule = types.Pointer("@request.auth.id != ''")

// Save to database
if err := app.Save(collection); err != nil {
    return err
}
```

### Querying collections

```go theme={null}
// Find by name
collection, err := app.FindCollectionByNameOrId("articles")

// Find by ID
collection, err := app.FindCachedCollectionByNameOrId("pbc_1234567890")

// List all collections
collections, err := app.FindAllCollections("")

// List only auth collections
authCollections, err := app.FindAllCollections(core.CollectionTypeAuth)
```

### Updating collections

```go theme={null}
collection, err := app.FindCollectionByNameOrId("articles")
if err != nil {
    return err
}

// Modify collection
collection.ListRule = types.Pointer("@request.auth.verified = true")

// Save changes
if err := app.Save(collection); err != nil {
    return err
}
```

### Deleting collections

```go theme={null}
collection, err := app.FindCollectionByNameOrId("articles")
if err != nil {
    return err
}

if err := app.Delete(collection); err != nil {
    return err
}
```

<Warning>
  Deleting a collection will permanently remove all its records and cannot be undone.
</Warning>

## Best practices

<AccordionGroup>
  <Accordion title="Use descriptive collection names">
    Choose names that clearly indicate the collection's purpose. Use lowercase and underscores for multi-word names (e.g., `blog_posts`, `user_profiles`).
  </Accordion>

  <Accordion title="Plan your schema carefully">
    While PocketBase allows schema changes, major structural changes can be complex when you have existing data. Plan your collections and fields before implementation.
  </Accordion>

  <Accordion title="Use appropriate field types">
    Select field types that match your data. For example, use `date` for timestamps, `number` for quantities, and `email` for email addresses to benefit from built-in validation.
  </Accordion>

  <Accordion title="Set API rules early">
    Define API rules during development to avoid accidentally exposing sensitive data. Start restrictive and relax rules as needed.
  </Accordion>

  <Accordion title="Index frequently queried fields">
    Add indexes to fields used in filters, sorts, or joins to improve query performance. However, avoid over-indexing as it can slow down write operations.
  </Accordion>
</AccordionGroup>
