set_chapter_pages

Replace a chapter's ordered page stack.

PUT/v1/chapters/{collectionId}/pages
MCP tool set_chapter_pagesScope: writeBetaSince 2026-10-06.2
Markdown

Full replacement, chapters only. Send all desired pages in reading order, at most 40. Fields unused by the page type are dropped; invalid variants or refs are refused. Missing and changed-kind targets, self Contents refs and removed photos are dropped silently. Other-guide ids are not_found; product- or listing-owned photos are invalid_request. Unused chapter-owned photos are released when no other chapter uses them. Legacy intro and body are cleared. The reply includes the pages as stored.

curl -X PUT "https://sceniq.earth/api/v1/chapters/kn7q65ntqkryzm6y45h5dyxqt0p454y8/pages" \
  -H "Authorization: Bearer $SCENIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "pages": [
    {
      "id": "page0001",
      "type": "cover",
      "variant": "split",
      "kicker": "A photographer'\''s field guide",
      "title": "US National Parks",
      "byline": true,
      "photos": [
        {
          "mediaId": "kg7d6v4r2t8y0w6q4p2n8m0k6j4h2g8f"
        }
      ]
    },
    {
      "id": "page0002",
      "type": "text",
      "kicker": "How to use this guide",
      "title": "Timed for the light",
      "body": [
        "Each spot lists its best time of day, how crowded it gets and how far it is from the car. Most are short walks; the hikes are marked.",
        "- One day per park? Start with Top picks.\n- Check the park road status before a sunrise drive."
      ]
    },
    {
      "id": "page0003",
      "type": "gallery",
      "title": "From the parks",
      "photos": [
        {
          "mediaId": "kg71s3d5f7g9h1j3k5k7z9x1c3v5b7n9",
          "caption": "Grand Prismatic Spring"
        },
        {
          "mediaId": "kg7p2p4j6v8y0t2r4e6w8q0a2s4d6f8g",
          "caption": "Midway Geyser Basin"
        },
        {
          "mediaId": "kg7m9n1b3v5c7x9z1k3k5j7h9g1f3d5s",
          "caption": "Tunnel View"
        }
      ]
    },
    {
      "id": "page0004",
      "type": "spots",
      "variant": "reader",
      "refs": [
        {
          "spotKey": "01M2Z1G0Y0QG7M2V6N9R3T5W8Y"
        },
        {
          "spotKey": "01M2Z1G0Y0R2K5P8S1V4X7Z0C3"
        }
      ]
    }
  ],
  "expectedUpdatedAt": 1789895640000
}'

Path parameters

  • collectionIdstring · chapter idrequired

    Id of a chapter from list_chapters. Plain collections refuse pages.

