Quick start
Every request carries your API key in the X-API-Key header — or, if you were given a username and
password, HTTP Basic authentication. The base URL for version 1 is:
https://<gateway>/api/public/v1
curl -H "X-API-Key: mtk_…" \
"https://<gateway>/api/public/v1/vessels/9811000"
Responses are JSON. Lists come back as {"data": [...]}; paged lists add
total, limit and offset.
Getting a key
Keys are issued by MariTrace — contact your account manager or MariTrace support. Each key belongs to one API
user and opens only the APIs that user has been granted. Access can start as a trial: the same
API and the same key, open until a date. While it runs, every response carries X-Trial-Ends; after it,
calls to that API are 403 until it is extended or made permanent. You can hold several keys (one per system, say) and
have any of them revoked without affecting the rest.
What you can call
The API is split into products, granted separately. A request to a product you have not been granted is
403.
Vessels
GET /vessels?q=searchGET /vessels/{ref}particulars
Positions
GET /vessels/{ref}/positionlatest + voyageGET /positions?vessels=up to 100 at once
Tracks
GET /vessels/{ref}/trackraw, hourly or daily
Port calls
GET /vessels/{ref}/port-callsGET /ports/{ref}/port-calls
Ports
GET /ports?q=searchGET /ports/{ref}GET /ports/nearest?lat=&lon=
A vessel {ref} is an IMO (7 digits), an MMSI (9 digits) or a MariTrace vessel id. A port
{ref} is a UN/LOCODE (GBSOU) or a MariTrace port id.
Rate limits
Each product you are granted has a per-minute and a per-day allowance (days run 00:00–24:00 UTC). Every response tells you where you stand:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed per minute for this product |
X-RateLimit-Remaining | Requests left this minute |
X-RateLimit-Reset | Seconds until the minute allowance refills |
Retry-After | On a 429 only: seconds to wait before retrying |
Back off and retry after Retry-After on a 429. Need more? Ask us — limits are set per user.
Errors
Errors are RFC 9457 problem details
(application/problem+json). Switch on status; detail is written for people.
{ "type": "about:blank", "title": "Bad Request", "status": 400,
"detail": "from must be before to", "instance": "/public/v1/vessels/9811000/track" }
| Status | When |
|---|---|
| 400 | A parameter is missing or invalid |
| 401 | No credentials, or they are unknown, revoked or expired |
| 403 | Valid credentials, but not granted this product, its trial has ended, or the vessel is outside your access |
| 404 | No such vessel, port or endpoint |
| 429 | Rate limit reached |
| 502 / 503 / 504 | A problem on our side — retry with backoff. Quote the X-Request-Id header if you contact us. |
Versioning
The major version is in the path: /api/public/v1. Within a version we only make additive changes —
new endpoints, new optional parameters, new response fields — so ignore fields you do not recognise. Anything that
would break a client (renaming, retyping or removing a field, changing a default) ships as a new version alongside
the old one, and the old one keeps running for a notice period before it retires.
| Version | Status | Reference |
|---|---|---|
| v1 | Current | Reference · OpenAPI |
| MariTrace API, MariData API, PublicAPIs | Legacy, still supported | Legacy APIs |
Conventions
- Times are ISO-8601 in UTC, e.g.
2026-11-10T09:30:00Z. - Units are in field names:
speed_knots,draught_m,course_deg. - A field with no value is left out rather than sent as
null. AIS "not available" markers (heading 511, draught 0) are never passed on as if they were measurements. - Field names are
snake_case.