create_itinerary

Start a trip with one empty day and its trip fields.

POST/v1/guides/{productId}/itineraries
MCP tool create_itineraryScope: writeBetaSince 2026-10-06.3
Markdown

Create once spots, routes and helpers exist. At most 50 itineraries per guide, archived ones included. The new trip starts with one empty day; write its full days with set_itinerary_days next. Trip fields and the cover are checked atomically. The reply is the stored, normalized row. The whole itinerary must fit 100000 JSON characters.

curl -X POST "https://sceniq.earth/api/v1/guides/j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2/itineraries" \
  -H "Authorization: Bearer $SCENIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Yellowstone over two days",
  "description": "Thermal colors, a night at Old Faithful and first light in Lamar Valley.",
  "body": "Book the inn ahead. Check road conditions and keep wildlife at a distance.",
  "coverMediaId": "kg71s3d5f7g9h1j3k5k7z9x1c3v5b7n9",
  "travelMode": "car",
  "season": {
    "months": [
      6,
      7,
      8,
      9
    ],
    "note": "Check the park road status before setting out."
  },
  "startsAt": "Old Faithful",
  "endsAt": "Lamar Valley"
}'

Path parameters

Body parameters

  • namestringrequired

    Trip name, required when sent, at most 120 characters. Cannot be empty.

  • bodystringoptional

    Before you go: who the trip suits, what to book and the pace, at most 5000 characters. Empty string clears.

  • coverMediaIdstring · photo idoptional

    Optional photo of this guide, from list_media. Omit for no cover; null is not accepted on create.

  • descriptionstringoptional

    Short description, at most 300 characters. Empty string clears.

  • endsAtstringoptional

    Where the trip ends, in words, at most 120 characters. Empty string clears.

  • seasonItinerarySeasonoptional

    Optional months and a season note. Omit when unknown; null is not accepted on create.

    Show 2 fieldsof ItinerarySeason
    • monthsarray of numbersoptional

      Optional month numbers, 1 to 12. Stored sorted with duplicates removed; [] drops.

    • notestringoptional

      Optional season note, at most 300 characters. Empty text drops.

  • startsAtstringoptional

    Where the trip starts, in words, at most 120 characters. Empty string clears.

  • travelModestringoptional

    Optional getting around on the whole trip: car, public_transport, campervan, bike, on_foot, boat, mixed. Omit when unknown; null is not accepted on create.

    carpublic_transportcampervanbikeon_footboatmixed

Returns

201 Created with ItineraryWrite: A stored itinerary after a write, with optional warnings.

  • itineraryIdstring · itineraries idrequired

    The itinerary's id.

  • productIdstring · guide idrequired

    The guide's id.

  • namestringrequired

    The trip's name.

  • descriptionstring or nullrequired

    Short description, or null when empty.

  • bodystring or nullrequired

    Before you go: the creator's trip notes, or null.

  • coverMediaIdstring or null · photo idrequired

    A photo of this guide, or null for no cover.

  • travelModestring or nullrequired

    How to get around on the whole trip, or null when unknown.

    carpublic_transportcampervanbikeon_footboatmixed
  • seasonItinerarySeason or nullrequired

    Months and a season note, or null when unset.

    Show 2 fieldsof ItinerarySeason
    • monthsarray of numbersoptional

      Optional month numbers, 1 to 12. Stored sorted with duplicates removed; [] drops.

    • notestringoptional

      Optional season note, at most 300 characters. Empty text drops.

  • startsAtstring or nullrequired

    Where the trip starts, in words, or null.

  • endsAtstring or nullrequired

    Where the trip ends, in words, or null.

  • daysarray of ItineraryDayrequired

    The days exactly as stored, with absent optional fields and no nulls inside. Edit this array and send it straight to set_itinerary_days.

    Show 4 fieldsof ItineraryDay
    • titlestringoptional

      Optional day title, at most 120 characters. Empty text drops.

    • notestringoptional

      Optional day note, at most 2000 characters. Empty text drops.

    • stopsarray of ItineraryStoprequired

      Ordered stops, 0 to 40, with no stop ids.

    • overnightItineraryOvernightoptional

      Where to sleep: a stay of this guide, words, or both, plus a note.

      Show 3 fieldsof ItineraryOvernight
      • facilityIdstringoptional

        Optional facilityId from list_facilities: a stay's helper spotId, or an id from before 2026-10-04 that still resolves. Must be a stay of this guide (kind hut or hut in extraKinds).

      • namestringoptional

        Optional place in words, at most 120 characters. Can accompany a stay id or stand alone.

      • notestringoptional

        Optional overnight note, at most 1000 characters. Empty text drops.

  • ordernumberrequired

    Position in the guide, ascending and fractional.

  • archivedbooleanrequired

    true hides this itinerary from buyers and keeps it editable.

  • createdAtnumberrequired

    When the row was created (Unix time in milliseconds).

  • updatedAtnumberrequired

    When the row last changed (Unix time in milliseconds).

  • warningsarray of stringsoptional

    Notes about things the write accepted but you should look at (a plain http link). Present only when there are any.

Response 201
{
  "itineraryId": "ki7a2c4e6g8j0m2p4s6v8y0b2d4f6h8k",
  "productId": "j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2",
  "name": "Yellowstone over two days",
  "description": "Thermal colors, a night at Old Faithful and first light in Lamar Valley.",
  "body": "Book the inn ahead. Check road conditions and keep wildlife at a distance.",
  "coverMediaId": "kg71s3d5f7g9h1j3k5k7z9x1c3v5b7n9",
  "travelMode": "car",
  "season": {
    "months": [
      6,
      7,
      8,
      9
    ],
    "note": "Check the park road status before setting out."
  },
  "startsAt": "Old Faithful",
  "endsAt": "Lamar Valley",
  "days": [
    {
      "stops": []
    }
  ],
  "order": 1024,
  "archived": false,
  "createdAt": 1790673240000,
  "updatedAt": 1790673240000
}

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.
  • 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.