update_facility
Edit a place.
/v1/facilities/{facilityId}Only sent fields change; empty strings clear (type "" falls back to the kind's default), null clears an object or the pin, lists are full replacements; spotKeys replaces the whole list.
curl -X PATCH "https://sceniq.earth/api/v1/facilities/km7d4f6g8h0j2k4k6z8x0c2v4b6n8m0q" \
-H "Authorization: Bearer $SCENIQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": {
"state": "partly_closed",
"note": "Half the lot is fenced off for repaving until 10 October.",
"since": "2026-09-28",
"until": "2026-10-10",
"sourceUrl": "https://www.nps.gov/yell/planyourvisit/conditions.htm",
"checkedOn": "2026-09-29"
},
"parking": {
"fillsBy": "08:30 while the repaving lasts",
"rule": "Day use only. No overnight parking."
},
"factsCheckedOn": "2026-09-29"
}'Path parameters
- facilityIdstring · place idrequired
Id of the facility (from
list_facilities).
Body parameters
Tours and activities (kind activity), null clears: {
meetingPoint?,meetingLat?,meetingLon?,durationMin?, departures?,requiredToSee? (the only way to see the spot),authorizedBy?,authorizedByUrl? }.Show 8 fieldsHide fieldsof ActivityInfo
- meetingPointstringoptional
Where to meet, at most 200 characters, shown as Meeting point.
- meetingLatnumberoptional
Latitude of the meeting point. Give
meetingLatandmeetingLontogether. - meetingLonnumberoptional
Longitude of the meeting point.
- durationMinnumberoptional
How long it takes in minutes (1 to 100,000), shown as Duration.
- departuresstringoptional
When it departs, in words, at most 300 characters (daily at 09:00 and 14:00), shown as Departures.
- requiredToSeebooleanoptional
true when a tour is the only way to see the spot (authorized tours at Antelope Canyon), shown as Needed to see the spot.
- authorizedBystringoptional
Who authorizes the operator, at most 120 characters, shown as Authorized by <name>.
- authorizedByUrlstringoptional
The authorizing body's page (http or https), linked from that line.
- bookingRequiredbooleanoptional
true shows Booking required.
- bookingUrlstringoptional
The page to book on (http or https).
null clears: {
minAge?,guestsOnly?,swimmersOnly?,luggageKg?,soldAsPackage?,cashOnly? }, shown as chips.Show 6 fieldsHide fieldsof PlaceConditions
- minAgenumberoptional
Minimum age, a whole number from 1 to 99, shown as Age 16+.
- guestsOnlybooleanoptional
true shows Guests only.
- swimmersOnlybooleanoptional
true shows Swimmers only.
- luggageKgnumberoptional
The luggage limit in kilograms (1 to 200), shown as Luggage up to 15 kg.
- soldAsPackagebooleanoptional
true shows Sold as a package.
- cashOnlybooleanoptional
true shows Cash only.
- costRawstringoptional
Price as the creator states it, e.g. 180 USD a night or 92 CHF half board; never parsed (
costUnitsays what it counts). Empty string clears. - costUnitstring or nulloptional
What
costRawcounts:per_person,per_night,per_person_night,per_room,per_vehicle,per_trip,per_hour,per_day. null clears.per_personper_nightper_person_nightper_roomper_vehicleper_tripper_hourper_day - countrystringoptional
ISO 3166-1 alpha-2 code (AR, BR): places on two sides of a border read right.
- descriptionstringoptional
The place in the creator's words. Empty string clears.
- extraKindsarray of stringsoptional
Further roles of the same place (a hut that is also a restaurant): [hut|
cable_car|activity|food|parking]. It then shows under each.hutcable_caractivityfoodparking Free label and value rows shown on the card, full replacement ([] clears), at most 24: [{ label (at most 60 characters), value (at most 500) }]. A row with both sides empty is dropped, a half-empty one refused.
Show 2 fieldsHide fieldsof ExtraProp
- labelstringrequired
The row's label, at most 60 characters.
- valuestringrequired
The row's value, at most 500 characters.
- factsCheckedOnstringoptional
The day the facts were last checked against their sources (YYYY-MM-DD). Empty string clears.
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 pastvalidUntilor unchecked for a year.Show 14 fieldsHide fieldsof Fee
- labelstringrequired
What the fee is for, at most 80 characters (Adult entry, Car park, Boat transfer).
- amountnumberoptional
The price in major units (40, 12.5). Needs currency. Absent when the fee is free or left to the official page.
- currencystringoptional
ISO 4217 code (USD, EUR, ARS). Required with amount.
- freebooleanoptional
true for no charge. Cannot be combined with an amount.
- seeOfficialbooleanoptional
true for a price the guide leaves to the official page on purpose (it changes too often to copy).
- perstringoptional
What one amount pays for: person, vehicle, night, group, entry, day or hour.
personvehiclenightgroupentrydayhour - audiencestringoptional
Who pays this rate: all, adult, child, foreign, domestic, resident, student or senior.
alladultchildforeigndomesticresidentstudentsenior - paidWherestringoptional
Where it is paid: online,
on_siteorin_tour(part of a tour price).onlineon_sitein_tour - paymentstringoptional
How it can be paid:
cash_only,card_onlyorcash_or_card.cash_onlycard_onlycash_or_card - notestringoptional
One line of context, at most 300 characters (free on the first Sunday of the month).
- validFromstringoptional
The first day the price applies (YYYY-MM-DD).
- validUntilstringoptional
The last day the price applies (YYYY-MM-DD). Readiness flags the row after it.
- sourceUrlstringoptional
The page the price comes from (http or https).
- checkedOnstringoptional
The day the value was last checked against its source (YYYY-MM-DD).
- gatewayTownstringoptional
The town the place sits in when it is far from the spot on purpose (Ushuaia for an Antarctic cruise); no distance is shown then. Empty string clears.
- googlePlaceIdstringoptional
Google place id the pin came from, as a reference.
- insideIdstring or null · place idoptional
facilityIdof the place this one sits inside (a restaurant inside a lodge); one level only. null clears. - kindstringoptional
Moves the place to another kind: hut (a stay),
cable_car(transport), activity (tours and activities), food or parking. A type the new kind does not have is dropped.hutcable_caractivityfoodparking - latnumber or nulloptional
The place's own latitude. With lon, the apps show it on the map and compute its distance to the spot; null clears.
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.
Show 5 fieldsHide fieldsof GuideLink
- kindstringrequired
What the link is for. official and website are the place's own pages; tickets and booking sell entry or rooms; status, timetable and tide carry live conditions; listing, social, authority and app cover the rest.
officialwebsiteticketsbookingstatustimetabletidelistingsocialauthorityappother - labelstringoptional
The link text buyers see, at most 60 characters. Without it the apps name the link by its kind.
- urlstringoptional
An http or https page. http is accepted with a warning.
- valuestringoptional
A channel that is not a URL, at most 200 characters, for example a WeChat mini program and its search term.
- notestringoptional
One line of context shown under the link, at most 300 characters.
- lonnumber or nulloptional
The place's own longitude.
- mapsUrlstringoptional
Map link: https on Google Maps, Apple Maps, Swisstopo, OpenStreetMap or SchweizMobil, or a geo: URI. Give lat and lon too. Empty string clears.
- namestringoptional
Name of the place. Cannot be empty.
- needsParentTicketbooleanoptional
true when entering needs the parent place's ticket.
- openRawstringoptional
Season or hours as text, never parsed (schedule holds structured hours). Empty string clears.
- operatorstringoptional
Who runs it. Empty string clears.
- osmIdstringoptional
OpenStreetMap reference the pin came from: node/123, way/456 or relation/789.
Parking places, null clears: {
fillsBy? (10:00), rule? (the only legal pullout) }.Show 2 fieldsHide fieldsof ParkingInfo
- fillsBystringoptional
When the lot is usually full, at most 80 characters (10:00, by 9 in summer), shown as Fills by.
- rulestringoptional
What is allowed, at most 300 characters (the only legal pullout).
- reviewBystringoptional
The day the facts need a new check (YYYY-MM-DD), e.g. when a season, fare or timetable runs out.
get_guide_readinessandget_publish_statuswarn once it has passed. Empty string clears. - reviewNotesstringoptional
Notes for the creator's review (why a value was chosen, what could not be verified). Never shown to buyers;
get_guide_readinesslists them. Empty string clears. 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.Show 8 fieldsHide fieldsof Schedule
Up to 24 bands; the last matching band wins.
Show 11 fieldsHide fieldsof HoursBand
- fromstringoptional
First day of the band as MM-DD. Absent means the start of the year.
- tostringoptional
Last day of the band as MM-DD. May wrap over the new year (from 11-01 to 03-31).
- weekdaysarray of numbersoptional
The weekdays it covers, 1 (Monday) to 7 (Sunday). Absent means every day.
- closedbooleanoptional
true when the place is closed in this band. Otherwise open and close are required.
- openstringoptional
Opening time as HH:MM, or sunrise or sunset.
- closestringoptional
Closing time as HH:MM, or sunrise or sunset.
- openOffsetMinnumberoptional
Minutes around a sun anchor for open (-240 to 240; -60 is an hour before sunrise).
- closeOffsetMinnumberoptional
Minutes around a sun anchor for close (-240 to 240).
- lastEntrystringoptional
Last entry as HH:MM.
- leaveBystringoptional
The time visitors must be out as HH:MM.
- notestringoptional
One line for the band, at most 200 characters.
- specialDaysarray of objectsoptional
Up to 40 days that differ from the bands: a date or a rule, closed or with their own times.
Show 6 fieldsHide fields
- datestringoptional
The day (YYYY-MM-DD). Give a date or a rule.
- rulestringoptional
A recurring day in words, at most 120 characters (first Sunday of the month).
- closedbooleanoptional
true when the place is closed that day.
- openstringoptional
Opening time that day as HH:MM, or sunrise or sunset.
- closestringoptional
Closing time that day as HH:MM, or sunrise or sunset.
- notestringoptional
One line for the day, at most 200 characters.
- slotsobjectoptional
Timed entry: entries every
everyMinminutes from first to last.Show 5 fieldsHide fields
- firststringrequired
The first entry time as HH:MM.
- laststringrequired
The last entry time as HH:MM.
- everyMinnumberrequired
Minutes between entries.
- capnumberoptional
People per slot, when the source states it (1 to 100,000).
- notestringoptional
One line about booking a slot, at most 200 characters.
- validFromstringoptional
The first day these hours apply (YYYY-MM-DD).
- validUntilstringoptional
The last day these hours apply (YYYY-MM-DD).
- sourceUrlstringoptional
The page the hours come from (http or https).
- checkedOnstringoptional
The day the value was last checked against its source (YYYY-MM-DD).
- notestringoptional
A note for the whole schedule, at most 500 characters.
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) }].Show 7 fieldsHide fieldsof SourceRef
- urlstringoptional
The page, API or archive copy the facts come from (http or https).
- titlestringoptional
A name for a source without a URL (a park leaflet, a phone call with the operator), at most 200 characters.
- kindstringoptional
page, api, archive, document or other.
pageapiarchivedocumentother - capturedOnstringoptional
The day the source was read (YYYY-MM-DD).
- notestringoptional
What the source says or why it was chosen, at most 500 characters.
- supportsarray of stringsoptional
Which facts it backs, up to 12 entries of at most 60 characters (fees, arrival.operating, lat/lon).
- conflictbooleanoptional
true when this source disagrees with another on the facts it backs. Say which one the value follows in note or
reviewNotes.
- spotKeysarray of stringsoptional
spotKeysof the spots it serves directly (a hotel near a viewpoint), in order and each once, full replacement ([] clears), at most 200. Archived spots are allowed. 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.Show 6 fieldsHide fieldsof StatusNotice
- statestringrequired
open,
partly_closed, closed or reopening. reopening with until means it reopens on that day.openpartly_closedclosedreopening - notestringoptional
What is closed or changed, in the creator's words, at most 500 characters.
- sincestringoptional
The day the state began (YYYY-MM-DD).
- untilstringoptional
The day the state is expected to end (YYYY-MM-DD). Must not be before since.
- sourceUrlstringoptional
The page that announced it (http or https).
- checkedOnstringoptional
The day the value was last checked against its source (YYYY-MM-DD).
Transport places, null clears: { stops?: [{ name, lat?, lon?,
registerId? (NSR or GTFS stop id), note? }],serviceDays? [1-7],timetableUrl?,timetableValidFrom?,timetableValidUntil?,verifyBeforeTravel? }.Show 6 fieldsHide fieldsof TransportInfo
- stopsarray of objectsoptional
Up to 30 stops, in the order buyers see them.
Show 5 fieldsHide fields
- namestringrequired
The stop's name, at most 100 characters. Required.
- latnumberoptional
Latitude of the stop. Give lat and lon together; the stop then links to a map.
- lonnumberoptional
Longitude of the stop.
- registerIdstringoptional
The stop's id in a public register (an NSR or GTFS stop id), at most 80 characters.
- notestringoptional
One line about the stop, at most 200 characters.
- serviceDaysarray of numbersoptional
The weekdays it runs, 1 (Monday) to 7 (Sunday). On fewer than seven days buyers see Runs Mon to Fri.
- timetableUrlstringoptional
The timetable page (http or https), shown as a Timetable link.
- timetableValidFromstringoptional
The first day the timetable applies (YYYY-MM-DD).
- timetableValidUntilstringoptional
The last day the timetable applies (YYYY-MM-DD), not before
timetableValidFrom. Buyers see Timetable valid until that day. - verifyBeforeTravelbooleanoptional
true shows Check the timetable before you travel.
- typestringoptional
Optional sub-type. Stays: hotel, guesthouse, hostel, hut, campsite, rental, liveaboard, pontoon. Transport:
cable_car, chairlift, funicular,cog_railway, train, bus, ferry, shuttle, flight, helicopter, tram, metro, taxi,bike_rental, jeep, elevator, toboggan, hub. Tours and activities:guided_tour,boat_tour, balloon,scenic_flight,jeep_safari,gear_rental. Food: restaurant, cafe, bar, bakery, grocery, market,picnic_site. Parking:parking_lot,parking_garage, street, campervan. A place without one reads as its kind's default (hut,cable_car,guided_tour, restaurant orparking_lot); empty string clears. - websitestringoptional
Link to the official site (https, or http with a warning). Empty string clears.
Returns
200 OK with this object.
- okbooleanrequired
Always true: the write went through.
Always
true - facilityIdstring · place idrequired
The place's id.
- warningsarray of stringsoptional
Notes about things the write accepted but you should look at (a plain http link). Present only when there are any.
{
"ok": true,
"facilityId": "km7d4f6g8h0j2k4k6z8x0c2v4b6n8m0q"
}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.