# create_spot

Add a spot (a place the creator has been to).

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

Coordinates come from the creator (their map link, GPX, or a pin they confirm) or, for a guide the creator asked you to research, from a source you cite in sources; never from memory. Leave lat/lon empty rather than guessing; the readiness check will list what is missing. Titles are place names as locals know them; kicker is the short line above the title (region, type). customValues keys must match list_properties; option values use option ids, not labels. create_spot takes every field update_spot takes (arrival, mapLinks, tripFacts, accessMode, pins, links, status, fees, schedule and the rest), so one call makes a complete spot. For many spots, or re-runs that must not duplicate, use upsert_spots. The response carries warnings (an http link) that did not stop the write.

## Path parameters

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

## Body parameters

- `title` (string, required): Place name as locals know it, e.g. Oeschinensee or Fushimi Inari-taisha. Cannot be empty.
- `accessMode` (string or null, optional): How visitors reach the spot, shown as Accessibility: drive_up, short_walk, hike, multi_day, boat, cable_car, train, flight, tour_only, aerial_only. null clears. Without it the cell shows the easiest required route's grade, or Drive-up only when arrival.byCar describes a drive. One of `drive_up`, `short_walk`, `hike`, `multi_day`, `boat`, `cable_car`, `train`, `flight`, `tour_only`, `aerial_only`.
- `areaId` (string, optional): The area (park, island, region) the spot sits in, from set_area; its rules, fees and links show on the spot. Empty string clears.
- `arrival` (Arrival or null, optional): How to get there, full replacement, null clears: { byCar?: { directions, parking, walkToSpotMin, walkRoundTrip? (the minutes are there and back), none? (no car access), note? }, byTrainBus?: { route, walkFromStopMin, walkRoundTrip?, none? (no public transport, which reads differently from an empty field), note? }, byBoat?, byAir?: { airports? (IATA or ICAO codes), route?, minutes?, operatorUrl?, luggageKg?, none?, note? }, onFoot?: { route?, minutes?, roundTrip?, none?, note? }, byBike?: { same }, bestTime?, operating?, approaches?: [{ label (Argentine side), country? (AR), legs?: [{ mode: car|bus|train|tram|metro|cable_car|funicular|boat|ferry|plane|helicopter|shuttle|jeep|walk|bike|taxi|other, from?, to?, minutes?, roundTrip?, price?, payment?, note? }], hours?, entry?, note?, lat?, lon? }] (at most 6, for spots with several ways in or chains of legs), rules?: [{ text, kind?: reservation|permit|guide|registration|no_independent_travel|vehicle|other, months? [1-12] (shown only then), appliesTo?: car|all, bookingOpens?, sourceUrl? }] }.
  Fields of Arrival: https://developers.sceniq.earth/fields/arrival.md
- `cardOrientation` (string, optional): portrait or landscape (photo framing in the viewer); a spot without one reads as landscape. One of `portrait`, `landscape`.
- `color` (string, optional): Optional pin color hex, e.g. #0071e3. Empty string clears.
- `customNotes` (map of strings, optional): One short note per custom property value, keyed by property key, shown next to the value (walls 40 EUR, morning from viewpoint 7). Full replacement ({} clears).
- `customPropsEnabled` (boolean, optional): false hides custom properties from buyers; values stay stored.
- `customValues` (map of values, optional): Object keyed by property key (list_properties): text for shortLabel and longSection, a number for number, epoch ms for date, one option id for singleSelect, an array of option ids for checkbox (ids, never labels). Every required property needs a value; keys without a live property are kept unchecked. Sent for an existing spot it replaces the stored object; null for a key clears that value.
- `events` (array of SpotEvent, optional): Recurring or one-off events worth timing a visit for, full replacement, at most 12: [{ name, when (in words: every night at 19:45 and 20:45), dates? [YYYY-MM-DD] (the apps show the next one), months?, url?, free?, note? }].
  Fields of SpotEvent: https://developers.sceniq.earth/fields/spot-event.md
