Swell Cabin › Developers
Swell Cabin API
A free JSON API with no key: 130 surf towns and 492 surf spots worldwide, a 7-day surf forecast rated for each spot, places to stay, what the surf cams show and where the surf is good now. HTTPS, open to browsers (CORS). Every answer is the same data the site shows, with a link to the town's page.
Start here
curl 'https://swellcabin.com/api/towns?q=portugal&month=10'
curl 'https://swellcabin.com/api/forecast?town=ericeira'
- Base URL:
https://swellcabin.com, HTTPS only. - No key, no sign-up. Every endpoint only reads, and answers JSON (UTF-8).
- CORS: open (
Access-Control-Allow-Origin: *), so a web page can call it straight from the browser. - Limits: each IP address can make 600 requests a minute to our own data (towns, events, surf now, cam readings) and 180 a minute to the endpoints that call an outside service (forecast, places, feed, photos, social). Past that you get
429 Too many requestswithRetry-After. Answers are cached, so please cache them too: a forecast changes about once an hour. - Machine-readable spec: openapi.json (OpenAPI 3.1; works as ChatGPT GPT Actions). For AI assistants there is also an MCP server with the same data.
- Where the data comes from: waves from Open-Meteo (checked against NOAA, Copernicus Marine, Queensland and IOLR buoys and satellite altimeters), wind from MET Norway, sea temperatures from NASA and NOAA satellites, tides from the nearest tide gauge, places from OpenStreetMap and Overture Maps, and reviewed published sources for spots and events. When you show it, please name Swell Cabin and link the town's page (each answer has its
url). - Terms: terms and privacy. Questions: daniel@swellcabin.com.
GET /api/towns
Surf towns, filtered.
| Parameter | What it is | |
|---|---|---|
q | optional | Text: town, country or region |
region | optional | Region name |
month | optional | Good surf in this month: towns in season then, ranked by measured good + great days that month, each with inMonth { goodDays, greatDays, seaTempC, waveHeightM } |
level | optional | beginner | intermediate | advanced |
break | optional | beach | reef | point | rivermouth |
Try it: /api/towns?q=portugal&month=10
Answer: Towns
GET /api/towns/{slug}
One town with its surf spots, and surfByMonth: how often the surf was good and great in each month, measured over the last three years.
| Parameter | What it is | |
|---|---|---|
slug | required |
Try it: /api/towns/ericeira?slug=
Answer: Town
GET /api/places
Places to stay (hotels, hostels, surf camps, homestays...), cafés, food or surf shops/schools near a town; reviewed photos come as photo { thumb, page, author, license }.
| Parameter | What it is | |
|---|---|---|
town | required | Town slug |
category | optional | stay | coffee | food | surf | spots |
radiusKm | optional | Search radius |
Try it: /api/places?town=ericeira
Answer: Places, nearest first
GET /api/events
What's on: weekly nights and upcoming events in a town.
| Parameter | What it is | |
|---|---|---|
town | required | Town slug |
Try it: /api/events?town=ericeira
Answer: Weekly schedule and events
GET /api/feed
A town's Feed: recent YouTube surf videos about the town (last 30 days, at most two per channel), the latest posts from its local Instagram accounts and public Bluesky/Mastodon posts, each through Swell Cabin's quality check (ads, off-topic, unwatched and repeated posts left out) and with langs (the languages it is written in, when clear; the site shows each visitor what is in English or their language); part=classics gives the surf clips picked for its breaks.
| Parameter | What it is | |
|---|---|---|
town | required | Town slug, or "all" for every town at once (each video and post then has its town) |
part | optional | videos, posts or classics (optional) (videos, posts, classics) |
review | optional | 1 to also list what the quality check left out, with why (dropped) (1) |
Try it: /api/feed?town=ericeira
Answer: videos, posts, instagram { accounts, posts }, quality { checked, kept, dropped, langs }
GET /api/forecast
7-day surf forecast for a town and each of its spots, rated per spot hour by hour (Flat … Epic, best time, why): surf height, swell, wind, tides, model confidence. Add live=1 for the nearest buoy and airport wind report right now.
| Parameter | What it is | |
|---|---|---|
town | required | Town slug |
Try it: /api/forecast?town=ericeira
Answer: Forecast by day and for the next 48 hours
GET /api/surf-now
Where the surf is good around the world in the next days: towns whose best day from today is at least min (fair, good, great, epic), best and soonest first, with that day's rating at the best spot, the spot, its best time and the surf in words, and today's rating; from the forecast for every town, worked out twice a day.
| Parameter | What it is | |
|---|---|---|
min | optional | fair | good | great | epic (default good) |
within | optional | Days from today, 1–4 (default 3) |
region | optional | Region name |
Try it: /api/surf-now
Answer: generated, stale, towns [{ slug, name, lat, lng, url, best { date, when, rating, spot, from, to, surf }, today }]
GET /api/cam-now
What the surf cams show right now: every 3 hours in daylight an AI reads a still from each free surf cam and says what it shows in the forecast's own words (size, surface, surfers out, how sure) and what that means at the spot (Looks good, Surfable, Looks poor, Flat); the latest reading per spot from the last 3 hours, with the cam's link and what the forecast said then. A reading of a picture, not a measurement.
| Parameter | What it is | |
|---|---|---|
town | optional | Town slug; leave out for every town with a reading now |
good | optional | 1: only the spots that look good |
Try it: /api/cam-now
Answer: One town: readings [{ spot, time, local, words, surface, crowd, sure, verdict, label, reason, cam, provider, forecast { words, rating, steps } }], leftOut; every town: towns [{ slug, name, url, readings }]
GET /api/social
Swell Cabin's social posts from its own data (swell alerts, the best day this week, the weekend's best towns, season openings, surf events, where to surf this month, town spotlights, about Swell Cabin, and the weekly stories), each written for Instagram, Facebook, Threads, X, Bluesky and Mastodon with its time, link and card image; without a town, the latest daily proposal and what is scheduled.
| Parameter | What it is | |
|---|---|---|
town | optional | Town slug (optional) |
Try it: /api/social
Answer: posts [{ kind, summary, card, posts [{ channel, text, dueAt }], facts }]
GET /api/card
The image (PNG) for one of Swell Cabin's social posts, drawn from the query that /api/social gives each post (card, story).
| Parameter | What it is | |
|---|---|---|
k | required | Kind: swell-alert, best-day, weekend, season, event, month, spotlight, intro, swell-track, numbers, locals, beginners, night or spot |
row | optional | On a list, the row to draw as its own photo slide |
f | optional | story for 1080×1920, og for the 1200×630 link preview (default 1080×1350) (story, og) |
Answer: PNG image
GET /api/spot-photos
Photos of surf at each spot in a town, with credits.
| Parameter | What it is | |
|---|---|---|
town | required | Town slug |
Try it: /api/spot-photos?town=ericeira
Answer: Photos by spot name