Body parameters

  • pagesarray of ChapterPagerequired

    Complete ordered ChapterPage array, up to 40 pages and 150,000 JSON characters after normalisation. [] clears the stack. Every page field other than id and type is optional; empty pages are valid.

    Show 13 fieldsof ChapterPage
    • idstringrequired

      Stable client-made identity: 8 to 16 letters, digits, underscores or hyphens, unique within the stack. Trimmed on save. Keep ids when editing or reordering; make a new id when duplicating.

    • typestringrequired

      cover: opening with title, photo and optional byline (kicker/title/lead/byline/author/authorMediaId/photos). text: paragraphs (kicker/title/lead/body). photoText: a photo beside paragraphs (kicker/title/lead/body/photos). photo: a big image (title/lead/photos). gallery: image grid (kicker/title/lead/photos with captions). quote: quotation (body/author/authorMediaId/photos). tips: numbered cards (kicker/title/lead/items title and text). checklist: lines (kicker/title/lead/items title only). facts: label/value table (kicker/title/lead/items title and text). chapters: Contents rows (kicker/title/lead/refs collectionId/title/line/color/hidden). collections: collection cards (kicker/title/lead/refs collectionId/title/mediaId/hidden). itineraries: trip tiles (kicker/title/lead/refs itineraryId/hidden). spots: chosen spot cards (kicker/title/lead/refs spotKey). creator: About me (kicker/title/body/photos), with socials from the creator profile. Other fields are dropped.

      covertextphotoTextphotogalleryquotetipschecklistfactschapterscollectionsitinerariesspotscreator
    • variantstringoptional

      cover: split (default), full, simple; photoText: left (default), right; photo: overlay (default), below; quote: plain (default), photo; spots: reader (default), grid; creator: profile (default), portrait. An invalid variant for these types is refused. Other types have no variants and drop this field.

    • kickerstringoptional

      Small heading line, at most 120 characters. Used by cover, text, photoText, gallery, tips, checklist, facts, chapters, collections, itineraries, spots and creator.

    • titlestringoptional

      Heading, at most 160 characters. Used by every type except quote. Empty cover title uses the chapter name; creator title overrides the profile name.

    • leadstringoptional

      Short introduction, at most 500 characters. Used by every type except quote and creator. Spots shows a heading only when kicker, title or lead has text.

    • bodyarray of stringsoptional

      text/photoText paragraphs, quote text or creator bio override: up to 30 strings of 10000 characters. Lines beginning with "- " render as dotted lists. Other types drop body.

    • bylinebooleanoptional

      Cover only: true shows the author and round photo. false is dropped. Empty author and authorMediaId use the current creator name and avatar.

    • authorstringoptional

      Cover byline or quote attribution, at most 120 characters. Other types drop it.

    • authorMediaIdstring · photo idoptional

      Cover or quote author photo: a media row id owned by this chapter or a spot/collection of this guide. Removed photos are dropped; other-guide ids are refused. Other page types drop it.

    • photosarray of ChapterPagePhotooptional

      cover/photoText/photo/quote/creator accept at most one photo; gallery accepts up to 6. Other types drop photos. Only gallery keeps captions. Upload with ownerType collection and ownerId collectionId, or reuse a spot photo mediaId from list_media. Photos retain the media row's credit; its display follows guide settings and licence requirements.

      Show 2 fieldsof ChapterPagePhoto
      • mediaIdstring · photo idrequired

        A spot- or collection-owned media id of this guide. Upload chapter photos with ownerType collection and ownerId collectionId, then reference mediaId. Product and listing owners are refused. No copy is made when reusing a spot photo.

      • captionstringoptional

        Gallery only: optional caption, at most 200 characters. Other page types drop it. Credit belongs to the media row, not this caption.

    • itemsarray of ChapterPageItemoptional

      tips: up to 8 title/text cards; checklist: up to 20 title-only lines; facts: up to 12 title (label)/text (value) rows. Empty items are dropped; other types drop items.

      Show 2 fieldsof ChapterPageItem
      • titlestringoptional

        Tip title, checklist line or fact label, at most 120 characters.

      • textstringoptional

        Tip text or fact value, at most 600 characters. Checklist drops it.

    • refsarray of ChapterPageRefoptional

      chapters/collections/itineraries accept up to 60/60/60 per-item overrides. They list the guide's eligible rows by themselves, not just refs. spots accepts zero to 12 spotKeys in display order. Each ref must carry exactly the target its type accepts; unsupported dressing is refused. Duplicate targets keep the first. Missing targets are dropped; archived spots stay stored and buyers hide them. Other types drop refs.

      Show 8 fieldsof ChapterPageRef
      • collectionIdstring · chapter idoptional

        chapters: another chapter of this guide (self refs drop). collections: a plain collection of this guide. Required for these types only. A target promoted or demoted to the wrong kind is dropped.

      • itineraryIdstring · itineraries idoptional

        itineraries only: itinerary of this guide. Required for that type; missing rows drop.

      • spotKeystringoptional

        spots only: key from list_spots, required for that type. Up to 12, in display order. Unknown keys drop; archived spots are hidden from buyers.

      • titlestringoptional

        chapters or collections only: row/card name override, at most 120 characters. Empty means the target's name.

      • linestringoptional

        chapters only: row description override, at most 200 characters. Empty means the chapter's description.

      • colorstringoptional

        chapters only: row color bar in #rrggbb format, stored lower case. Absent uses the chapter art.

      • mediaIdstring · photo idoptional

        collections only: card photo override, a spot- or collection-owned media row of this guide. Missing media is unset on save. Empty uses the collection art.

      • hiddenbooleanoptional

        chapters/collections/itineraries only: true hides the item on this page. false is dropped. Does not hide it elsewhere or change membership.

  • expectedUpdatedAtnumberoptional

    Optional staleness guard: the chapter's updatedAt you last read (list_chapters). The write is refused with stale_editor when the chapter changed since.

Returns

