Create a Collection

Create a Collection

This endpoint creates a new collection (content type) in the project. You can optionally include field definitions to create the collection with its full schema in a single request.

Endpoint

[POST]

/collections

Permissions

This endpoint requires a token with the admin ability.

Headers

NameRequiredDescription
AcceptYesSpecifies the response content type. Must be application/json.
AuthorizationYesRequired. Must be a Bearer token with admin scope.
project-idYesThe unique identifier for the project.

Body Parameters

NameTypeRequiredDescription
namestringYesThe display name of the collection. Max 60 characters.
slugstringYesThe URL-friendly identifier. Must be unique per project. Max 60 characters.
is_singletonbooleanNoIf true, the collection can only have one entry. Defaults to false.
fieldsarrayNoAn array of field definitions to create with the collection.

Reserved Slugs

The following slugs are reserved and cannot be used: collections, files.

fields Array

Each field object in the fields array can have the following properties:

NameTypeRequiredDescription
typestringYesThe field type (e.g., text, number, richtext, boolean, date, media, relation, group, etc.).
labelstringYesThe display label for the field. Max 60 characters.
namestringYesThe field identifier in kebab-case (e.g., my-field). Max 60 characters.
descriptionstringNoA description of the field.
placeholderstringNoPlaceholder text for the field input.
optionsobjectNoField-specific options (e.g., { "repeatable": true }).
validationsobjectNoValidation rules for the field.
childrenarrayNoChild field definitions. Only applicable for group type fields.

Example Requests

// Create a collection with fields in one request
axios.post('https://your-domain.com/api/collections', {
    name: 'Blog Posts',
    slug: 'blog-posts',
    fields: [
        {
            type: 'text',
            label: 'Title',
            name: 'title',
            validations: {
                required: { status: true, message: 'Title is required' }
            }
        },
        {
            type: 'richtext',
            label: 'Content',
            name: 'content'
        },
        {
            type: 'group',
            label: 'SEO',
            name: 'seo',
            options: { repeatable: false },
            children: [
                { type: 'text', label: 'Meta Title', name: 'meta-title' },
                { type: 'longtext', label: 'Meta Description', name: 'meta-description' }
            ]
        }
    ]
}, {
    headers: {
        'Accept': 'application/json',
        'Authorization': 'Bearer YOUR_API_TOKEN',
        'project-id': 'YOUR_PROJECT_UUID'
    }
});
use Illuminate\Support\Facades\Http;
 
$response = Http::withToken('YOUR_API_TOKEN')->withHeaders([
    'Accept' => 'application/json',
    'project-id' => 'YOUR_PROJECT_UUID'
])->post('https://your-domain.com/api/collections', [
    'name' => 'Blog Posts',
    'slug' => 'blog-posts',
    'fields' => [
        [
            'type' => 'text',
            'label' => 'Title',
            'name' => 'title',
            'validations' => [
                'required' => ['status' => true, 'message' => 'Title is required']
            ]
        ],
        [
            'type' => 'richtext',
            'label' => 'Content',
            'name' => 'content'
        ]
    ]
]);
curl -X POST "https://your-domain.com/api/collections" \
     -H "Accept: application/json" \
     -H "Authorization: Bearer YOUR_API_TOKEN" \
     -H "project-id: YOUR_PROJECT_UUID" \
     -H "Content-Type: application/json" \
     -d '{
         "name": "Blog Posts",
         "slug": "blog-posts",
         "fields": [
             {
                 "type": "text",
                 "label": "Title",
                 "name": "title"
             },
             {
                 "type": "richtext",
                 "label": "Content",
                 "name": "content"
             }
         ]
     }'

Responses

201: Created

Returns the newly created collection object, including its fields if any were provided.

{
    "data": {
        "uuid": "d8f7b5c1-e4a3-4b21-8e9f-a9c1e2b3d4f5",
        "name": "Blog Posts",
        "slug": "blog-posts",
        "is_singleton": false,
        "created_at": "2026-02-10T10:00:00.000000Z",
        "updated_at": "2026-02-10T10:00:00.000000Z",
        "fields": [
            {
                "uuid": "a1b2c3d4-0001-0000-0000-000000000001",
                "type": "text",
                "label": "Title",
                "name": "title",
                "description": null,
                "placeholder": null,
                "options": [],
                "validations": {
                    "required": { "status": true, "message": "Title is required" }
                },
                "order": 1,
                "parent_field_id": null
            },
            {
                "uuid": "a1b2c3d4-0001-0000-0000-000000000002",
                "type": "richtext",
                "label": "Content",
                "name": "content",
                "description": null,
                "placeholder": null,
                "options": [],
                "validations": [],
                "order": 2,
                "parent_field_id": null
            }
        ]
    }
}

403: Forbidden

Returned if the API token does not have the admin ability.

{
    "message": "API token doesn't have the right abilities!"
}

422: Unprocessable Entity

Returned for validation errors, such as a duplicate slug or a reserved slug.

{
    "message": "The slug has already been taken.",
    "errors": {
        "slug": [
            "The slug has already been taken."
        ]
    }
}

Search documentation

Find guides and reference pages