Limits follow your plan: Developer is 1 key, 50 requests a day and a 3-day forecast and tides for 60 days; Starter is 2 keys and 500 a day with the full 7 days; Growth and Pro go up from there.
Checking your access…
Confirm your email
Open the link we emailed to , then come back here. Nothing in your inbox? We can send it again.
Access is by invite
Your account is ready, but it is not on the list yet. Email us from this address with a line about what you are building: we read every message and we will set you up.
Developer access lasts 60 days and yours is over, so your key no longer answers. Write to us with the plan you want and we switch your account over. The same key starts working again within a few minutes.
contact@surf-map.com
Create your first key
One name, one click, and you can make your first call in a minute.
Save it now. You will not see the full key again, only its prefix.
Your keys
Loading your keys…
No keys yet. Create your first one above.
Usage
Requests per key, counted per UTC day. The quota resets at midnight UTC.
Last 30 days
Requests per day, last 30 days, UTC.
Create a key to see usage.
By endpoint
Where the last 30 days went.
API reference
Surf spot database, 7-day hourly forecasts rated 1 to 5 for beginner, intermediate and advanced surfers, and tide extremes for 5,877 named surf spots. JSON over HTTPS, metric units, UTC times. Weather inputs include Open-Meteo data (CC BY 4.0).
Basics
Base URL
https://api.surf-map.com
Auth
X-API-Key: sm_live_… or Authorization: Bearer sm_live_… on every /v1 and /mcp request.
Rate limits
X-RateLimit-Limit, X-RateLimit-Remaining (daily), X-RateLimit-Reset (next UTC midnight, ISO 8601). Sent on every authenticated /v1 and /mcp response. Per-minute burst by plan: Developer 10, Starter 60, Growth 120, Pro 300. Over it you get a 429 with Retry-After.
Horizon
Horizon in days, 1 to 7 (default 7); anything else is a 400 invalid_request. Above your plan's horizon (3 on Developer) the value is clamped to the horizon, not rejected.
Freshness
Forecasts refresh about twice a day. Every forecast and tides response carries aCache-Control max-age and an updatedAt: honor them, cache on your own server for at most 24 hours, and never store or redistribute the data beyond that.
Units
Metric everywhere: meters, seconds, km/h, Celsius. Times are ISO 8601 in UTC.
Errors
Every error body is { "error": { "code", "message" } }. Codes: invalid_key, account_disabled, not_found, no_forecast, rate_limited, invalid_request, internal.
MCP
POST https://api.surf-map.com/mcp with the same key in X-API-Key. Tools: search_spots(query, limit?), spots_nearby(lat, lng, radius_km?, limit?), get_forecast(spot_id, days?), get_tides(spot_id, days?). Tool calls count toward the same quota.
GET/v1/spots
Search spots by name, alias, or country
Case- and diacritic-insensitive search. q is required (at least 2 characters); there is no unfiltered listing. Returns a bare JSON array.
Parameters
Name
In
Type
Notes
qrequired
query
string, at least 2 chars
Example: hossegor
limit
query
integer, 1..50, default 10
Response
200 Matching spots, best match first. Body: Array of Spot.
Field
Type
Notes
id
string
Stable slug id, e.g. anchor-point.
name
string
The local name of the spot.
aka
string
International nickname when name is the local endonym (Punta Elena, aka Rocky Point). Only present when the catalog has one; search matches it too.
country
string
First segment of the spot's country string.
region
string | null
Remaining segments, or null.
lat
number
lng
number
Errors
400 Invalid parameters.
401 Missing, unknown, or revoked API key (code invalid_key), or a key whose account is disabled or whose 60-day Developer access has ended (code account_disabled, the message gives the end date).
429 Daily quota or per-minute burst exceeded. Retry-After header is set.
International nickname when name is the local endonym (Punta Elena, aka Rocky Point). Only present when the catalog has one; search matches it too.
country
string
First segment of the spot's country string.
region
string | null
Remaining segments, or null.
lat
number
lng
number
distanceKm
number
Errors
400 Invalid parameters.
401 Missing, unknown, or revoked API key (code invalid_key), or a key whose account is disabled or whose 60-day Developer access has ended (code account_disabled, the message gives the end date).
429 Daily quota or per-minute burst exceeded. Retry-After header is set.
International nickname when name is the local endonym (Punta Elena, aka Rocky Point). Only present when the catalog has one; search matches it too.
country
string
First segment of the spot's country string.
region
string | null
Remaining segments, or null.
lat
number
lng
number
Errors
401 Missing, unknown, or revoked API key (code invalid_key), or a key whose account is disabled or whose 60-day Developer access has ended (code account_disabled, the message gives the end date).
404 Unknown spot (code not_found).
429 Daily quota or per-minute burst exceeded. Retry-After header is set.
Hourly conditions from the current UTC hour forward, refreshed twice a day. waveDirection is the primary swell direction (true wave direction is not persisted). tide is null for tideless spots. Responds 404 with code no_forecast when the spot exists but has no forecast document yet.
Parameters
Name
In
Type
Notes
idrequired
path
string
Spot slug (e.g. anchor-point) or raw 16-hex id. Example: anchor-point
days
query
integer, 1..7, default 7
Horizon in days, 1 to 7 (default 7); anything else is a 400 invalid_request. Above your plan's horizon (3 on Developer) the value is clamped to the horizon, not rejected.
401 Missing, unknown, or revoked API key (code invalid_key), or a key whose account is disabled or whose 60-day Developer access has ended (code account_disabled, the message gives the end date).
404 Unknown spot (code not_found), or no forecast yet for a known spot (code no_forecast).
429 Daily quota or per-minute burst exceeded. Retry-After header is set.
Stored tide extremes from now forward. Tideless spots return 200 with an empty extremes array and tideless true.
Parameters
Name
In
Type
Notes
idrequired
path
string
Spot slug (e.g. anchor-point) or raw 16-hex id. Example: anchor-point
days
query
integer, 1..7, default 7
Horizon in days, 1 to 7 (default 7); anything else is a 400 invalid_request. Above your plan's horizon (3 on Developer) the value is clamped to the horizon, not rejected.
401 Missing, unknown, or revoked API key (code invalid_key), or a key whose account is disabled or whose 60-day Developer access has ended (code account_disabled, the message gives the end date).
404 Unknown spot (code not_found), or no forecast yet for a known spot (code no_forecast).
429 Daily quota or per-minute burst exceeded. Retry-After header is set.
401 Missing, unknown, or revoked API key (code invalid_key), or a key whose account is disabled or whose 60-day Developer access has ended (code account_disabled, the message gives the end date).
429 Daily quota or per-minute burst exceeded. Retry-After header is set.
code is one of "invalid_key", "account_disabled", "not_found", "no_forecast", "rate_limited", "invalid_request", "internal".
Account
Who you are here, what your plan allows, and the two buttons you rarely need.
Your account
Email
confirmed
Plan
…
Active keys
…
Requests
…
Horizon
…
Change plan
Starter is $39 a month (2 keys, 500 requests a day), Growth $99 (5 keys, 2,500 a day), Pro $249 (10 keys, 10,000 a day, no attribution required). Above that, Scale is custom. Write to us with the plan you want and we switch your account over. Your existing keys keep working.
contact@surf-map.com
Security
Reset your password from here, or sign out of this browser.