200 OK with this object.

  • okbooleanrequired

    Always true: the write went through.

    Always true

  • collectionIdstring · chapter idrequired

    The chapter's or collection's id.

  • updatedAtnumberrequired

    The stored chapter revision in epoch milliseconds. Use it as expectedUpdatedAt for the next write.

  • pagesarray of ChapterPagerequired

    The normalised pages stored by this replacement, including silent removal of stale refs and photos.

    Show 13 fieldsof ChapterPage
    • idstringrequired

      Stable client-made identity: 8 to 16 letters, digits, underscores or hyphens, unique within the stack. Trimmed on save. Keep ids when editing or reordering; make a new id when duplicating.

    • typestringrequired

      cover: opening with title, photo and optional byline (kicker/title/lead/byline/author/authorMediaId/photos). text: paragraphs (kicker/title/lead/body). photoText: a photo beside paragraphs (kicker/title/lead/body/photos). photo: a big image (title/lead/photos). gallery: image grid (kicker/title/lead/photos with captions). quote: quotation (body/author/authorMediaId/photos). tips: numbered cards (kicker/title/lead/items title and text). checklist: lines (kicker/title/lead/items title only). facts: label/value table (kicker/title/lead/items title and text). chapters: Contents rows (kicker/title/lead/refs collectionId/title/line/color/hidden). collections: collection cards (kicker/title/lead/refs collectionId/title/mediaId/hidden). itineraries: trip tiles (kicker/title/lead/refs itineraryId/hidden). spots: chosen spot cards (kicker/title/lead/refs spotKey). creator: About me (kicker/title/body/photos), with socials from the creator profile. Other fields are dropped.

      covertextphotoTextphotogalleryquotetipschecklistfactschapterscollectionsitinerariesspotscreator
    • variantstringoptional

      cover: split (default), full, simple; photoText: left (default), right; photo: overlay (default), below; quote: plain (default), photo; spots: reader (default), grid; creator: profile (default), portrait. An invalid variant for these types is refused. Other types have no variants and drop this field.

    • kickerstringoptional

      Small heading line, at most 120 characters. Used by cover, text, photoText, gallery, tips, checklist, facts, chapters, collections, itineraries, spots and creator.

    • titlestringoptional

      Heading, at most 160 characters. Used by every type except quote. Empty cover title uses the chapter name; creator title overrides the profile name.

    • leadstringoptional

      Short introduction, at most 500 characters. Used by every type except quote and creator. Spots shows a heading only when kicker, title or lead has text.

    • bodyarray of stringsoptional

      text/photoText paragraphs, quote text or creator bio override: up to 30 strings of 10000 characters. Lines beginning with "- " render as dotted lists. Other types drop body.

    • bylinebooleanoptional

      Cover only: true shows the author and round photo. false is dropped. Empty author and authorMediaId use the current creator name and avatar.

    • authorstringoptional

      Cover byline or quote attribution, at most 120 characters. Other types drop it.

    • authorMediaIdstring · photo idoptional

      Cover or quote author photo: a media row id owned by this chapter or a spot/collection of this guide. Removed photos are dropped; other-guide ids are refused. Other page types drop it.

    • photosarray of ChapterPagePhotooptional

      cover/photoText/photo/quote/creator accept at most one photo; gallery accepts up to 6. Other types drop photos. Only gallery keeps captions. Upload with ownerType collection and ownerId collectionId, or reuse a spot photo mediaId from list_media. Photos retain the media row's credit; its display follows guide settings and licence requirements.

      Show 2 fieldsof ChapterPagePhoto
      • mediaIdstring · photo idrequired

        A spot- or collection-owned media id of this guide. Upload chapter photos with ownerType collection and ownerId collectionId, then reference mediaId. Product and listing owners are refused. No copy is made when reusing a spot photo.

      • captionstringoptional

        Gallery only: optional caption, at most 200 characters. Other page types drop it. Credit belongs to the media row, not this caption.

    • itemsarray of ChapterPageItemoptional

      tips: up to 8 title/text cards; checklist: up to 20 title-only lines; facts: up to 12 title (label)/text (value) rows. Empty items are dropped; other types drop items.

      Show 2 fieldsof ChapterPageItem
      • titlestringoptional

        Tip title, checklist line or fact label, at most 120 characters.

      • textstringoptional

        Tip text or fact value, at most 600 characters. Checklist drops it.

    • refsarray of ChapterPageRefoptional

      chapters/collections/itineraries accept up to 60/60/60 per-item overrides. They list the guide's eligible rows by themselves, not just refs. spots accepts zero to 12 spotKeys in display order. Each ref must carry exactly the target its type accepts; unsupported dressing is refused. Duplicate targets keep the first. Missing targets are dropped; archived spots stay stored and buyers hide them. Other types drop refs.

      Show 8 fieldsof ChapterPageRef
      • collectionIdstring · chapter idoptional

        chapters: another chapter of this guide (self refs drop). collections: a plain collection of this guide. Required for these types only. A target promoted or demoted to the wrong kind is dropped.

      • itineraryIdstring · itineraries idoptional

        itineraries only: itinerary of this guide. Required for that type; missing rows drop.

      • spotKeystringoptional

        spots only: key from list_spots, required for that type. Up to 12, in display order. Unknown keys drop; archived spots are hidden from buyers.

      • titlestringoptional

        chapters or collections only: row/card name override, at most 120 characters. Empty means the target's name.

      • linestringoptional

        chapters only: row description override, at most 200 characters. Empty means the chapter's description.

      • colorstringoptional

        chapters only: row color bar in #rrggbb format, stored lower case. Absent uses the chapter art.

      • mediaIdstring · photo idoptional

        collections only: card photo override, a spot- or collection-owned media row of this guide. Missing media is unset on save. Empty uses the collection art.

      • hiddenbooleanoptional

        chapters/collections/itineraries only: true hides the item on this page. false is dropped. Does not hide it elsewhere or change membership.