- `factsCheckedOn` (string, optional): The day the facts were last checked against their sources (YYYY-MM-DD). Empty string clears.
- `features` (array of SpotFeature, optional): Parts of the site with their own rules (a monastery's closing day, a ticketed skyway), full replacement, at most 12: [{ name, note?, hours?, entry?, season?, fees? (as fees), status? (as status), url? }].
  Fields of SpotFeature: https://developers.sceniq.earth/fields/spot-feature.md
- `fees` (array of Fee, optional): Fees and tickets, full replacement ([] clears), at most 30: [{ label, amount? (major units, e.g. 40 or 12.5; needs currency), currency? (EUR), free?, seeOfficial? (a price left to the official page on purpose), per?: person|vehicle|night|group|entry|day|hour, audience?: all|adult|child|foreign|domestic|resident|student|senior, paidWhere?: online|on_site|in_tour, payment?: cash_only|card_only|cash_or_card, note?, validFrom?, validUntil?, sourceUrl?, checkedOn? }]. Buyers see the amount with an as-of date; readiness flags rows past validUntil or unchecked for a year.
  Fields of Fee: https://developers.sceniq.earth/fields/fee.md
- `food` (FoodNote or null, optional): Why the spot lists no food places, null clears: { status: included (meals come with the lodge or boat) | none_nearby | bring_your_own, note? }.
  Fields of FoodNote: https://developers.sceniq.earth/fields/food-note.md
- `imagesEnabled` (boolean, optional): false hides the photo section from buyers; photos stay stored.
- `kicker` (string, optional): Short eyebrow above the title, e.g. Patagonia, Bernese Oberland or Glacier lake. Empty string clears.
- `lat` (number, optional): Latitude in decimal degrees (-90 to 90). From the creator's material or a cited source.
- `links` (array of GuideLink, optional): Links with a purpose, full replacement ([] clears), at most 12: [{ kind: official|website|tickets|booking|status|timetable|tide|listing|social|authority|app|other, label?, url? (http or https; http is accepted with a warning), value? (a channel that is not a URL, e.g. WeChat mini program: Li River boats), note? }]. Each needs a url or a value.
  Fields of GuideLink: https://developers.sceniq.earth/fields/guide-link.md
- `lon` (number, optional): Longitude in decimal degrees (-180 to 180).
- `longDescription` (string, optional): The full write-up in the creator's voice. Empty string clears.
- `mapLinks` (array of MapLink, optional): Extra map links [{ label, url }] (https or an allowlisted map link), drawn as map pills. [] clears. For official, ticket or status pages use links instead.
  Fields of MapLink: https://developers.sceniq.earth/fields/map-link.md
- `mapsUrl` (string, optional): The creator's own map link: https on Google Maps, Apple Maps, Swisstopo, OpenStreetMap or SchweizMobil, or a geo: URI. Empty string clears.
- `pinLabel` (string, optional): What the main pin marks for a spot that is an area or a line, shown as Pinned: <label> (Ti Top viewpoint). Empty string clears.
- `pins` (array of SpotPin, optional): Extra points, full replacement ([] clears), at most 12: [{ kind: viewpoint|entrance|gate|trailhead|parking|stop|pier|summit|other, label, lat, lon, months? [1-12] (only reachable then), note? }]. Each gets its own map links and a place on the web map.
  Fields of SpotPin: https://developers.sceniq.earth/fields/spot-pin.md
- `ref` (string, optional): Your own stable key for this spot (af04-abu-simbel), unique in the guide; upsert_spots matches on it. Empty string clears.
- `restrictions` (array of Restriction, optional): Rules on site, full replacement, at most 20: [{ kind: no_photo|wide_only|no_drone|no_entry|no_stopping|no_parking|other, label, note?, lat?, lon?, radiusM?, line? ([[lon, lat], ...] for a stretch of road), sourceUrl? }].
  Fields of Restriction: https://developers.sceniq.earth/fields/restriction.md
- `reviewBy` (string, optional): The day the facts need a new check (YYYY-MM-DD), e.g. when a season, fare or timetable runs out. get_guide_readiness and get_publish_status warn once it has passed. Empty string clears.
- `reviewNotes` (string, optional): Notes for the creator's review (why a value was chosen, what could not be verified). Never shown to buyers; get_guide_readiness lists them. Empty string clears.
- `schedule` (Schedule or null, optional): Structured opening hours, null clears; the free-text hours stay the fallback: { hours?: [{ from? (MM-DD), to? (MM-DD, may wrap over the new year), weekdays? [1-7], closed?, open? (HH:MM or sunrise|sunset), close? (HH:MM or sunrise|sunset), openOffsetMin?, closeOffsetMin? (minutes around a sun anchor, -60 = an hour before), lastEntry? (HH:MM), leaveBy? (HH:MM), note? }], specialDays?: [{ date? or rule? (first Sunday of the month), closed?, open?, close?, note? }], slots?: { first, last, everyMin, cap?, note? }, validFrom?, validUntil?, sourceUrl?, checkedOn?, note? }. The last matching band wins, so list the year-round band first and exceptions after it. The apps show today's hours in the spot's time zone.
  Fields of Schedule: https://developers.sceniq.earth/fields/schedule.md
- `shortDescription` (string, optional): One or two sentences for the card. Empty string clears.
- `siteChange` (SiteChange or null, optional): The day something at the spot changed (a bridge replaced, boats banned), null clears: { on (YYYY-MM-DD), note? }. Readiness flags photos captured before it.
  Fields of SiteChange: https://developers.sceniq.earth/fields/site-change.md
- `sources` (array of SourceRef, optional): Research evidence for reviewers, never shown to buyers; full replacement, at most 40: [{ url? or title?, kind?: page|api|archive|document|other, capturedOn?, note?, supports? (which facts it backs, e.g. fees, arrival.operating, lat/lon), conflict? (true when it disagrees with another source on those facts) }].
  Fields of SourceRef: https://developers.sceniq.earth/fields/source-ref.md
- `status` (StatusNotice or null, optional): Closure or works notice, null clears: { state: open|partly_closed|closed|reopening, note?, since?, until? (the day the state is expected to end; buyers stop seeing the notice after it), sourceUrl?, checkedOn? }. reopening with until means reopens on that day.
  Fields of StatusNotice: https://developers.sceniq.earth/fields/status-notice.md
- `timeZone` (string, optional): IANA zone (America/Phoenix). Derived from the pin on every write; set it only when the lookup is wrong near a border. Empty string hands it back to the pin.
- `tripFacts` (TripFacts or null, optional): The planning stats bar, null clears: { elevationM? (meters; 0 is a stated sea level, absent is unknown), elevationRefersTo?: viewpoint|summit|ground|water|trailhead, elevationSource?, busyness? (1 quiet to 5 packed, shown as Crowdedness), bestSeason? }.
  Fields of TripFacts: https://developers.sceniq.earth/fields/trip-facts.md

## Returns

201: SpotWrite.

- `spotId` (string, required): The spot's id.
- `spotKey` (string, required): The spot's stable key within the guide; chapters and routes reference spots by it.
- `productId` (string, required): The guide the spot belongs to.
- `title` (string, required): The place name.
- `kicker` (string or null, required): The short line above the title (region or type).
- `lat` (number or null, required): Latitude in decimal degrees, or null when the pin is not set yet.
- `lon` (number or null, required): Longitude in decimal degrees, or null when the pin is not set yet.
- `mapsUrl` (string or null, required): The creator's own map link.
- `shortDescription` (string or null, required): One or two sentences for the card.
- `longDescription` (string or null, required): The full write-up.
- `color` (string or null, required): Pin color as a hex value, or null for the default.
- `cardOrientation` (string, required): Photo framing in the viewer. One of `portrait`, `landscape`.
- `customValues` (map of values, required): Custom property values keyed by property key; option values are option ids.
- `tripFacts` (TripFacts or null, required): The planning stats bar.
  Fields of TripFacts: https://developers.sceniq.earth/fields/trip-facts.md
- `arrival` (Arrival or null, required): How to get there.
  Fields of Arrival: https://developers.sceniq.earth/fields/arrival.md
- `mapLinks` (array of MapLink, required): Extra map links, drawn as map pills.
  Fields of MapLink: https://developers.sceniq.earth/fields/map-link.md
- `imagesEnabled` (boolean, required): false hides the photo section from buyers.
- `customPropsEnabled` (boolean, required): false hides the custom properties from buyers.
- `archived` (boolean, required): true when the spot is hidden from buyers but kept.
- `ref` (string or null, required): Your own stable key for upsert_spots.
- `accessMode` (string or null, required): How visitors reach the spot, shown as Accessibility. One of `drive_up`, `short_walk`, `hike`, `multi_day`, `boat`, `cable_car`, `train`, `flight`, `tour_only`, `aerial_only`.
- `pinLabel` (string or null, required): What the main pin marks, for a spot that is an area or a line.
- `pins` (array of SpotPin, required): Extra points: viewpoints, entrances, trailheads, parking.
  Fields of SpotPin: https://developers.sceniq.earth/fields/spot-pin.md
- `links` (array of GuideLink, required): Links with a purpose.
  Fields of GuideLink: https://developers.sceniq.earth/fields/guide-link.md
- `status` (StatusNotice or null, required): A closure or works notice.
  Fields of StatusNotice: https://developers.sceniq.earth/fields/status-notice.md
- `fees` (array of Fee, required): Fees and tickets.
  Fields of Fee: https://developers.sceniq.earth/fields/fee.md
- `schedule` (Schedule or null, required): Structured opening hours.
  Fields of Schedule: https://developers.sceniq.earth/fields/schedule.md
- `features` (array of SpotFeature, required): Parts of the site with their own rules.
  Fields of SpotFeature: https://developers.sceniq.earth/fields/spot-feature.md
- `restrictions` (array of Restriction, required): Rules on site.
  Fields of Restriction: https://developers.sceniq.earth/fields/restriction.md
- `events` (array of SpotEvent, required): Events worth timing a visit for.
  Fields of SpotEvent: https://developers.sceniq.earth/fields/spot-event.md
- `food` (FoodNote or null, required): Why the spot lists no food places.
  Fields of FoodNote: https://developers.sceniq.earth/fields/food-note.md
- `areaId` (string or null, required): The area (park, island, region) the spot sits in.
- `timeZone` (string or null, required): IANA time zone, derived from the pin unless set by hand.
- `timeZoneManual` (boolean, required): true when the time zone was set by hand rather than from the pin.
- `customNotes` (map of strings, required): One short note per custom property value, keyed by property key.
- `sources` (array of SourceRef, required): Research evidence for the review, never shown to buyers.
  Fields of SourceRef: https://developers.sceniq.earth/fields/source-ref.md
- `reviewNotes` (string or null, required): Notes for the creator's review, never shown to buyers.
- `factsCheckedOn` (string or null, required): The day the facts were last checked (YYYY-MM-DD).
- `reviewBy` (string or null, required): The day the facts need a new check (YYYY-MM-DD).
- `siteChange` (SiteChange or null, required): The day something at the spot changed.
  Fields of SiteChange: https://developers.sceniq.earth/fields/site-change.md
- `createdAt` (number, required): When the row was created (Unix time in milliseconds).
- `updatedAt` (number, required): When the row last changed (Unix time in milliseconds).
- `photos` (array of objects, required): The spot's photos in gallery order. list_media has every photo field.
  - `mediaId` (string, required): The photo's id.
  - `url` (string, required): The photo's URL.
  - `caption` (string or null, required): Caption.
  - `credit` (string or null, required): Photographer credit.
  - `width` (number or null, required): Width in pixels.
  - `height` (number or null, required): Height in pixels.
  - `order` (number, required): Position in the spot's gallery (ascending).
- `chapters` (array of objects, required): The chapters and collections the spot belongs to.
  - `collectionId` (string, required): The chapter's or collection's id.
  - `name` (string, required): Its name.
  - `kind` (string, required): chapter carries prose; collection is a plain spot set. One of `collection`, `chapter`.
  - `order` (number, required): The spot's position inside that chapter.
- `routes` (array of objects, required): The routes that reach the spot.
  - `routeId` (string, required): The route's id.
  - `name` (string or null, required): The route's name.
  - `order` (number, required): The spot's position on the route.
  - `quickest` (boolean, required): true when this route is the fastest approach to the spot.
- `warnings` (array of strings, optional): Notes about things the write accepted but you should look at (a plain http link). Present only when there are any.

## Examples

### Create a complete spot in one call

```bash
curl -X POST "https://sceniq.earth/api/v1/guides/j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2/spots" \
  -H "Authorization: Bearer $SCENIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Grand Prismatic Spring",
  "kicker": "Yellowstone, Midway Geyser Basin",
  "lat": 44.5251,
  "lon": -110.8382,
  "mapsUrl": "https://maps.apple.com/?ll=44.5251,-110.8382&q=Grand%20Prismatic%20Spring",
  "shortDescription": "The largest hot spring in the United States. See it from the boardwalk, then from the overlook above the Fairy Falls trail.",
  "longDescription": "Grand Prismatic is about 110 meters across, and from the boardwalk you mostly see steam and the orange mats that run off toward the Firehole River. For the colors, park at the Fairy Falls trailhead and follow the trail to the signed spur for the overlook: about 1 km each way, 20 minutes up. The whole spring opens up below the platform. Come on a warm, dry morning; on a cold day the steam hides everything.",
  "accessMode": "short_walk",
  "tripFacts": {
    "elevationM": 2176,
    "elevationRefersTo": "ground",
    "busyness": 5,
    "bestSeason": "Late May to September"
  },
  "arrival": {
    "byCar": {
      "directions": "Grand Loop Road, 11 km north of Old Faithful. Midway Geyser Basin lot.",
      "parking": "Midway Geyser Basin lot, full by 10:00 in summer. Fairy Falls trailhead lot 1.6 km south.",
      "walkToSpotMin": 10
    },
    "byTrainBus": {
      "none": true
    },
    "bestTime": "Mid morning on a warm, dry day: cold air turns the steam into fog that hides the colors."
  },
  "pins": [
    {
      "kind": "viewpoint",
      "label": "Grand Prismatic Overlook",
      "lat": 44.5192,
      "lon": -110.8391,
      "note": "Platform on a spur of the Fairy Falls trail, about 1 km from the trailhead lot."
    },
    {
      "kind": "parking",
      "label": "Fairy Falls trailhead lot",
      "lat": 44.5153,
      "lon": -110.8325,
      "note": "For the overlook. Full by mid morning in July and August."
    }
  ],
  "fees": [
    {
      "label": "Park entrance, private vehicle, 7 days",
      "amount": 35,
      "currency": "USD",
      "per": "vehicle",
      "paidWhere": "online",
      "sourceUrl": "https://www.nps.gov/yell/planyourvisit/fees.htm",
      "checkedOn": "2026-09-20"
    }
  ],
  "restrictions": [
    {
      "kind": "no_drone",
      "label": "No drones in the park",
      "note": "Drones are banned in all US national parks."
    },
    {
      "kind": "no_entry",
      "label": "Stay on the boardwalk",
      "note": "The crust around the spring is thin, and the water under it is scalding."
    }
  ],
  "links": [
    {
      "kind": "official",
      "url": "https://www.nps.gov/places/000/grand-prismatic-spring.htm",
      "label": "Grand Prismatic Spring (NPS)"
    },
    {
      "kind": "status",
      "url": "https://www.nps.gov/yell/planyourvisit/conditions.htm",
      "label": "Park road status"
    }
  ],
  "customValues": {
    "best_time": "morning",
    "crowds": "packed",
    "photo_notes": "From the overlook a 24 mm lens takes in the whole spring. On the boardwalk, shoot the runoff channels instead of the steam."
  },
  "customNotes": {
    "crowds": "Quieter before 9:00 and after 18:00"
  },
  "sources": [
    {
      "url": "https://www.nps.gov/places/000/grand-prismatic-spring.htm",
      "kind": "page",
      "capturedOn": "2026-09-20",
      "supports": [
        "arrival",
        "restrictions"
      ]
    }
  ],
  "factsCheckedOn": "2026-09-20",
  "reviewBy": "2027-04-01",
  "reviewNotes": "The overlook pin comes from your GPX of 18 September; please confirm it. The trail distance is from the NPS page (0.6 mi each way)."
}'
```

MCP `tools/call`:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "create_spot",
    "arguments": {
      "productId": "j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2",
      "title": "Grand Prismatic Spring",
      "kicker": "Yellowstone, Midway Geyser Basin",
      "lat": 44.5251,
      "lon": -110.8382,
      "mapsUrl": "https://maps.apple.com/?ll=44.5251,-110.8382&q=Grand%20Prismatic%20Spring",
      "shortDescription": "The largest hot spring in the United States. See it from the boardwalk, then from the overlook above the Fairy Falls trail.",
      "longDescription": "Grand Prismatic is about 110 meters across, and from the boardwalk you mostly see steam and the orange mats that run off toward the Firehole River. For the colors, park at the Fairy Falls trailhead and follow the trail to the signed spur for the overlook: about 1 km each way, 20 minutes up. The whole spring opens up below the platform. Come on a warm, dry morning; on a cold day the steam hides everything.",
      "accessMode": "short_walk",
      "tripFacts": {
        "elevationM": 2176,
        "elevationRefersTo": "ground",
        "busyness": 5,
        "bestSeason": "Late May to September"
      },
      "arrival": {
        "byCar": {
          "directions": "Grand Loop Road, 11 km north of Old Faithful. Midway Geyser Basin lot.",
          "parking": "Midway Geyser Basin lot, full by 10:00 in summer. Fairy Falls trailhead lot 1.6 km south.",
          "walkToSpotMin": 10
        },
        "byTrainBus": {
          "none": true
        },
        "bestTime": "Mid morning on a warm, dry day: cold air turns the steam into fog that hides the colors."
      },
      "pins": [
        {
          "kind": "viewpoint",
          "label": "Grand Prismatic Overlook",
          "lat": 44.5192,
          "lon": -110.8391,
          "note": "Platform on a spur of the Fairy Falls trail, about 1 km from the trailhead lot."
        },
        {
          "kind": "parking",
          "label": "Fairy Falls trailhead lot",
          "lat": 44.5153,
          "lon": -110.8325,
          "note": "For the overlook. Full by mid morning in July and August."
        }
      ],
      "fees": [
        {
          "label": "Park entrance, private vehicle, 7 days",
          "amount": 35,
          "currency": "USD",
          "per": "vehicle",
          "paidWhere": "online",
          "sourceUrl": "https://www.nps.gov/yell/planyourvisit/fees.htm",
          "checkedOn": "2026-09-20"
        }
      ],
      "restrictions": [
        {
          "kind": "no_drone",
          "label": "No drones in the park",
          "note": "Drones are banned in all US national parks."
        },
        {
          "kind": "no_entry",
          "label": "Stay on the boardwalk",
          "note": "The crust around the spring is thin, and the water under it is scalding."
        }
      ],
      "links": [
        {
          "kind": "official",
          "url": "https://www.nps.gov/places/000/grand-prismatic-spring.htm",
          "label": "Grand Prismatic Spring (NPS)"
        },
        {
          "kind": "status",
          "url": "https://www.nps.gov/yell/planyourvisit/conditions.htm",
          "label": "Park road status"
        }
      ],
      "customValues": {
        "best_time": "morning",
        "crowds": "packed",
        "photo_notes": "From the overlook a 24 mm lens takes in the whole spring. On the boardwalk, shoot the runoff channels instead of the steam."
      },
      "customNotes": {
        "crowds": "Quieter before 9:00 and after 18:00"
      },
      "sources": [
        {
          "url": "https://www.nps.gov/places/000/grand-prismatic-spring.htm",
          "kind": "page",
          "capturedOn": "2026-09-20",
          "supports": [
            "arrival",
            "restrictions"
          ]
        }
      ],
      "factsCheckedOn": "2026-09-20",
      "reviewBy": "2027-04-01",
      "reviewNotes": "The overlook pin comes from your GPX of 18 September; please confirm it. The trail distance is from the NPS page (0.6 mi each way)."
    }
  }
}
```

Response 201:

```json
{
  "spotId": "k1709e2vj4sk8q6x0d3m5r7t9w1y3b5c",
  "spotKey": "01M2Z1G0Y0QG7M2V6N9R3T5W8Y",
  "productId": "j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2",
  "title": "Grand Prismatic Spring",
  "kicker": "Yellowstone, Midway Geyser Basin",
  "lat": 44.5251,
  "lon": -110.8382,
  "mapsUrl": "https://maps.apple.com/?ll=44.5251,-110.8382&q=Grand%20Prismatic%20Spring",
  "shortDescription": "The largest hot spring in the United States. See it from the boardwalk, then from the overlook above the Fairy Falls trail.",
  "longDescription": "Grand Prismatic is about 110 meters across, and from the boardwalk you mostly see steam and the orange mats that run off toward the Firehole River. For the colors, park at the Fairy Falls trailhead and follow the trail to the signed spur for the overlook: about 1 km each way, 20 minutes up. The whole spring opens up below the platform. Come on a warm, dry morning; on a cold day the steam hides everything.",
  "color": null,
  "cardOrientation": "landscape",
  "customValues": {
    "best_time": "morning",
    "crowds": "packed",
    "photo_notes": "From the overlook a 24 mm lens takes in the whole spring. On the boardwalk, shoot the runoff channels instead of the steam."
  },
  "tripFacts": {
    "elevationM": 2176,
    "elevationRefersTo": "ground",
    "busyness": 5,
    "bestSeason": "Late May to September"
  },
  "arrival": {
    "byCar": {
      "directions": "Grand Loop Road, 11 km north of Old Faithful. Midway Geyser Basin lot.",
      "parking": "Midway Geyser Basin lot, full by 10:00 in summer. Fairy Falls trailhead lot 1.6 km south.",
      "walkToSpotMin": 10
    },
    "byTrainBus": {
      "none": true
    },
    "bestTime": "Mid morning on a warm, dry day: cold air turns the steam into fog that hides the colors."
  },
  "mapLinks": [],
  "imagesEnabled": true,
  "customPropsEnabled": true,
  "archived": false,
  "ref": null,
  "accessMode": "short_walk",
  "pinLabel": null,
  "pins": [
    {
      "kind": "viewpoint",
      "label": "Grand Prismatic Overlook",
      "lat": 44.5192,
      "lon": -110.8391,
      "note": "Platform on a spur of the Fairy Falls trail, about 1 km from the trailhead lot."
    },
    {
      "kind": "parking",
      "label": "Fairy Falls trailhead lot",
      "lat": 44.5153,
      "lon": -110.8325,
      "note": "For the overlook. Full by mid morning in July and August."
    }
  ],
  "links": [
    {
      "kind": "official",
      "url": "https://www.nps.gov/places/000/grand-prismatic-spring.htm",
      "label": "Grand Prismatic Spring (NPS)"
    },
    {
      "kind": "status",
      "url": "https://www.nps.gov/yell/planyourvisit/conditions.htm",
      "label": "Park road status"
    }
  ],
  "status": null,
  "fees": [
    {
      "label": "Park entrance, private vehicle, 7 days",
      "amount": 35,
      "currency": "USD",
      "per": "vehicle",
      "paidWhere": "online",
      "sourceUrl": "https://www.nps.gov/yell/planyourvisit/fees.htm",
      "checkedOn": "2026-09-20"
    }
  ],
  "schedule": null,
  "features": [],
  "restrictions": [
    {
      "kind": "no_drone",
      "label": "No drones in the park",
      "note": "Drones are banned in all US national parks."
    },
    {
      "kind": "no_entry",
      "label": "Stay on the boardwalk",
      "note": "The crust around the spring is thin, and the water under it is scalding."
    }
  ],
  "events": [],
  "food": null,
  "areaId": null,
  "timeZone": "America/Denver",
  "timeZoneManual": false,
  "customNotes": {
    "crowds": "Quieter before 9:00 and after 18:00"
  },
  "sources": [
    {
      "url": "https://www.nps.gov/places/000/grand-prismatic-spring.htm",
      "kind": "page",
      "capturedOn": "2026-09-20",
      "supports": [
        "arrival",
        "restrictions"
      ]
    }
  ],
  "reviewNotes": "The overlook pin comes from your GPX of 18 September; please confirm it. The trail distance is from the NPS page (0.6 mi each way).",
  "factsCheckedOn": "2026-09-20",
  "reviewBy": "2027-04-01",
  "siteChange": null,
  "createdAt": 1789895640000,
  "updatedAt": 1789895640000,
  "photos": [],
  "chapters": [],
  "routes": []
}
```

### Create a spot before the creator has sent its pin

```bash
curl -X POST "https://sceniq.earth/api/v1/guides/j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2/spots" \
  -H "Authorization: Bearer $SCENIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Lamar Valley",
  "kicker": "Yellowstone, northeast entrance road",
  "reviewNotes": "No pin yet: the creator is sending the pullout they use for the bison herds."
}'
```

MCP `tools/call`:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "create_spot",
    "arguments": {
      "productId": "j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2",
      "title": "Lamar Valley",
      "kicker": "Yellowstone, northeast entrance road",
      "reviewNotes": "No pin yet: the creator is sending the pullout they use for the bison herds."
    }
  }
}
```

