Skip to content
i4seaAPI documentation

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"
ParameterRequiredValuesDefault
latitudeyes−90 to 90
longitudeyes−180 to 180
typeyesweather, waves, ocean, visibility
variablesnocomma-separated variable names for that typethe type's default set
hoursno1 to 36072
unitsnosi, metric, nauticalsi

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": []
}
  • time holds the forecast steps, in UTC (ISO 8601 with Z). The interval is the one of the model that serves the point, so read it from time rather than assuming hourly steps. timezone is the point's IANA time zone, for when you want to show local time.
  • series holds one entry per variable. values[i] is the value at time[i]; null marks a missing step. Look series up by name rather than by position.
  • units on each series is the unit its values are in. Read it instead of assuming one.
  • sampled_latitude / sampled_longitude are the model grid point that was read for your coordinate.
  • model names the model that produced the data and when its run was published. run_published_at can be null.
  • horizon_limited is true when your plan's forecast horizon is shorter than the hours you asked for; the series then stop at the plan's horizon.
  • unavailable_variables lists 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:

Quantitysimetricnautical
wind, gust and current speedm/skm/hkt
temperatureK°C°C
pressurePahPahPa
visibilitymkmkm
wave height, water levelmmm
directiondegreedegreedegree
relative humidity, cloud cover, probability%%%
precipitationmmmmmm
wave periodsss

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.