Response 200
{
  "ok": true,
  "collectionId": "kn7q65ntqkryzm6y45h5dyxqt0p454y8",
  "updatedAt": 1790586840000,
  "pages": [
    {
      "id": "page0001",
      "type": "cover",
      "variant": "split",
      "kicker": "A photographer's field guide",
      "title": "US National Parks",
      "byline": true,
      "photos": [
        {
          "mediaId": "kg7d6v4r2t8y0w6q4p2n8m0k6j4h2g8f"
        }
      ]
    },
    {
      "id": "page0002",
      "type": "text",
      "kicker": "How to use this guide",
      "title": "Timed for the light",
      "body": [
        "Each spot lists its best time of day, how crowded it gets and how far it is from the car. Most are short walks; the hikes are marked.",
        "- One day per park? Start with Top picks.\n- Check the park road status before a sunrise drive."
      ]
    },
    {
      "id": "page0003",
      "type": "gallery",
      "title": "From the parks",
      "photos": [
        {
          "mediaId": "kg71s3d5f7g9h1j3k5k7z9x1c3v5b7n9",
          "caption": "Grand Prismatic Spring"
        },
        {
          "mediaId": "kg7p2p4j6v8y0t2r4e6w8q0a2s4d6f8g",
          "caption": "Midway Geyser Basin"
        },
        {
          "mediaId": "kg7m9n1b3v5c7x9z1k3k5j7h9g1f3d5s",
          "caption": "Tunnel View"
        }
      ]
    },
    {
      "id": "page0004",
      "type": "spots",
      "variant": "reader",
      "refs": [
        {
          "spotKey": "01M2Z1G0Y0QG7M2V6N9R3T5W8Y"
        },
        {
          "spotKey": "01M2Z1G0Y0R2K5P8S1V4X7Z0C3"
        }
      ]
    }
  ]
}

Errors

Every error is { error: { code, message } }. Act on the code.

  • 400invalid_argumentA 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).
  • 400invalid_requestA 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.
  • 409stale_editorThe row changed after the expectedUpdatedAt you sent (update_chapter, set_chapter_pages, update_itinerary, set_itinerary_days, save_sales_page_draft).
  • 401unauthenticatedThe request carries no key. Send it as Authorization: Bearer sk_sceniq_... (or X-Api-Key).
  • 401invalid_api_keyThe key is unknown, revoked or expired.
  • 403api_scope_requiredA read-only key called a write operation, or a key without the publish option called publish_changes.
  • 403forbiddenThe key belongs to a creator account that is no longer active.
  • 404not_foundThe id does not exist or belongs to another creator. The two answers are identical on purpose, so ids never reveal what exists.
  • 413payload_too_largeA JSON body over 2 MB, an image over 6 MB, a batch upload over 19 MB, or an MCP message over 2 MB.
  • 429rate_limitedOver a limit: requests per key per minute, per creator per hour, uploads per key per minute, or check_links per guide per hour.
  • 500internal_errorAn unexpected failure. The message is hidden on purpose.