{"openapi":"3.1.0","info":{"title":"LezPlanIt Agent API","version":"1.0.0","description":"Plan whole trips with Lez from your own assistant or agent. The host converses; LezPlanIt plans: real places, opening hours, travel times, day by day, kept live in the traveller's LezPlanIt account. Drafting is a job to poll; edits are proposals applied only when the traveller agrees. Errors are `{error, message, ...}` with a stable `error` code: needs_upgrade (carries upgrade_url), rate_limited (retry_after_seconds), draft_in_progress (job_id), conflict, no_match, validation_failed, ai_unavailable, not_found, forbidden, invalid_arguments.","contact":{"email":"support@lezplanit.com"},"x-mcp-server":"https://lezplanit.com/mcp","x-mcp-public-server":"https://lezplanit.com/mcp/public","termsOfService":"https://lezplanit.com/legal/terms"},"servers":[{"url":"https://lezplanit.com/api/agent/v1"}],"security":[{"oauth2":["mcp:use"]}],"tags":[{"name":"Planning","description":"Lez drafts and edits; the traveller approves."},{"name":"Trips","description":"The traveller's trips, read-only."},{"name":"Money & bookings"},{"name":"Public","description":"No sign-in: guides, shared itineraries, invite previews."}],"paths":{"/drafts":{"post":{"tags":["Planning"],"operationId":"createDraft","summary":"Draft a trip with Lez","description":"Needs at least destination plus dates or duration_days and travelers. Uses one plan credit. Returns the job to poll.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["brief"],"properties":{"brief":{"$ref":"#/components/schemas/Brief"},"sentence":{"type":"string","maxLength":1000}}}}}},"responses":{"202":{"description":"Draft queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftJob"}}}},"402":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}}}},"/drafts/{job}":{"get":{"tags":["Planning"],"operationId":"getDraftStatus","summary":"Check a draft","parameters":[{"name":"job","in":"path","required":true,"schema":{"type":"string"}},{"name":"wait_seconds","in":"query","schema":{"type":"integer","minimum":0,"maximum":15},"description":"Long-poll for up to this many seconds (15 is a good default)."}],"responses":{"200":{"description":"Status, and the trip once ready","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftStatus"}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/trips":{"get":{"tags":["Trips"],"operationId":"listTrips","summary":"List the traveller's trips","parameters":[{"name":"include_past","in":"query","schema":{"type":"boolean"}},{"name":"timezone","in":"query","schema":{"type":"string"},"description":"IANA zone for judging upcoming / now / past."}],"responses":{"200":{"description":"Trips with ids, dates, relation to today and the traveller's role","content":{"application/json":{"schema":{"type":"object","properties":{"trips":{"type":"array","items":{"$ref":"#/components/schemas/TripSummary"}},"quota":{"$ref":"#/components/schemas/Quota"}}}}}}}}},"/trips/{trip}":{"get":{"tags":["Trips"],"operationId":"getTrip","summary":"Read a trip day by day","parameters":[{"$ref":"#/components/parameters/trip"},{"name":"day_numbers","in":"query","schema":{"type":"string"},"description":"Comma-separated day numbers to return in full."}],"responses":{"200":{"description":"The trip","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Trip"}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/trips/{trip}/today":{"get":{"tags":["Trips"],"operationId":"getToday","summary":"What's on today","parameters":[{"$ref":"#/components/parameters/trip"},{"name":"timezone","in":"query","schema":{"type":"string"}},{"name":"now","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Where the traveller is in the trip and today's stops"},"404":{"$ref":"#/components/responses/Error"}}}},"/trips/{trip}/budget":{"get":{"tags":["Money & bookings"],"operationId":"getBudget","summary":"Trip money summary","parameters":[{"$ref":"#/components/parameters/trip"},{"name":"scope","in":"query","schema":{"type":"string","enum":["mine","trip"]}}],"responses":{"200":{"description":"Spend by category, tracking against plan, balances"},"403":{"$ref":"#/components/responses/Error"}}}},"/trips/{trip}/alerts":{"get":{"tags":["Trips"],"operationId":"getTripAlerts","summary":"Things that need attention on one trip","parameters":[{"$ref":"#/components/parameters/trip"}],"responses":{"200":{"description":"Unanswered watcher findings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alerts"}}}}}}},"/alerts":{"get":{"tags":["Trips"],"operationId":"getAllAlerts","summary":"Things that need attention on every upcoming trip","responses":{"200":{"description":"Unanswered watcher findings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alerts"}}}}}}},"/trips/{trip}/edits":{"post":{"tags":["Planning"],"operationId":"proposeEdit","summary":"Propose a change in plain words","parameters":[{"$ref":"#/components/parameters/trip"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["instruction"],"properties":{"instruction":{"type":"string","maxLength":500},"focused_day_number":{"type":"integer","minimum":1}}}}}},"responses":{"201":{"description":"A proposal; nothing applied yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Proposal"}}}},"403":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/trips/{trip}/replan":{"post":{"tags":["Planning"],"operationId":"replanDays","summary":"Rework whole days","parameters":[{"$ref":"#/components/parameters/trip"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["day_numbers","intent"],"properties":{"day_numbers":{"type":"array","items":{"type":"integer"},"minItems":1,"maxItems":3},"intent":{"type":"string","maxLength":400}}}}}},"responses":{"201":{"description":"A proposal; nothing applied yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Proposal"}}}}}}},"/edits/{proposal}/apply":{"post":{"tags":["Planning"],"operationId":"applyEdit","summary":"Apply a proposal the traveller agreed to","parameters":[{"name":"proposal","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Applied (idempotent)"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"}}}},"/trips/{trip}/checklist":{"post":{"tags":["Planning"],"operationId":"generateChecklist","summary":"Build the packing list and/or entry requirements","parameters":[{"$ref":"#/components/parameters/trip"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["section"],"properties":{"section":{"type":"string","enum":["packing","requirements","all"]}}}}}},"responses":{"200":{"description":"Sections built and the items"},"422":{"$ref":"#/components/responses/Error"}}}},"/trips/{trip}/expenses":{"post":{"tags":["Money & bookings"],"operationId":"logExpense","summary":"Log an expense","parameters":[{"$ref":"#/components/parameters/trip"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amount_minor","currency_code"],"properties":{"amount_minor":{"type":"integer","minimum":0,"description":"4800 = 48.00"},"currency_code":{"type":"string","pattern":"^[A-Za-z]{3}$"},"logged_at":{"type":"string","format":"date-time"},"category":{"type":"string","enum":["lodging","food","transport","activity","incidentals","other"]},"note":{"type":"string","maxLength":500},"day_number":{"type":"integer","minimum":1},"activity_id":{"type":"string"}}}}}},"responses":{"201":{"description":"The expense with its home-currency snapshot"},"403":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}}}},"/trips/{trip}/reservations":{"post":{"tags":["Money & bookings"],"operationId":"addReservation","summary":"Add a booking","parameters":[{"$ref":"#/components/parameters/trip"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["kind","title","start_at","start_tz","end_at","end_tz"],"properties":{"kind":{"type":"string","enum":["flight","lodging","other"]},"title":{"type":"string","maxLength":200},"start_at":{"type":"string","format":"date-time"},"start_tz":{"type":"string"},"end_at":{"type":"string","format":"date-time"},"end_tz":{"type":"string"},"vendor":{"type":"string"},"booking_reference":{"type":"string"},"start_location_label":{"type":"string"},"end_location_label":{"type":"string"},"price_paid_minor":{"type":"integer"},"price_paid_currency":{"type":"string"},"notes":{"type":"string"}}}}}},"responses":{"201":{"description":"The booking"},"403":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}}}},"/public/guides":{"get":{"tags":["Public"],"operationId":"searchGuides","summary":"Find a LezPlanIt guide or post","security":[],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","maxLength":120}},{"name":"kind","in":"query","schema":{"type":"string","enum":["guides","blog"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":10}}],"responses":{"200":{"description":"Matching articles with links"}}}},"/public/guides/{slug}":{"get":{"tags":["Public"],"operationId":"getGuide","summary":"Read a guide in full (markdown)","security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"kind","in":"query","schema":{"type":"string","enum":["guides","blog"]}}],"responses":{"200":{"description":"The article"},"404":{"$ref":"#/components/responses/Error"}}}},"/public/trips/{slug}":{"get":{"tags":["Public"],"operationId":"getPublicTrip","summary":"Read a shared itinerary","security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"The 8-character slug from lezplanit.com/t/{slug}"}],"responses":{"200":{"description":"The itinerary day by day with page and copy links"},"404":{"$ref":"#/components/responses/Error"}}}},"/public/share/{code}":{"get":{"tags":["Public"],"operationId":"previewSharedTrip","summary":"Preview a trip invite code","security":[],"parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"What the invite points at, or an error code"}}}}},"components":{"securitySchemes":{"oauth2":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://lezplanit.com/oauth/authorize","tokenUrl":"https://lezplanit.com/oauth/token","refreshUrl":"https://lezplanit.com/oauth/token","scopes":{"mcp:use":"Read and plan the traveller's trips"}}}}},"parameters":{"trip":{"name":"trip","in":"path","required":true,"schema":{"type":"string"},"description":"A trip id from GET /trips"}},"responses":{"Error":{"description":"A failure the host can act on","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error","message"],"properties":{"error":{"type":"string","enum":["needs_upgrade","rate_limited","draft_in_progress","conflict","no_match","validation_failed","ai_unavailable","not_found","forbidden","invalid_arguments","auth_required"]},"message":{"type":"string"},"upgrade_url":{"type":"string"},"retry_after_seconds":{"type":"integer"},"job_id":{"type":"string"},"errors":{"type":"object"}}},"Brief":{"type":"object","required":["destination"],"properties":{"destination":{"type":"string","maxLength":120},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"duration_days":{"type":"integer","minimum":1,"maximum":62},"origin_city":{"type":"string"},"travelers":{"type":"string","enum":["solo","couple","friends","family","custom"]},"adult_count":{"type":"integer"},"kid_count":{"type":"integer"},"getting_around":{"type":"string","enum":["walk_transit","own_car","rental_car","mix"]},"budget":{"type":"string","enum":["backpacker","mid_range","comfortable","luxury","custom"]},"budget_per_day_usd":{"type":"integer"},"budget_is_total":{"type":"boolean"},"style":{"type":"string","enum":["mixed","cultural","adventure","relaxed","custom"]},"style_note":{"type":"string"},"pace":{"type":"string","enum":["balanced","slow","packed","surprise","custom"]},"pace_note":{"type":"string"},"must_sees":{"type":"string"},"anchors":{"type":"object"}}},"Quota":{"type":"object","properties":{"credits":{"type":"integer"},"credits_max":{"type":"integer"},"trip_passes":{"type":"integer"},"max_free_days":{"type":"integer"},"is_plus":{"type":"boolean"}}},"DraftJob":{"type":"object","properties":{"job_id":{"type":"string"},"status":{"type":"string"},"stage":{"type":"string"},"destination":{"type":"string"},"expected_seconds":{"type":"integer"},"dates_assumed":{"type":"boolean","description":"True when the brief had no start_date: Lez picks the dates and the ready status names them in dates_note."},"quota":{"$ref":"#/components/schemas/Quota"},"next":{"type":"string"}}},"DraftStatus":{"type":"object","properties":{"job_id":{"type":"string"},"status":{"type":"string","enum":["queued","running","ready","failed"]},"stage":{"type":"string"},"destination":{"type":"string"},"elapsed_seconds":{"type":"integer"},"expected_seconds":{"type":"integer"},"progress":{"$ref":"#/components/schemas/DraftProgress"},"dates_assumed":{"type":"boolean","description":"True when Lez picked the dates because the brief had none."},"dates_note":{"type":"string","description":"Ready and dates_assumed only: the sentence to relay, e.g. \"I assumed Fri 6 – Sun 8 Nov 2026. Tell me your real dates and I'll shift the plan.\""},"error_code":{"type":"string"},"message":{"type":"string"},"next":{"type":"string"},"trip":{"$ref":"#/components/schemas/Trip"},"markdown":{"type":"string","description":"Ready only: the trip as markdown, opening with dates_note when dates were assumed."},"url":{"type":"string"},"quota":{"$ref":"#/components/schemas/Quota"}}},"DraftProgress":{"type":"object","description":"Compact on purpose: no coordinates or place ids. The full trip arrives with status ready.","properties":{"pool_count":{"type":["integer","null"],"description":"Places Lez is weighing, once the pool is built."},"days":{"type":["array","null"],"description":"Each day's chosen stop names, once Lez has picked them.","items":{"type":"object","properties":{"day":{"type":"integer"},"stops":{"type":"array","items":{"type":"string"}}}}}}},"TripSummary":{"type":"object","properties":{"id":{"type":"string"},"destination":{"type":"string"},"start_date":{"type":"string"},"end_date":{"type":"string"},"days":{"type":"integer"},"relation":{"type":"string","enum":["upcoming","happening_now","past"]},"role":{"type":"string","enum":["owner","editor","viewer"]},"url":{"type":"string"}}},"Trip":{"type":"object","properties":{"id":{"type":"string"},"destination":{"type":"string"},"start_date":{"type":"string"},"end_date":{"type":"string"},"day_count":{"type":"integer"},"url":{"type":"string"},"days":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"day_number":{"type":"integer"},"title":{"type":"string"},"date":{"type":"string"},"activities":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"location":{"type":"string"},"start_time":{"type":"string"},"duration_minutes":{"type":"integer"},"category":{"type":"string"}}}}}}},"reservations":{"type":"array","items":{"type":"object"}},"attention":{"type":"object"}}},"Proposal":{"type":"object","properties":{"proposal_id":{"type":"string"},"trip_id":{"type":"string"},"summary":{"type":"string"},"changes":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}},"expires_at":{"type":"string"}}},"Alerts":{"type":"object","properties":{"alerts":{"type":"array","items":{"type":"object","properties":{"trip_id":{"type":"string"},"destination":{"type":"string"},"trigger":{"type":"string"},"headline":{"type":"string"},"consequence":{"type":"string"},"day_number":{"type":"integer"},"url":{"type":"string"}}}},"checked_trips":{"type":"integer"}}}}},"externalDocs":{"url":"https://lezplanit.com/agents","description":"How to connect an AI assistant to LezPlanIt"}}