# save_sales_page_draft

Save the sales page draft (never publishes).

`PUT /v1/guides/{productId}/sales-page/draft` · MCP tool `save_sales_page_draft` · scope `write` · stable · since 2026-09-17

Full-replacement draftConfig with the fixed sections: hero (carousel of listing/product media ids, title, 2-6 bullets), pitch boxes, reviews (custom testimonials only with the creator's real quotes), gallery, aboutCreator, buyForm, faq. Media ids must be product- or listing-owned. Copy must never promise updates. The creator publishes the sales page in the dashboard; publish_changes does not touch it.

## Path parameters

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

## Body parameters

- `draftConfig` (ListingConfig, required): The complete ListingConfig object (read get_sales_page first and edit that).
  Fields of ListingConfig: https://developers.sceniq.earth/fields/listing-config.md
- `expectedUpdatedAt` (number, optional): Optional staleness guard: the listing updatedAt you last read.

## Returns

200.

- `ok` (boolean, required): Always true: the write went through. Always `true`.
- `productId` (string, required): The guide's id.
- `saved` (string, required): Always draft: the creator publishes the sales page. Always `"draft"`.

## Examples

### Save the whole draft, guarded against an edit made elsewhere since the last read

```bash
curl -X PUT "https://sceniq.earth/api/v1/guides/j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2/sales-page/draft" \
  -H "Authorization: Bearer $SCENIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "draftConfig": {
    "hero": {
      "carousel": [
        {
          "mediaId": "kg7q8w6e4r2t0y8v6j4p2p0a8s6d4f2g",
          "order": 1024
        },
        {
          "mediaId": "kg7t5y7v9j1p3p5a7s9d1f3g5h7j9k1k",
          "caption": "Tunnel View, Yosemite, at first light",
          "order": 2048
        },
        {
          "mediaId": "kg7b4n6m8q0w2e4r6t8y0v2j4p6p8a0s",
          "order": 3072
        }
      ],
      "title": "American West: Parks at First Light",
      "headline": "Twelve viewpoints across Yellowstone and Yosemite, timed for the light and the crowds.",
      "kicker": "A map guide by Mara Lindgren",
      "bullets": [
        {
          "text": "Twelve viewpoints in Yellowstone and Yosemite, each with an exact pin",
          "order": 1
        },
        {
          "text": "The best hour for every view, and when the crowds arrive",
          "order": 2
        },
        {
          "text": "Trailheads, parking and the time each lot fills",
          "order": 3
        },
        {
          "text": "Fees, opening hours and closures checked in September 2026",
          "order": 4
        }
      ]
    },
    "pitch": {
      "enabled": true,
      "title": "Built for the hour you are there",
      "description": "Every spot says when to arrive, where to park and how long the walk takes, so the good light finds you at the viewpoint, not in the parking lot.",
      "imageAspect": "4:5",
      "boxes": [
        {
          "mediaId": "kg7b4n6m8q0w2e4r6t8y0v2j4p6p8a0s",
          "title": "One map for both parks",
          "description": "Pins for every viewpoint, trailhead and lot, in the Sceniq app and in your browser.",
          "order": 1
        },
        {
          "mediaId": "kg7q8w6e4r2t0y8v6j4p2p0a8s6d4f2g",
          "title": "Timed for the light",
          "description": "Grand Prismatic mid morning once the steam lifts, Tunnel View at first light.",
          "order": 2
        },
        {
          "title": "Parking that works",
          "description": "Which lot to use, when it fills, and where to go when it does.",
          "order": 3
        }
      ]
    },
    "reviews": {
      "enabled": true,
      "source": "product",
      "heading": "What buyers say"
    },
    "gallery": {
      "enabled": false,
      "slides": []
    },
    "aboutCreator": {
      "enabled": true
    },
    "buyForm": {
      "ctaLabel": "Get the guide",
      "reassuranceText": "One payment. Open it in the Sceniq app or in your browser.",
      "imageMediaId": "kg7t5y7v9j1p3p5a7s9d1f3g5h7j9k1k"
    },
    "faq": {
      "enabled": true,
      "title": "Common questions",
      "items": [
        {
          "question": "Do I need a car?",
          "answer": "Yes. Every spot lists where to park, how early the lot fills and how long the walk is from there.",
          "order": 1
        },
        {
          "question": "Does the guide work without signal?",
          "answer": "Download it in the Sceniq app before you go. The map, the spots and the photos then open without signal, which most of these viewpoints do not have.",
          "order": 2
        },
        {
          "question": "When should I go?",
          "answer": "Late May to September for both parks. Each spot lists its best months and the hour it looks its best.",
          "order": 3
        }
      ]
    }
  },
  "expectedUpdatedAt": 1790241240000
}'
```

MCP `tools/call`:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "save_sales_page_draft",
    "arguments": {
      "productId": "j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2",
      "draftConfig": {
        "hero": {
          "carousel": [
            {
              "mediaId": "kg7q8w6e4r2t0y8v6j4p2p0a8s6d4f2g",
              "order": 1024
            },
            {
              "mediaId": "kg7t5y7v9j1p3p5a7s9d1f3g5h7j9k1k",
              "caption": "Tunnel View, Yosemite, at first light",
              "order": 2048
            },
            {
              "mediaId": "kg7b4n6m8q0w2e4r6t8y0v2j4p6p8a0s",
              "order": 3072
            }
          ],
          "title": "American West: Parks at First Light",
          "headline": "Twelve viewpoints across Yellowstone and Yosemite, timed for the light and the crowds.",
          "kicker": "A map guide by Mara Lindgren",
          "bullets": [
            {
              "text": "Twelve viewpoints in Yellowstone and Yosemite, each with an exact pin",
              "order": 1
            },
            {
              "text": "The best hour for every view, and when the crowds arrive",
              "order": 2
            },
            {
              "text": "Trailheads, parking and the time each lot fills",
              "order": 3
            },
            {
              "text": "Fees, opening hours and closures checked in September 2026",
              "order": 4
            }
          ]
        },
        "pitch": {
          "enabled": true,
          "title": "Built for the hour you are there",
          "description": "Every spot says when to arrive, where to park and how long the walk takes, so the good light finds you at the viewpoint, not in the parking lot.",
          "imageAspect": "4:5",
          "boxes": [
            {
              "mediaId": "kg7b4n6m8q0w2e4r6t8y0v2j4p6p8a0s",
              "title": "One map for both parks",
              "description": "Pins for every viewpoint, trailhead and lot, in the Sceniq app and in your browser.",
              "order": 1
            },
            {
              "mediaId": "kg7q8w6e4r2t0y8v6j4p2p0a8s6d4f2g",
              "title": "Timed for the light",
              "description": "Grand Prismatic mid morning once the steam lifts, Tunnel View at first light.",
              "order": 2
            },
            {
              "title": "Parking that works",
              "description": "Which lot to use, when it fills, and where to go when it does.",
              "order": 3
            }
          ]
        },
        "reviews": {
          "enabled": true,
          "source": "product",
          "heading": "What buyers say"
        },
        "gallery": {
          "enabled": false,
          "slides": []
        },
        "aboutCreator": {
          "enabled": true
        },
        "buyForm": {
          "ctaLabel": "Get the guide",
          "reassuranceText": "One payment. Open it in the Sceniq app or in your browser.",
          "imageMediaId": "kg7t5y7v9j1p3p5a7s9d1f3g5h7j9k1k"
        },
        "faq": {
          "enabled": true,
          "title": "Common questions",
          "items": [
            {
              "question": "Do I need a car?",
              "answer": "Yes. Every spot lists where to park, how early the lot fills and how long the walk is from there.",
              "order": 1
            },
            {
              "question": "Does the guide work without signal?",
              "answer": "Download it in the Sceniq app before you go. The map, the spots and the photos then open without signal, which most of these viewpoints do not have.",
              "order": 2
            },
            {
              "question": "When should I go?",
              "answer": "Late May to September for both parks. Each spot lists its best months and the hour it looks its best.",
              "order": 3
            }
          ]
        }
      },
      "expectedUpdatedAt": 1790241240000
    }
  }
}
```

Response 200:

```json
{
  "ok": true,
  "productId": "j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2",
  "saved": "draft"
}
```

## 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.
- `stale_editor` (409): The row changed after the expectedUpdatedAt you sent (update_chapter, save_sales_page_draft).
- `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/save_sales_page_draft
