# create_chapter

Create a chapter or a collection.

`POST /v1/guides/{productId}/chapters` · MCP tool `create_chapter` · scope `write` · stable · since 2026-09-17

kind chapter for sections that carry prose (body paragraphs, an intro); kind collection for pure spot sets. Add members afterwards with set_chapter_members.

## Path parameters

- `productId` (string, required): Id of the guide (a product of type map). From list_guides or create_guide.

## Body parameters

- `name` (string, required): Chapter title, e.g. Yellowstone or Bernese Oberland. Cannot be empty.
- `body` (array of strings, optional): Ordered prose paragraphs, chapters only, full replacement ([] clears): at most 100, each at most 10,000 characters; empty paragraphs are dropped.
- `description` (string, optional): One-line summary shown on the chapter card. Empty string clears.
- `kind` (string, optional): chapter or collection (default collection). One of `chapter`, `collection`.
- `slug` (string, optional): Optional URL slug, unique in the guide: 1 to 63 lowercase letters, digits or hyphens, a letter or digit first (stored lower case). Empty string clears.

## Returns

201: Chapter.

- `collectionId` (string, required): The chapter's or collection's id.
- `productId` (string, required): The guide's id.
- `name` (string, required): Its title.
- `slug` (string or null, required): URL slug, unique in the guide.
- `description` (string or null, required): One-line summary on the chapter card.
- `kind` (string, required): chapter carries prose and front matter; collection is a plain spot set. One of `collection`, `chapter`.
- `body` (array of strings, required): Prose paragraphs (chapters only).
- `intro` (ChapterIntro or null, required): Structured front matter (chapters only).
  Fields of ChapterIntro: https://developers.sceniq.earth/fields/chapter-intro.md
- `order` (number, required): Position in the guide.
- `coverUrl` (string or null, required): The cover image.
- `coverStorageId` (string or null, required): The cover's storage id (from an upload with target=blob).
- `members` (array of objects, required): Members in order: spots, or chapters inside a collection.
  - `spotKey` (string or null, required): A member spot's key.
  - `memberCollectionId` (string or null, required): A chapter placed as a card inside a collection.
  - `order` (number, required): Position in the chapter.
- `createdAt` (number, required): When the row was created (Unix time in milliseconds).
- `updatedAt` (number, required): When the row last changed (Unix time in milliseconds).

## Examples

### A chapter with prose

```bash
curl -X POST "https://sceniq.earth/api/v1/guides/j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2/chapters" \
  -H "Authorization: Bearer $SCENIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Yosemite",
  "kind": "chapter",
  "slug": "yosemite",
  "description": "Granite walls and the valley from above",
  "body": [
    "Tunnel View, Glacier Point and the trails off Glacier Point Road show the valley from three heights. Glacier Point Road closes to cars in winter, so from November to late May this chapter shrinks to the valley floor.",
    "Sunset belongs to Tunnel View and Taft Point; Glacier Point works from late afternoon into the blue hour."
  ]
}'
```

MCP `tools/call`:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "create_chapter",
    "arguments": {
      "productId": "j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2",
      "name": "Yosemite",
      "kind": "chapter",
      "slug": "yosemite",
      "description": "Granite walls and the valley from above",
      "body": [
        "Tunnel View, Glacier Point and the trails off Glacier Point Road show the valley from three heights. Glacier Point Road closes to cars in winter, so from November to late May this chapter shrinks to the valley floor.",
        "Sunset belongs to Tunnel View and Taft Point; Glacier Point works from late afternoon into the blue hour."
      ]
    }
  }
}
```

Response 201:

```json
{
  "collectionId": "kn73r7x6mp88mxa9swcbshwd3e7zvr39",
  "productId": "j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2",
  "name": "Yosemite",
  "slug": "yosemite",
  "description": "Granite walls and the valley from above",
  "kind": "chapter",
  "body": [
    "Tunnel View, Glacier Point and the trails off Glacier Point Road show the valley from three heights. Glacier Point Road closes to cars in winter, so from November to late May this chapter shrinks to the valley floor.",
    "Sunset belongs to Tunnel View and Taft Point; Glacier Point works from late afternoon into the blue hour."
  ],
  "intro": null,
  "order": 3072,
  "coverUrl": null,
  "coverStorageId": null,
  "members": [],
  "createdAt": 1789895640000,
  "updatedAt": 1789895640000
}
```

### A collection: a plain set of spots (the default kind)

```bash
curl -X POST "https://sceniq.earth/api/v1/guides/j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2/chapters" \
  -H "Authorization: Bearer $SCENIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Top picks",
  "description": "If you only have a day in each park"
}'
```

MCP `tools/call`:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "create_chapter",
    "arguments": {
      "productId": "j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2",
      "name": "Top picks",
      "description": "If you only have a day in each park"
    }
  }
}
```

Response 201:

```json
{
  "collectionId": "kn7a2s4d6f8g0h2j4k6k8z0x2c4v6b8n",
  "productId": "j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2",
  "name": "Top picks",
  "slug": null,
  "description": "If you only have a day in each park",
  "kind": "collection",
  "body": [],
  "intro": null,
  "order": 4096,
  "coverUrl": null,
  "coverStorageId": null,
  "members": [],
  "createdAt": 1789895640000,
  "updatedAt": 1789895640000
}
```

## Errors

- `invalid_argument` (400): A required field is missing, a field is unknown, or a value does not match its type (the Convex validator's path and value are in the message).
- `invalid_request` (400): A writer refused a value: a map link on a host that is not allowed, a title that is too long, a date that does not exist, too many items in a list. The message is the writer's own sentence.
- `unauthenticated` (401): The request carries no key. Send it as Authorization: Bearer sk_sceniq_... (or X-Api-Key).
- `invalid_api_key` (401): The key is unknown, revoked or expired.
- `api_scope_required` (403): A read-only key called a write operation, or a key without the publish option called publish_changes.
- `forbidden` (403): The key belongs to a creator account that is no longer active.
- `not_found` (404): The id does not exist or belongs to another creator. The two answers are identical on purpose, so ids never reveal what exists.
- `payload_too_large` (413): A JSON body over 2 MB, an image over 6 MB, a batch upload over 19 MB, or an MCP message over 2 MB.
- `rate_limited` (429): Over a limit: requests per key per minute, per creator per hour, uploads per key per minute, or check_links per guide per hour.
- `internal_error` (500): An unexpected failure. The message is hidden on purpose.

Reference: https://developers.sceniq.earth/reference/create_chapter
