Dark mode
/v3/sea-margin.json
POST
/v3/sea-margin.json
Sea Margin API v3
Statistical analysis of Sea Margin (weather/current impact on vessel speed) derived from
5 years of historical voyage data. Returns histograms, percentiles, and GeoJSON route data.
| Item | Value |
|---|---|
| Data Area | Global |
| Output Format | JSON / GeoJSON |
| Historical Data | Past 5 years of voyages |
| Endpoint | Single POST endpoint |
What This API Does
Quantifies the impact of weather and ocean currents on vessel speed, enabling data-driven
decisions for voyage planning, CP calculations, and route analysis.
| Want to... | Use action |
|---|---|
| Analyze Sea Margin between two specific ports | port_to_port |
| Get Sea Margin overview from one port to all ports | port_to_world |
| Retrieve past voyage routes as GeoJSON | smc_route |
| Retrieve shortest route as GeoJSON | shortest_route |
| Get list of available port codes | smc_port |
Typical Use Cases
- Voyage planning / CP calculation: Use
sea_margin.middleas standard estimate,
sea_margin.highas conservative estimate - Seasonal variation: Use
monthlydata to compare winter/summer Sea Margin and
visualize risk seasons - New route market research: Use
port_to_worldto get Sea Margin overview for all
ports and narrow down promising routes - Route visualization: Use
smc_routeto display historical routes as GeoJSON - Passage days estimation: The difference between
passage_days.base(theoretical)
andpassage_days.middle(actual median) is the expected delay due to Sea Margin
How to Use
Send a POST request with action in the JSON body. All parameters are flat (no nesting).
{
"action": "port_to_port",
"from_port": "SGP",
"to_port": "STS",
"ship_type": "BULK CARRIER",
"perf_speed": 12,
"area_size": "medium"
}
Convenient Features
- Auto case normalization:
from_port/to_port→ uppercase,ship_type→ uppercase,
area_size→ lowercase. Input"sgp"→"SGP","bulk carrier"→"BULK CARRIER" area_sizedefault: Omittingarea_sizedefaults to"medium"(recommended)- Port code validation: Unknown port codes return similar code suggestions
(e.g.,"SNGP"→"Did you mean: SGP (SINGAPORE)?") - Response headers:
X-Request-Id(request tracking) andX-Response-Time-Ms(processing time) are included
Performance Reference
| Action | Approx. Time | Response Size (gzip) |
|---|---|---|
smc_port |
~6s | 77KB (417KB uncompressed) |
shortest_route |
~0.1s | — |
port_to_port |
~0.6s | — |
smc_route |
~1.7s | varies (up to 600KB) |
port_to_world (medium) |
~7s | 131KB (2.2MB uncompressed) |
For port_to_world and smc_route, use Accept-Encoding: gzip header.
Authentication
All requests require Authorization: WniWebApi {token} header.
Token is obtained via POST /api/auth.json with uid/password form data.
The client is automatically identified from the token — no need to include it in the request body.
Parameters
Header Parameters
Authorization*
"WniWebApi " + Token ID
Typestring
RequiredAccept-Encoding
Recommended: gzip for port_to_world and smc_route actions.
Reduces response size by up to 95%.
Typestring
Example
gzipRequest Body
JSON
{
"action": "port_to_port",
"from_port": "SGP",
"to_port": "STS",
"ship_type": "BULK CARRIER",
"perf_speed": 12,
"area_size": "medium"
}
Responses
Success. Response format varies by `action`:
- **`port_to_port`**: `{ shortest_distance, annual: {...}, monthly: { "1": {...}, ... "12": {...} } }`
- `sea_margin`: `{ histogram, low, middle, high }` — percentile values (e.g., `middle` = 50th percentile)
- `passage_days`: `{ histogram, base, low, middle, high }` — `base` is theoretical, others are historical
- `wx_factor` / `ct_factor`: weather and current factor distributions
- **`port_to_world`**: Object keyed by port code → `{ annual: { sea_margin, passage_days }, monthly: {...} }`
- **`smc_route`**: `{ route: GeoJSON FeatureCollection (LineString per month), area: GeoJSON FeatureCollection (Polygon) }`
- **`shortest_route`**: `{ route: GeoJSON FeatureCollection (single LineString) }`
- **`smc_port`**: GeoJSON FeatureCollection (Point per port, ~2,300 features)
application/json
JSON
{
"shortest_distance": 8904.83,
"annual": {
"sample_count": 644,
"sea_margin": {
"histogram": {
"0.03": 114,
"0.04": 146,
"0.05": 119,
"0.06": 90
},
"low": 0.033,
"middle": 0.0479,
"high": 0.0638
},
"passage_days": {
"histogram": {
"31.5": 131,
"32.0": 217,
"32.5": 178,
"33.0": 82
},
"base": 32.3988,
"low": 31.9402,
"middle": 32.2545,
"high": 32.8939
},
"wx_factor": {
"histogram": {
"-0.6": 249,
"-0.4": 332,
"-0.2": 43
},
"middle": -0.3174
},
"ct_factor": {
"histogram": {
"0.0": 479,
"0.2": 140,
"0.4": 20
},
"middle": 0.1055
},
"total_distance": {
"histogram": {
"9000": 57,
"9050": 200,
"9100": 186
},
"middle": 9079.655
}
},
"monthly": {
"1": {
"sample_count": 117,
"sea_margin": {
"histogram": {
"0.02": 21,
"0.03": 36,
"0.04": 31
},
"low": 0.0269,
"middle": 0.0381,
"high": 0.0493
},
"passage_days": {
"base": 32.3988,
"low": 31.8116,
"middle": 32.1283,
"high": 32.6102
}
}
}
}