{"openapi":"3.1.0","paths":{"/public/v1/experiences/search":{"get":{"description":"Find upcoming fitness and wellness experiences (classes, run clubs, workouts, retreats, wellness sessions) that match what the user asked for, ranked by semantic relevance to `query`.\n\nUse it whenever the user wants something to do, join or attend — \"a beginner yoga class this weekend in Austin\", \"free run clubs near me\", \"sound bath under $30\". Put the activity and vibe in `query`; put place, dates and budget in the dedicated parameters rather than in `query`.\n\nLocation: send `lat` + `lng` (+ optional `radius_km`) when you know the user's position, otherwise `market` with a city slug from `GET /public/v1/markets` or a plain city name (\"Austin\" or \"Austin, TX\"). Without either, results are not location-filtered.\nDates default to the next 90 days. Only public, published experiences are returned, one entry per recurring series (its next matching date).\n\nPagination: when `next_cursor` is non-null, call again with the same parameters plus `cursor`. A page can contain fewer than `limit` results (e.g. when `price_max` filters some out) — keep going while `next_cursor` is non-null.\n\nExample: `GET /public/v1/experiences/search?query=sunrise%20trail%20run&market=austin-tx&date_from=2026-10-01&date_to=2026-10-07&price_max=20&limit=5`\n\nSend the user to each result's `url` to view and book; call `GET /public/v1/experiences/{id}` for full details.","operationId":"searchExperiences","parameters":[{"name":"query","required":true,"in":"query","description":"What the user is looking for, in natural language (1-300 chars). Activity, style, level and vibe work best.","schema":{"example":"beginner friendly sunrise trail run","type":"string"}},{"name":"lat","required":false,"in":"query","description":"Latitude of the search center. Must be sent together with `lng`; takes precedence over `market`.","schema":{"example":30.2672,"type":"number"}},{"name":"lng","required":false,"in":"query","description":"Longitude of the search center. Must be sent together with `lat`.","schema":{"example":-97.7431,"type":"number"}},{"name":"radius_km","required":false,"in":"query","description":"Radius around lat/lng in km (default 25, max 200). Requires lat and lng.","schema":{"example":10,"type":"number"}},{"name":"market","required":false,"in":"query","description":"City to search in: a `slug` from GET /public/v1/markets, or a city name optionally followed by \", region\". Ignored when lat/lng are sent. Unknown values return 400 INVALID_PARAMETER.","schema":{"example":"austin-tx","type":"string"}},{"name":"date_from","required":false,"in":"query","description":"Earliest start, ISO 8601 date or date-time. Defaults to now; past values are clamped to now.","schema":{"example":"2026-10-01","type":"string"}},{"name":"date_to","required":false,"in":"query","description":"Latest start, ISO 8601 date or date-time (a bare date includes that whole UTC day). Defaults to 90 days after date_from (or now); date_from..date_to may span at most 366 days.","schema":{"example":"2026-10-07","type":"string"}},{"name":"price_max","required":false,"in":"query","description":"Maximum ticket price in major units of `currency` (e.g. 20 = $20). Free and donation-based experiences always pass; priced ones in another currency are excluded.","schema":{"example":20,"type":"number"}},{"name":"currency","required":false,"in":"query","description":"ISO 4217 currency for price_max (default USD).","schema":{"example":"USD","type":"string"}},{"name":"limit","required":false,"in":"query","description":"Results per page (default 10, max 25).","schema":{"example":5,"type":"number"}},{"name":"cursor","required":false,"in":"query","description":"Opaque `next_cursor` from the previous page. Send it with exactly the same other parameters.","schema":{"example":"eyJvIjoxMCwicSI6IjNmMmExYjRjIn0","type":"string"}}],"responses":{"200":{"description":"Matching experiences, most relevant first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicExperiencesSearchResponseDto"},"example":{"results":[{"id":"0b7e5c1a-2f3d-4e5f-8a9b-0c1d2e3f4a5b","event_id":"9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a","title":"Sunrise Trail Run + Coffee","short_description":"An easy-paced 5K on the Butler trail followed by coffee with the crew. All paces welcome.","start":"2026-10-03T07:00:00-05:00","end":"2026-10-03T08:30:00-05:00","timezone":"America/Chicago","venue":{"name":"Zilker Park","address":"Austin, Texas, United States","lat":30.2669,"lng":-97.7729},"is_online":false,"market":{"slug":"austin-tx","name":"Austin","region":"Texas"},"price":{"amount":0,"currency":null,"is_free":true,"is_donation_based":false},"host":{"id":"6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f","name":"Austin Sunrise Runners","url":"https://sweatpals.com/host/austinsunriserunners"},"tags":["Running"],"availability":"limited","spots_remaining":4,"image_url":"https://edge.sweatpals.com/api/files/2c9f0a1b-3d4e-4f5a-9b8c-7d6e5f4a3b2c?variant=l","url":"https://sweatpals.com/event/sunrise-trail-run/2026-10-03/07-00?utm_source=agent&utm_medium=ai_agent&ref=agent"}],"next_cursor":"eyJvIjoxMCwicSI6IjNmMmExYjRjIn0","market":{"slug":"austin-tx","name":"Austin","region":"Texas"},"query":"trail run"}}}},"400":{"description":"A parameter is missing or invalid (INVALID_PARAMETER).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorDto"},"example":{"error":{"code":"INVALID_PARAMETER","message":"query must be longer than or equal to 1 characters"}}}}},"429":{"description":"Rate limit exceeded (RATE_LIMITED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorDto"},"example":{"error":{"code":"RATE_LIMITED","message":"Too many requests; slow down and retry after a minute."}}}}}},"summary":"Search fitness & wellness experiences","tags":["Public API"]}},"/public/v1/experiences/{id}":{"get":{"description":"Full details for one experience occurrence returned by search: complete description, refund policy, skill level, gallery images, live availability and a direct `booking_url` (checkout).\n\nUse it after search when the user shows interest in a specific result or asks a follow-up (\"is it beginner friendly?\", \"can I get a refund?\", \"how many spots are left?\"). `id` is the `id` field of a search result.\n\nExample: `GET /public/v1/experiences/0b7e5c1a-2f3d-4e5f-8a9b-0c1d2e3f4a5b`\n\nReturns `404 NOT_FOUND` for unknown ids and for experiences that are no longer public. Booking always happens on Sweatpals via `url` or `booking_url`.","operationId":"getExperience","parameters":[{"name":"id","required":true,"in":"path","description":"The `id` of a search result.","schema":{"example":"0b7e5c1a-2f3d-4e5f-8a9b-0c1d2e3f4a5b","type":"string"}}],"responses":{"200":{"description":"The experience with full details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicExperienceDetailDto"},"example":{"id":"0b7e5c1a-2f3d-4e5f-8a9b-0c1d2e3f4a5b","event_id":"9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a","title":"Sunrise Trail Run + Coffee","short_description":"An easy-paced 5K on the Butler trail followed by coffee with the crew. All paces welcome.","start":"2026-10-03T07:00:00-05:00","end":"2026-10-03T08:30:00-05:00","timezone":"America/Chicago","venue":{"name":"Zilker Park","address":"Austin, Texas, United States","lat":30.2669,"lng":-97.7729},"is_online":false,"market":{"slug":"austin-tx","name":"Austin","region":"Texas"},"price":{"amount":0,"currency":null,"is_free":true,"is_donation_based":false},"host":{"id":"6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f","name":"Austin Sunrise Runners","url":"https://sweatpals.com/host/austinsunriserunners"},"tags":["Running"],"availability":"limited","spots_remaining":4,"image_url":"https://edge.sweatpals.com/api/files/2c9f0a1b-3d4e-4f5a-9b8c-7d6e5f4a3b2c?variant=l","url":"https://sweatpals.com/event/sunrise-trail-run/2026-10-03/07-00?utm_source=agent&utm_medium=ai_agent&ref=agent","description":"Meet at the Zilker Park boathouse at 6:50. **Easy pace**, no one gets left behind. Coffee on us afterwards.","refund_policy":null,"skill_level":"beginner","booking_url":"https://sweatpals.com/event/sunrise-trail-run/2026-10-03/07-00/checkout?utm_source=agent&utm_medium=ai_agent&ref=agent","gallery_image_urls":["https://edge.sweatpals.com/api/files/4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d?variant=l"]}}}},"404":{"description":"Unknown id or no longer public (NOT_FOUND).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorDto"},"example":{"error":{"code":"NOT_FOUND","message":"No public experience with this id; ids come from GET /api/public/v1/experiences/search"}}}}},"429":{"description":"Rate limit exceeded (RATE_LIMITED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorDto"},"example":{"error":{"code":"RATE_LIMITED","message":"Too many requests; slow down and retry after a minute."}}}}}},"summary":"Get one experience in detail","tags":["Public API"]}},"/public/v1/markets":{"get":{"description":"Lists the cities (markets) where Sweatpals is active, with the `slug` to pass as `market` to search, the city center coordinates and a link to the city's discovery page.\n\nUse it to turn a city the user mentions into a valid `market` value, to check whether Sweatpals covers a city, or to suggest nearby covered cities. Searching still works outside these markets with `lat`/`lng`.\n\nExample: `GET /public/v1/markets`","operationId":"listMarkets","parameters":[],"responses":{"200":{"description":"All active markets, alphabetically.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicMarketsResponseDto"},"example":{"markets":[{"slug":"austin-tx","name":"Austin","region":"Texas","country":"United States","lat":30.2672,"lng":-97.7431,"url":"https://sweatpals.com/discover?city=austin"},{"slug":"new-york-ny","name":"New York","region":"New York","country":"United States","lat":40.7128,"lng":-74.006,"url":"https://sweatpals.com/discover?city=new_york"}]}}}},"429":{"description":"Rate limit exceeded (RATE_LIMITED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorDto"},"example":{"error":{"code":"RATE_LIMITED","message":"Too many requests; slow down and retry after a minute."}}}}}},"summary":"List Sweatpals markets (cities)","tags":["Public API"]}},"/public/v1/openapi.json":{"get":{"description":"This OpenAPI 3.1 document. Import it into an agent framework, a custom GPT action or an MCP/OpenAPI connector to get typed tools for the other endpoints.\n\nExample: `GET /public/v1/openapi.json`","operationId":"getOpenapiDocument","parameters":[],"responses":{"200":{"description":"OpenAPI 3.1 document.","content":{"application/json":{"schema":{"type":"object"},"example":{"openapi":"3.1.0","info":{"title":"Sweatpals Public API","version":"1.0.0"}}}}}},"summary":"OpenAPI document for this API","tags":["Public API"]}}},"info":{"title":"Sweatpals Public API","description":"Read-only API for AI agents and assistants to discover fitness and wellness experiences (run clubs, yoga, pilates, bootcamps, sound baths, social workouts, ...) hosted on Sweatpals.\n\n- **No authentication.** No API key, no OAuth — call it directly.\n- **Read-only.** Nothing can be booked or changed through this API. To book, send the user to the `url` (event page) or `booking_url` (checkout) returned for each experience; payment and sign-in happen on Sweatpals.\n- **Attribution.** Returned links already carry `utm_source`, `utm_medium=ai_agent` and `ref` — keep them intact when you show a link.\n- **Freshness.** Responses are cached for up to 60 seconds; availability and spots can lag by that much.\n- **Rate limits.** Per client IP: 600 requests/minute for search, 1200 requests/minute for the other endpoints. Limits are currently observed, not enforced; design for ~600 requests/min per IP. Once enforced, exceeding them returns `429` with error code `RATE_LIMITED`.\n- **Errors.** Always `{ \"error\": { \"code\", \"message\" } }` with code `INVALID_PARAMETER` (400), `NOT_FOUND` (404), `RATE_LIMITED` (429), `INTERNAL_ERROR` (500) or `SERVICE_UNAVAILABLE` (503).\n- **Base path:** `/public/v1` under the server URL below. Field names are snake_case, optional fields are always present as `null`, and times are ISO 8601 with the venue's UTC offset.\n\nTypical flow: `GET /public/v1/markets` (optional, to learn city slugs) → `GET /public/v1/experiences/search?query=...` → `GET /public/v1/experiences/{id}` for the one the user picks → share its `url`.","version":"1.0.0","contact":{}},"tags":[],"servers":[{"url":"https://ilove.sweatpals.com/api"}],"components":{"schemas":{"PublicVenueDto":{"type":"object","properties":{"name":{"type":["string","null"],"description":"Venue or place name as the host entered it.","example":"Zilker Park"},"address":{"type":["string","null"],"description":"\"City, Region, Country\" of the venue; street addresses are not exposed.","example":"Austin, Texas, United States"},"lat":{"type":["number","null"],"example":30.2669},"lng":{"type":["number","null"],"example":-97.7729}},"required":["name","address","lat","lng"]},"PublicMarketRefDto":{"type":"object","properties":{"slug":{"type":"string","description":"Stable market identifier; pass it as `market` to search.","example":"austin-tx"},"name":{"type":"string","description":"City name.","example":"Austin"},"region":{"type":["string","null"],"description":"State / region name.","example":"Texas"}},"required":["slug","name","region"]},"PublicPriceDto":{"type":"object","properties":{"amount":{"type":["number","null"],"description":"Lowest ticket price checkout charges now (active time-based offers applied), in major units (e.g. 25.5 = $25.50); 0 when free, the minimum donation when donation-based, null when unknown.","example":25},"currency":{"type":["string","null"],"description":"ISO 4217 currency of `amount`; null when free or unknown.","example":"USD"},"is_free":{"type":"boolean","example":false},"is_donation_based":{"type":"boolean","description":"Pay-what-you-want; `amount` is the minimum donation when set.","example":false}},"required":["amount","currency","is_free","is_donation_based"]},"PublicHostDto":{"type":"object","properties":{"id":{"type":"string","example":"6f1c2d3e-4b5a-4c6d-8e7f-9a0b1c2d3e4f"},"name":{"type":"string","description":"Host (community or person) display name.","example":"Austin Sunrise Runners"},"url":{"type":"string","description":"Host page on Sweatpals.","example":"https://sweatpals.com/host/austinsunriserunners"}},"required":["id","name","url"]},"PublicExperienceAvailability":{"type":"string","enum":["available","limited","sold_out","waitlist","unknown"],"description":"`limited` = 5 or fewer spots left; `waitlist` = sold out with an open waitlist; `unknown` = could not be determined (never implies sold out)."},"PublicExperienceSummaryDto":{"type":"object","properties":{"id":{"type":"string","description":"Occurrence id; pass it to `GET /experiences/{id}`.","example":"0b7e5c1a-2f3d-4e5f-8a9b-0c1d2e3f4a5b"},"event_id":{"type":"string","description":"Series id shared by every occurrence of a recurring experience (informational).","example":"9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a"},"title":{"type":"string","example":"Sunrise Trail Run + Coffee"},"short_description":{"type":["string","null"],"description":"Plain-text summary, at most 300 characters.","example":"An easy-paced 5K on the Butler trail followed by coffee with the crew. All paces welcome."},"start":{"type":"string","description":"Start in ISO 8601 with the venue's UTC offset.","example":"2026-10-03T07:00:00-05:00"},"end":{"type":["string","null"],"description":"End in ISO 8601 with the venue's UTC offset.","example":"2026-10-03T08:30:00-05:00"},"timezone":{"type":"string","description":"IANA time zone of the venue.","example":"America/Chicago"},"venue":{"description":"Physical location; null for online experiences.","oneOf":[{"$ref":"#/components/schemas/PublicVenueDto"},{"type":"null"}]},"is_online":{"type":"boolean","example":false},"market":{"description":"Sweatpals market the experience belongs to, when its city is an onboarded market.","oneOf":[{"$ref":"#/components/schemas/PublicMarketRefDto"},{"type":"null"}]},"price":{"$ref":"#/components/schemas/PublicPriceDto"},"host":{"$ref":"#/components/schemas/PublicHostDto"},"tags":{"description":"Activity tags (e.g. Running, Yoga).","example":["Running"],"type":"array","items":{"type":"string"}},"availability":{"description":"`limited` = 5 or fewer spots left; `waitlist` = sold out with an open waitlist; `unknown` = could not be determined (never implies sold out).","example":"available","allOf":[{"$ref":"#/components/schemas/PublicExperienceAvailability"}]},"spots_remaining":{"type":["number","null"],"description":"Spots left; null when capacity is unlimited or unknown.","example":12},"image_url":{"type":["string","null"],"example":"https://edge.sweatpals.com/api/files/2c9f0a1b-3d4e-4f5a-9b8c-7d6e5f4a3b2c?variant=l"},"url":{"type":"string","description":"Canonical event page; send the user here to view and book.","example":"https://sweatpals.com/event/sunrise-trail-run/2026-10-03?utm_source=agent&utm_medium=ai_agent&ref=agent"}},"required":["id","event_id","title","short_description","start","end","timezone","venue","is_online","market","price","host","tags","availability","spots_remaining","image_url","url"]},"PublicExperiencesSearchResponseDto":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/PublicExperienceSummaryDto"}},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` (with the same other params) for the next page; null on the last page. Pages may hold fewer than `limit` results.","example":"eyJvIjoxMCwicSI6IjNmMmExYjRjIn0"},"market":{"description":"Market the search was scoped to, when `market` resolved.","oneOf":[{"$ref":"#/components/schemas/PublicMarketRefDto"},{"type":"null"}]},"query":{"type":"string","description":"The query as interpreted (trimmed).","example":"trail run"}},"required":["results","next_cursor","market","query"]},"PublicApiErrorCode":{"type":"string","enum":["INVALID_PARAMETER","NOT_FOUND","RATE_LIMITED","INTERNAL_ERROR","SERVICE_UNAVAILABLE"]},"PublicApiErrorBodyDto":{"type":"object","properties":{"code":{"example":"INVALID_PARAMETER","allOf":[{"$ref":"#/components/schemas/PublicApiErrorCode"}]},"message":{"type":"string","description":"Human-readable explanation, safe to show or act on.","example":"query must be longer than or equal to 1 characters"}},"required":["code","message"]},"PublicApiErrorDto":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/PublicApiErrorBodyDto"}},"required":["error"]},"PublicSkillLevel":{"type":"string","enum":["beginner","intermediate","advanced"]},"PublicExperienceDetailDto":{"type":"object","properties":{"id":{"type":"string","description":"Occurrence id; pass it to `GET /experiences/{id}`.","example":"0b7e5c1a-2f3d-4e5f-8a9b-0c1d2e3f4a5b"},"event_id":{"type":"string","description":"Series id shared by every occurrence of a recurring experience (informational).","example":"9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a"},"title":{"type":"string","example":"Sunrise Trail Run + Coffee"},"short_description":{"type":["string","null"],"description":"Plain-text summary, at most 300 characters.","example":"An easy-paced 5K on the Butler trail followed by coffee with the crew. All paces welcome."},"start":{"type":"string","description":"Start in ISO 8601 with the venue's UTC offset.","example":"2026-10-03T07:00:00-05:00"},"end":{"type":["string","null"],"description":"End in ISO 8601 with the venue's UTC offset.","example":"2026-10-03T08:30:00-05:00"},"timezone":{"type":"string","description":"IANA time zone of the venue.","example":"America/Chicago"},"venue":{"description":"Physical location; null for online experiences.","oneOf":[{"$ref":"#/components/schemas/PublicVenueDto"},{"type":"null"}]},"is_online":{"type":"boolean","example":false},"market":{"description":"Sweatpals market the experience belongs to, when its city is an onboarded market.","oneOf":[{"$ref":"#/components/schemas/PublicMarketRefDto"},{"type":"null"}]},"price":{"$ref":"#/components/schemas/PublicPriceDto"},"host":{"$ref":"#/components/schemas/PublicHostDto"},"tags":{"description":"Activity tags (e.g. Running, Yoga).","example":["Running"],"type":"array","items":{"type":"string"}},"availability":{"description":"`limited` = 5 or fewer spots left; `waitlist` = sold out with an open waitlist; `unknown` = could not be determined (never implies sold out).","example":"available","allOf":[{"$ref":"#/components/schemas/PublicExperienceAvailability"}]},"spots_remaining":{"type":["number","null"],"description":"Spots left; null when capacity is unlimited or unknown.","example":12},"image_url":{"type":["string","null"],"example":"https://edge.sweatpals.com/api/files/2c9f0a1b-3d4e-4f5a-9b8c-7d6e5f4a3b2c?variant=l"},"url":{"type":"string","description":"Canonical event page; send the user here to view and book.","example":"https://sweatpals.com/event/sunrise-trail-run/2026-10-03?utm_source=agent&utm_medium=ai_agent&ref=agent"},"description":{"type":["string","null"],"description":"Full description as the host wrote it (may contain Markdown).","example":"Meet at the Zilker Park boathouse. **Easy pace**, no one gets left behind."},"refund_policy":{"type":["string","null"],"example":"Full automatic refund if cancelled more than 24 hours before the start."},"skill_level":{"example":"beginner","oneOf":[{"$ref":"#/components/schemas/PublicSkillLevel"},{"type":"null"}]},"booking_url":{"type":"string","description":"Opens checkout directly; same attribution params as `url`.","example":"https://sweatpals.com/event/sunrise-trail-run/2026-10-03/checkout?utm_source=agent&utm_medium=ai_agent&ref=agent"},"gallery_image_urls":{"example":["https://edge.sweatpals.com/api/files/4a5b6c7d-8e9f-4a0b-9c1d-2e3f4a5b6c7d?variant=l"],"type":"array","items":{"type":"string"}}},"required":["id","event_id","title","short_description","start","end","timezone","venue","is_online","market","price","host","tags","availability","spots_remaining","image_url","url","description","refund_policy","skill_level","booking_url","gallery_image_urls"]},"PublicMarketDto":{"type":"object","properties":{"slug":{"type":"string","description":"Pass as `market` to search.","example":"austin-tx"},"name":{"type":"string","example":"Austin"},"region":{"type":["string","null"],"example":"Texas"},"country":{"type":["string","null"],"example":"United States"},"lat":{"type":["number","null"],"example":30.2672},"lng":{"type":["number","null"],"example":-97.7431},"url":{"type":"string","description":"Sweatpals discovery page for this market; the generic discover page (no city) when another market shares this city name.","example":"https://sweatpals.com/discover?city=austin"}},"required":["slug","name","region","country","lat","lng","url"]},"PublicMarketsResponseDto":{"type":"object","properties":{"markets":{"type":"array","items":{"$ref":"#/components/schemas/PublicMarketDto"}}},"required":["markets"]}}}}