Create an Entry

Create an Entry

This endpoint creates a new content entry in a specified collection.

Endpoint

[POST]

/{collection_slug}

Permissions

This endpoint requires a token with the create ability.

Path Parameters

NameRequiredDescription
collection_slugYesThe unique slug of the collection.

Headers

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

Body Parameters

The request body should be a JSON object containing the following keys:

NameTypeRequiredDescription
dataobjectYesAn object where keys are the field names and values are the content for each field.
statusstringNoThe publication status. Can be published or draft (default).
localestringNoThe locale code for the content (e.g., en-US).

Relation and Media Reference Rules

  • Relation and media fields accept entry/asset UUIDs (and numeric IDs when enabled by your setup).
  • Every referenced entry/asset must belong to the same project as the request.
  • Relation fields must also match the relation field's configured target collection.
  • Invalid references return 422 validation errors under data.<field_name>.

data Object Example

{
    "data": {
        "title": "My New Post",
        "slug": "my-new-post-slug",
        "author": "e3a4b1c2-d5e6-f7g8-h9i0-j1k2l3m4n5o6", // UUID for a relation
        "tags": [
            { "value": "API" },
            { "value": "Tech" }
        ] // Example for a repeatable text field
    },
    "status": "published",
    "locale": "en"
}

Example Requests

import { createClient } from '@elmapicms/js-sdk';
 
const client = createClient(
  'https://your-domain.com/api',
  'YOUR_API_TOKEN',
  'YOUR_PROJECT_UUID'
);
 
// Create a new entry
const newEntry = await client.createEntry('blog-posts', {
  locale: 'en',
  state: 'draft',
  data: {
    title: 'API Best Practices',
    slug: 'api-best-practices'
  }
});
 
// Create a published entry
const publishedEntry = await client.createEntry('blog-posts', {
  locale: 'en',
  state: 'published',
  published_at: '2024-01-01T00:00:00Z',
  data: {
    title: 'My Published Post',
    slug: 'my-published-post'
  }
});
const collectionSlug = 'blog-posts';
const newEntry = {
    data: {
        title: 'API Best Practices',
        slug: 'api-best-practices'
    },
    status: 'draft'
};
 
axios.post(`https://your-domain.com/api/${collectionSlug}`, newEntry, {
    headers: {
        'Accept': 'application/json',
        'Authorization': 'Bearer YOUR_API_TOKEN', // Required - must have 'create' ability
        'project-id': 'YOUR_PROJECT_UUID'
    }
});
use Illuminate\Support\Facades\Http;
 
$collectionSlug = 'blog-posts';
$newEntry = [
    'data' => [
        'title' => 'API Best Practices',
        'slug' => 'api-best-practices'
    ],
    'status' => 'draft'
];
 
$response = Http::withToken('YOUR_API_TOKEN')->withHeaders([
    'Accept' => 'application/json',
    'project-id' => 'YOUR_PROJECT_UUID'
])->post("https://your-domain.com/api/{$collectionSlug}", $newEntry);
import React, { useState } from 'react';
 
function CreateEntryForm({ collectionSlug }) {
  const [title, setTitle] = useState('');
  const [slug, setSlug] = useState('');
 
  const handleSubmit = async (event) => {
    event.preventDefault();
    try {
      const response = await fetch(`https://your-domain.com/api/${collectionSlug}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
          'Authorization': 'Bearer YOUR_API_TOKEN', // Required - must have 'create' ability
          'project-id': 'YOUR_PROJECT_UUID'
        },
        body: JSON.stringify({
          data: { title, slug },
          status: 'draft'
        })
      });
 
      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.message || 'Failed to create entry');
      }
 
      const createdEntry = await response.json();
      console.log('Entry created:', createdEntry);
    } catch (error) {
      console.error('Failed to create entry:', error);
    }
  };
 
  return (
    <form onSubmit={handleSubmit}>
      <input type="text" value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Title" required />
      <input type="text" value={slug} onChange={(e) => setSlug(e.target.value)} placeholder="Slug" required />
      <button type="submit">Create Entry</button>
    </form>
  );
}
<template>
  <form @submit.prevent="createEntry">
    <input v-model="title" placeholder="Title" required />
    <input v-model="slug" placeholder="Slug" required />
    <button type="submit">Create Entry</button>
  </form>
</template>
 
<script setup>
import { ref } from 'vue';
 
const props = defineProps({
  collectionSlug: { type: String, required: true }
});
 
const title = ref('');
const slug = ref('');
 
const createEntry = async () => {
  try {
    const response = await fetch(`https://your-domain.com/api/${props.collectionSlug}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Authorization': 'Bearer YOUR_API_TOKEN', // Required - must have 'create' ability
        'project-id': 'YOUR_PROJECT_UUID'
      },
      body: JSON.stringify({
        data: {
          title: title.value,
          slug: slug.value,
        },
        status: 'draft'
      })
    });
 
    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.message || 'Failed to create entry');
    }
 
    const createdEntry = await response.json();
    console.log('Entry created:', createdEntry);
  } catch (error) {
    console.error('Failed to create entry:', error);
  }
};
</script>
curl -X POST "https://your-domain.com/api/blog-posts" \
     -H "Accept: application/json" \
     -H "Authorization: Bearer YOUR_API_TOKEN" \
     -H "project-id: YOUR_PROJECT_UUID" \
     -H "Content-Type: application/json" \
     -d '{
         "data": {
             "title": "API Best Practices",
             "slug": "api-best-practices"
         },
         "status": "draft"
     }'

Responses

201: Created

Returns the newly created content entry object.

{
    "data": {
        "uuid": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
        "locale": "en",
        "published_at": null,
        "fields": {
            "title": "API Best Practices",
            "slug": "api-best-practices"
        }
    }
}

403: Forbidden

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

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

422: Unprocessable Entity

Returned for validation errors, such as a missing required field, a non-unique value for a unique field, invalid relation/media references, or attempting to create an entry in a singleton collection that already has one.

{
    "message": "The slug field is required.",
    "errors": {
        "data.slug": [
            "The slug field is required."
        ],
        "data.gallery": [
            "One or more media references are invalid for this project."
        ]
    }
}

Search documentation

Find guides and reference pages