Response 201:

```json
{
  "spotId": "k17rwzt006kbqwjbs5jrqk4jjf5srec9",
  "spotKey": "01M3GYV6A0Y3SYC62RBPEA9S0C",
  "productId": "j5738kd1q9x2m7v4c6b8n0p3r5t1w9y2",
  "title": "Lamar Valley",
  "kicker": "Yellowstone, northeast entrance road",
  "lat": null,
  "lon": null,
  "mapsUrl": null,
  "shortDescription": null,
  "longDescription": null,
  "color": null,
  "cardOrientation": "landscape",
  "customValues": {},
  "tripFacts": null,
  "arrival": null,
  "mapLinks": [],
  "imagesEnabled": true,
  "customPropsEnabled": true,
  "archived": false,
  "ref": null,
  "accessMode": null,
  "pinLabel": null,
  "pins": [],
  "links": [],
  "status": null,
  "fees": [],
  "schedule": null,
  "features": [],
  "restrictions": [],
  "events": [],
  "food": null,
  "areaId": null,
  "timeZone": null,
  "timeZoneManual": false,
  "customNotes": {},
  "sources": [],
  "reviewNotes": "No pin yet: the creator is sending the pullout they use for the bison herds.",
  "factsCheckedOn": null,
  "reviewBy": null,
  "siteChange": null,
  "createdAt": 1789895640000,
  "updatedAt": 1789895640000,
  "photos": [],
  "chapters": [],
  "routes": []
}
```

## 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_spot
