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

# Blog

> Posts, categories, tags, scheduling, multi-language translation, and the AI authoring pipeline.

The Blog pillar is a full content engine — not a header-and-body table. Posts
have categories and tags, scheduling, multi-language translations, featured
images, SEO meta, and a research → write → image → translate → publish
pipeline that runs as one async job.

## What this gives you

* **Posts** with `draft`, `scheduled`, `published`, `archived` lifecycle.
* **Translations** per language with their own title, content, excerpt, and
  SEO meta.
* **Categories** and **tags** with slugs, attached many-to-many.
* **Scheduling** — set `scheduled_at` and we publish at the precise minute.
* **AI authoring pipeline** — one POST kicks off topic research, writing,
  image generation, translation to every target language, and SEO meta.

## Quick example

Create a published post in English, then async-translate it into French:

<CodeGroup>
  ```ts SDK theme={null}
  import { NeuralDraftClient } from "@neuraldraft/sdk";

  const nd = new NeuralDraftClient({ apiKey: process.env.NEURALDRAFT_API_KEY! });

  // Manual create (0 credits beyond plan post-quota). The SDK sets type="manual".
  const post = await nd.blogPosts.create({
    title: "Five things we shipped this week",
    content: "<p>It was a busy week.</p>",
    excerpt: "Highlights from the past seven days.",
    language_code: "en",
    status: "published",
  });

  // Async translate — returns a Job; 7 credits per language.
  const job = await nd.blogPosts.translate(post.id, ["fr"]);
  await nd.jobs.poll(job.id);
  ```

  ```bash cURL theme={null}
  # Manual create — note the discriminator: type=manual
  curl -X POST https://api.neuraldraft.io/v1/blog-posts \
    -H "Authorization: Bearer $NEURALDRAFT_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "manual",
      "title": "Five things we shipped this week",
      "content": "<p>It was a busy week.</p>",
      "excerpt": "Highlights from the past seven days.",
      "language_code": "en",
      "status": "published"
    }'

  # Translate the post asynchronously (returns a Job)
  curl -X POST https://api.neuraldraft.io/v1/blog-posts/4711/translate \
    -H "Authorization: Bearer $NEURALDRAFT_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"target_languages":["fr"]}'
  ```
</CodeGroup>

## Common workflows

### 1. Generate a multi-language post end to end

The headline workflow. One POST kicks off the full pipeline (research →
outline → write → featured-image → SEO meta → per-language translations) and
returns a Job reference. Subscribe to `blog_post.published` for the finished
result, or poll.

```ts SDK theme={null}
const job = await nd.blogPosts.generateAi({
  topic: "Why API-first beats site-builder-first for SMBs",
  style: "thought_leadership",
  word_count: 1200,
  primary_keyword: "API-first CMS",
  translate_to_all: true, // translate into every project target language
  enable_research: true,
});

const finished = await nd.jobs.poll(job.id, { timeoutMs: 10 * 60_000 });
// finished.result?.blog_post_id
```

```bash cURL theme={null}
# Same endpoint as manual create — discriminator: type=ai
curl -X POST https://api.neuraldraft.io/v1/blog-posts \
  -H "Authorization: Bearer $NEURALDRAFT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "ai",
    "topic": "Why API-first beats site-builder-first for SMBs",
    "style": "thought_leadership",
    "word_count": 1200,
    "primary_keyword": "API-first CMS",
    "translate_to_all": true,
    "enable_research": true
  }'
```

Cost: **60 credits** for the post itself (`blog_post` — covers research,
draft, and featured image). Per-language translations charge **7 credits
each** (`translate_language`) on top, billed when each language lands.

### 2. Schedule a post for next Tuesday

```ts SDK theme={null}
await nd.blogPosts.schedule(4711, "2026-05-19T09:00:00Z");
// Or: nd.blogPosts.schedule(4711, new Date(...))
```

```bash cURL theme={null}
curl -X POST https://api.neuraldraft.io/v1/blog-posts/4711/schedule \
  -H "Authorization: Bearer $NEURALDRAFT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"scheduled_at":"2026-05-19T09:00:00Z"}'
```

The post enters `scheduled` state. At the exact minute we transition it to
`published` and fire the `blog_post.published` webhook.

### 3. Edit and republish

Patch a published post in-place. Text fields (`title`, `content`, `excerpt`,
`meta_title`, `meta_description`) write to the translation row resolved by
`language_code` (default `en`); post-level fields (`slug`, `status`,
`category_id`, `featured_image`) write to the post itself.

```ts SDK theme={null}
await nd.blogPosts.update(4711, {
  title: "Five things we shipped (updated)",
  language_code: "en",
});
```

```bash cURL theme={null}
curl -X PATCH https://api.neuraldraft.io/v1/blog-posts/4711 \
  -H "Authorization: Bearer $NEURALDRAFT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Five things we shipped (updated)","language_code":"en"}'
```

### 4. Translate an existing post into a new language

```ts SDK theme={null}
const job = await nd.blogPosts.translate(4711, ["es", "it"]);
await nd.jobs.poll(job.id);
```

Cost: **7 credits per language** (`translate_language`).

### 5. Lifecycle helpers

```ts SDK theme={null}
await nd.blogPosts.publish(4711);
await nd.blogPosts.unpublish(4711);
await nd.blogPosts.delete(4711);

// List + filter
const { data: drafts } = await nd.blogPosts.list({
  status: "draft",
  page_size: 20,
  sort: "-created_at",
});
```

## Reference

| Endpoint                                      | Tag                             |
| --------------------------------------------- | ------------------------------- |
| `GET /v1/blog-posts`                          | [Blog](/api-reference#tag/Blog) |
| `POST /v1/blog-posts`                         | [Blog](/api-reference#tag/Blog) |
| `GET /v1/blog-posts/{slug}`                   | [Blog](/api-reference#tag/Blog) |
| `PUT /v1/blog-posts/{id}`                     | [Blog](/api-reference#tag/Blog) |
| `POST /v1/blog-posts/{id}/publish`            | [Blog](/api-reference#tag/Blog) |
| `POST /v1/blog-posts/{id}/schedule`           | [Blog](/api-reference#tag/Blog) |
| `POST /v1/blog-posts/{id}/unpublish`          | [Blog](/api-reference#tag/Blog) |
| `GET /v1/blog-posts/{id}/translations`        | [Blog](/api-reference#tag/Blog) |
| `PUT /v1/blog-posts/{id}/translations/{lang}` | [Blog](/api-reference#tag/Blog) |
| `GET /v1/categories`                          | [Blog](/api-reference#tag/Blog) |
| `GET /v1/tags`                                | [Blog](/api-reference#tag/Blog) |
| `POST /v1/jobs` (`blog_post.generate`)        | [Jobs](/api-reference#tag/Jobs) |
| `GET /v1/blog/topic-suggestions`              | [Blog](/api-reference#tag/Blog) |
