# Create a content

**Publié le** : 2026-05-08
**Catégorie** : Core CMS

## `POST /contents`

**Create a content**

Creates a new content in `draft` status by default. You must provide
at least a `title` and `type` (currently only `"post"` is supported).

The `slug` is auto-generated from the title if not provided. If a
slug collision occurs, a numeric suffix is appended (e.g., `my-post-2`).

Submit the body as markdown via `bodyMarkdown`. The API converts it
to TipTap JSON internally. Alternatively, submit raw TipTap JSON via
`body` for advanced formatting control.

Required permissions: `contents.create`

### Request Body

Content-Type: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | "post" | Yes | Required. Resource type. One of: post |
| `title` | string | Yes | Required. Display title. 1-500 characters |
| `slug` | string | Yes | Required. URL-friendly identifier, unique per site and locale. 1-500 characters |
| `excerpt` | string | No | Short summary for previews |
| `body` | object | No | Rich text content as TipTap JSON |
| `bodyMarkdown` | string | No | Content as Markdown (converted to TipTap JSON on save) |
| `status` | "draft" \| "published" \| "archived" \| "scheduled" | No | One of: draft, published, archived, scheduled |
| `featuredImage` | string | No | Featured image URL |
| `scheduledAt` | string | No | Scheduled publication datetime (ISO 8601) |
| `metaTitle` | string | No | Custom meta title for SEO. Max 255 characters |
| `metaDescription` | string | No | Meta description for search engines. Max 500 characters |
| `keywords` | string | No | Comma-separated SEO keywords. Max 500 characters |
| `canonicalUrl` | string | No | Canonical URL override. Max 1000 characters |
| `ogImage` | string | No | Open Graph image URL for social sharing. Max 1000 characters |
| `authorName` | string \| null | No |  |
| `authorUrl` | string \| null | No |  |
| `meta` | object | No | Additional metadata |
| `categoryIds` | string[] | No | Min 1 character. Array of strings |
| `tagIds` | string[] | No | Array of strings |
| `customData` | object \| null | No | Custom fields data (structured content) |
| `locale` | string | No | BCP 47 locale code (e.g. "en", "fr") |
| `translationGroupId` | string | No | Translation group UUID (links translations across locales) |
| `faqSettings` | object | No | FAQ detection and JSON-LD settings |
| `jsonLdGraph` | object[] | No | Max 50 characters. Array of objects |
| `jsonLdExclusions` | string[] | No | Max 50 characters. Array of strings |
| `displayOrder` | number | No | Number |


### Responses

| Status | Description |
| --- | --- |
| `201` | Successful response |
| `401` | Unauthorized — invalid or missing API token |
| `403` | Forbidden — insufficient permissions |
| `422` | Validation error |


> **Notes:** - `scheduledAt` is required when `status` is `"scheduled"` and must be in the future.
> 
> - `categoryIds` must reference existing category UUIDs for the same site.
> - `customData` is available only for contents whose category uses structured content schemas.

### Examples

```bash
curl -X POST https://api.lynkow.com/v1/contents \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "post",
    "title": "Getting Started with Lynkow",
    "bodyMarkdown": "# Welcome\n\nThis is your first article.",
    "status": "draft",
    "categoryIds": ["uuid-of-category"]
  }'
```

### Response Example

```json
{
  "data": {
    "id": 43,
    "title": "Getting Started with Lynkow",
    "slug": "getting-started-with-lynkow",
    "type": "post",
    "status": "draft",
    "excerpt": null,
    "bodyHtml": "<h1>Welcome</h1><p>This is your first article.</p>",
    "locale": "en",
    "featuredImage": null,
    "categories": [
      {
        "id": 1,
        "name": "Tutorials",
        "slug": "tutorials"
      }
    ],
    "tags": [],
    "meta": {
      "metaTitle": null,
      "metaDescription": null,
      "canonicalUrl": null,
      "ogImage": null
    },
    "author": {
      "id": 1,
      "fullName": "Jane Doe"
    },
    "publishedAt": null,
    "createdAt": "2025-04-06T12:00:00.000Z",
    "updatedAt": "2025-04-06T12:00:00.000Z"
  }
}
```

---