# Content Types

A **content type** defines the fields that entries in that content type can store. Think of it as a reusable template: an Articles type might ask for a title, body, and cover image, while an Events type might ask for a date and location.

Every content type belongs to exactly one content bucket.

## Creating a content type

Open `/@acme/entries`, select a content bucket, and add a content type. Two fields are required:

| Field | Rules | Example |
|---|---|---|
| **Name** | Alpha-dash, up to 255 characters. Used as the `contentType` query parameter in API requests. | `pages` |
| **Label** | Up to 255 characters. Displayed in the manager. | `Pages` |

Content Type names are API contracts. Changing a content type name or its field names changes the API contract for API clients, so choose stable names.

## Adding fields

Each content type can have any number of fields. A field defines:

- **Name** — the key used in API payloads, validation errors, and rendered entry fields. Alpha-dash, up to 64 characters.
- **Label** — the editor-facing name shown in entry forms, up to 255 characters.
- **Type** — string, number, boolean, date, array, attachment, relation, or JSON.
- **Required** — required fields must be filled when an entry is created and when the field is submitted during updates.

See [Fields](/docs/content-modeling/fields) for the full field type reference.

## Primary field

A **primary field** gives entries a meaningful display name. Set one field as primary in the content type editor.

The primary field value appears as the entry `name` in:

- Entry lists in the manager.
- Relation field selectors.
- API response objects (`response.name`).

If no primary field is set, the entry's ULID is used as the `name`.

## Field configuration

Fields can be reordered, duplicated, and deleted from the content type editor. The field order determines the editor form layout.

Each field also accepts type-specific settings:

| Setting | Applies to | Description |
|---|---|---|
| `input_type` | string | Subtype: textarea, richtext, email, URL, slug, path, dropdown, list, phone |
| `multiple` | attachment, relation | Allow multiple values |
| `distinct` | attachment, relation, array | Prevent duplicate selections |
| `unique` | string, number | Enforce unique values across all entries in the content type |
| `options` | string (dropdown/list), array | Predefined allowed values |
| `accept` | attachment | Allowed MIME types (e.g. `image/*`, `application/pdf`) |
| `cascade_on_delete` | attachment, relation | Delete related files or entries when an entry is deleted |
| `decimal` | number | Fixed decimal precision |
| `format` | date | Date, time, or datetime format |
| `checked_by_default` | boolean | Default value for new entries |
| `current_timestamp` | date | Default to the current timestamp |

## API contract

API requests use `contentBucket` and `contentType` query parameters to identify the target content type. Entry payloads place editor values under `fields` using the field name as the key. See [API Entries](/docs/api/entries) for examples.

## Deleting a content type

Deleting a content type removes all entries inside it. This cannot be undone.

## Next steps

- [Fields](/docs/content-modeling/fields) — Reference for all field types and settings.
- [Entries](/docs/content/entries) — Creating and managing entries.
- [API Entries](/docs/api/entries) — Entry CRUD via the API.
