Quickstart
This guide takes you from an API key to a forecast you can use: list the variables, request a point forecast and read the series it returns.
1. Get an API key
i4sea issues API keys to companies with an API subscription. Ask your i4sea account manager for a key; it looks like
i4s_live_ followed by 32 letters and digits.
The full key is shown once, when it is created. i4sea keeps only a one-way hash and cannot show it again, so
store it right away in your secrets manager or as an environment variable. The examples below read it from
I4SEA_API_KEY:
export I4SEA_API_KEY="i4s_live_..."
Every request sends the key in the Authorization header. See Authentication for how to
store and rotate it.
2. List the variables
The base URL is https://api.i4sea.com.br/i4cast/v1. Start with the variable catalogue, which costs no units:
curl -s "https://api.i4sea.com.br/i4cast/v1/forecast/variables?type=weather" \
-H "Authorization: Bearer $I4SEA_API_KEY"
{
"types": [
{
"type": "weather",
"variables": [
{
"name": "wind_speed_10m",
"description": "Wind speed at 10 m above the surface",
"dimension": "speed",
"default": true,
"units": { "si": "m/s", "metric": "km/h", "nautical": "kt" }
}
]
}
]
}
There are four forecast types: weather, waves, ocean and visibility. Leave out type to list all of them.
Variables marked "default": true are returned when you do not ask for specific ones.
3. Request a point forecast
GET /forecast/point returns the forecast for one coordinate, in decimal degrees:
curl -s "https://api.i4sea.com.br/i4cast/v1/forecast/point?latitude=-23.9545&longitude=-46.3278&type=weather&hours=24" \
-H "Authorization: Bearer $I4SEA_API_KEY"
| Parameter | Required | Values | Default |
|---|---|---|---|
latitude | yes | −90 to 90 | |
longitude | yes | −180 to 180 | |
type | yes | weather, waves, ocean, visibility | |
variables | no | comma-separated variable names for that type | the type's default set |
hours | no | 1 to 360 | 72 |
units | no | si, metric, nautical | si |
The point must lie inside your company's contracted coverage; outside it the API answers
403 outside_coverage and charges nothing. Each successful point forecast costs 1 unit
of your monthly quota (see Limits and quotas).
4. Read the response
{
"status": "ok",
"latitude": -23.9545,
"longitude": -46.3278,
"sampled_latitude": -23.95,
"sampled_longitude": -46.33,
"type": "weather",
"model": { "name": "wrf3km", "run_published_at": "2026-10-01T06:42:00Z" },
"timezone": "America/Sao_Paulo",
"units_system": "si",
"horizon_limited": false,
"time": ["2026-10-01T12:00:00Z", "2026-10-01T13:00:00Z"],
"series": [
{ "name": "wind_speed_10m", "units": "m/s", "values": [5.42, 6.01] },
{ "name": "wind_from_direction_10m", "units": "degree", "values": [185, 190] }
],
"unavailable_variables": []
}
timeholds the forecast steps, in UTC (ISO 8601 withZ). The interval is the one of the model that serves the point, so read it fromtimerather than assuming hourly steps.timezoneis the point's IANA time zone, for when you want to show local time.seriesholds one entry per variable.values[i]is the value attime[i];nullmarks a missing step. Look series up bynamerather than by position.unitson each series is the unit its values are in. Read it instead of assuming one.sampled_latitude/sampled_longitudeare the model grid point that was read for your coordinate.modelnames the model that produced the data and when its run was published.run_published_atcan benull.horizon_limitedistruewhen your plan's forecast horizon is shorter than thehoursyou asked for; the series then stop at the plan's horizon.unavailable_variableslists requested variables that could not be returned for this point.
A point with no forecast for that type (for example, waves over land) is still a 200, with "status": "no_data",
empty time and series, and a note explaining why. Check status before reading the series.
Turning the columns into rows, in JavaScript (Node.js 18 or later):
const url = new URL('https://api.i4sea.com.br/i4cast/v1/forecast/point');
url.search = new URLSearchParams({ latitude: '-23.9545', longitude: '-46.3278', type: 'weather', hours: '24' });
const response = await fetch(url, { headers: { Authorization: `Bearer ${process.env.I4SEA_API_KEY}` } });
if (!response.ok) {
const problem = await response.json();
throw new Error(`${response.status} ${problem.code}: ${problem.detail} (request_id ${problem.request_id})`);
}
const forecast = await response.json();
const rows =
forecast.status === 'no_data'
? []
: forecast.time.map((time, i) => ({
time,
...Object.fromEntries(forecast.series.map((series) => [series.name, series.values[i]])),
}));
And in Python, with requests:
import os
import requests
response = requests.get(
"https://api.i4sea.com.br/i4cast/v1/forecast/point",
params={"latitude": -23.9545, "longitude": -46.3278, "type": "weather", "hours": 24},
headers={"Authorization": f"Bearer {os.environ['I4SEA_API_KEY']}"},
timeout=35,
)
if not response.ok:
problem = response.json()
raise RuntimeError(f"{response.status_code} {problem['code']}: {problem['detail']} ({problem['request_id']})")
forecast = response.json()
rows = [] if forecast["status"] == "no_data" else [
{"time": time, **{s["name"]: s["values"][i] for s in forecast["series"]}}
for i, time in enumerate(forecast["time"])
]
5. Choose your units
Values are in SI units unless you pass units. The variable catalogue gives the unit of each variable in each
system; by quantity:
| Quantity | si | metric | nautical |
|---|---|---|---|
| wind, gust and current speed | m/s | km/h | kt |
| temperature | K | °C | °C |
| pressure | Pa | hPa | hPa |
| visibility | m | km | km |
| wave height, water level | m | m | m |
| direction | degree | degree | degree |
| relative humidity, cloud cover, probability | % | % | % |
| precipitation | mm | mm | mm |
| wave period | s | s | s |
Directions follow the variable name: wind and waves are given as the direction they come from
(wind_from_direction_10m, wave_from_direction), currents as the direction they flow to
(current_to_direction).
Next steps
- API reference: every parameter and field, with each endpoint's scope and cost.
- Limits and quotas: the limit headers and how to stay inside your plan.
- Errors: the error format and when to retry.