Credits and plans
Each successful response (HTTP 200) costs credits; errors, 404s and refused requests cost nothing. Credits reset at the start of each UTC month. All your keys share one allowance, and the bigger allowance applies when you hold more than one plan: allowances never add up.
| Plan | Credits a month | Requests per second | Commercial use | Price |
|---|---|---|---|---|
| Sandbox | 2,500 | 1 | No, personal use | Free |
| Plus allowance | 5,000 | 2 | No, personal use | Included in the personal plan |
| Pro allowance | 25,000 | 5 | Internal business use | Included in the personal plan |
| Developer | 25,000 | 5 | Yes, including in your products | US$19/month |
| Growth | 250,000 | 20 | Yes, including in your products | US$99/month |
| Scale | 2,500,000 | 50 | Yes, including in your products | US$399/month |
Cost per request
| Endpoint | Credits | Key required |
|---|---|---|
| GET /api/v1/vessels/{id} | 1 | Works without a key |
| GET /api/v1/ports/{unlocode} | 1 | Works without a key |
| GET /api/v1/companies/{entityId} | 1 | Works without a key |
| GET /api/v1/flags/{iso2} | 1 | Works without a key |
| GET /api/v1/wrecks/{id} | 1 | Works without a key |
| GET /api/v1/search | 1 | Key required |
| GET /api/v1/ports | 1 | Key required |
| GET /api/v1/sanctions/{list} | 1 | Key required |
| GET /api/v1/vessels/{id}/track | 1per day of track | Key required |
| GET /api/v1/screen | 1per vessel | Key required |
| GET /api/v1/waterways | 1 | Key required |
| GET /api/v1/usage | 0 | Key required |
| GET /api/v1/me/feed | 1 | Key required |
History: the last 24 hours of a track are open to every plan, including the free Sandbox key. Older windows need history in your plan: Plus 365 days, Developer 30 days, Growth 2 years, Pro and Scale everything Voydar holds (position history starts on 1 June 2026; positions older than 90 days are served from the archive at 10-minute resolution, without navigational status). A request beyond your plan answers 403 history_not_in_plan; if the archive cannot answer, 503 archive_unavailable, not charged.
Every keyed response carries X-Credits-Limit, X-Credits-Used, X-Credits-Remaining, X-Credits-Cost, X-Credits-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Seadar-Tier and X-Seadar-Commercial-Use. GET /api/v1/usage returns the same numbers as JSON, free.
Usage is counted on each server and written in batches every few seconds, so a burst spread over many servers can go slightly past the allowance before it is refused, and the account page can trail live traffic by about 10 seconds. Rate limits allow a burst of twice the per-second rate.
Errors
Errors are JSON with "error" (a stable code), "message" and "docs".
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_parameter | A query parameter is out of range or malformed. |
| 401 | api_key_required | This endpoint needs a key. |
| 401 | invalid_key | The key is malformed, unknown, revoked or rotated. |
| 402 | credits_exhausted | This month's credits are used up. The body has resetsAt and an upgrade link. |
| 403 | history_not_in_plan | The track window reaches further back than your plan's history. The body has maxHours and an upgrade link. |
| 404 | not_found | No such entity (free). |
| 429 | rate_limited | Too many requests. Wait for the Retry-After header (seconds). |
| 451 | not_licensed_for_api | The data's sources do not permit API redistribution (only when full enforcement is switched on). |
| 503 | auth_unavailable | Keys cannot be checked right now. Retry after a few seconds. |
Why a field is withheld
A fact can be free to read on a Voydar page and still not be ours to redistribute. Each section of a response names the sources behind it and is included only when every one of them permits redistribution through an API. Everything else is listed under "withheld" with its sources and a reason, so you can see what exists and why it is not served.
Your plan changes how much you can ask for, never what a response contains: no key, plan or payment unlocks a withheld field. Rights come from each source's licence.
Withheld today: live AIS positions from feeds without redistribution terms (AISstream, BarentsWatch) and the port calls and chokepoint transit counts derived from them, data from Beacon contributor stations (the contributor licence is awaiting confirmation), ship particulars from the legacy vessel load (no field-level source), photos and Wikipedia text. Served: sanctions lists, US Coast Guard inspections, EU MRV emissions, GLEIF, Wikidata, UN/LOCODE, NGA, and positions from Digitraffic, Kystverket and NOAA.
Reasons: source_not_licensed_for_api (a source's API right is not granted) and rights_registry_unavailable (the rights registry could not be read, so nothing is served: the API fails closed).
"withheld": [
{ "section": "lastPosition", "sources": ["aisstream"], "reason": "source_not_licensed_for_api" }
]Caching
Responses are built from a shared cache that refreshes at most every 15 minutes (lists and search: 1 hour). Keyed responses are marked private and never stored by shared caches; keyless entity lookups are cached at the edge for 15 minutes.