Register a container, B/L, or booking once as a reference. Vizion then delivers the same update payload two ways: pushed to your callback_url as updates are created, or pulled from GET /references/{referenceId}/updates.
Your existing polling workflow can stay largely as-is: keep your scheduler and poll the updates endpoint on your own cadence. Webhooks are recommended, not required. This guide maps the fields, parameters, and errors you use today onto their Vizion equivalents.
In SeaRates every request is a fresh lookup, and you own the schedule, the cache, and the deduplication. In Vizion you create a reference once and Vizion keeps it updated. Read those updates by push to a callback URL or by pull from the updates endpoint. Both return the same payload, so every mapping below applies either way.
Every call spends quota. Freshness is capped by the polling interval.
To keep this shape, point the same scheduler at GET /references/{id}/updates.
No cache layer or dedup logic either way. Push removes the polling loop. Pull keeps it on your cadence.
| Aspect | SeaRates | Vizion |
|---|---|---|
| Tracking model | Poll on demand | Subscribe once, then push or poll |
| Data delivery | Synchronous GET response | Webhook POST, or pull via GET. Same payload. |
| Authentication | API key as query parameter (?api_key=) | API key as header (X-API-Key) |
| Base URL | https://tracking.searates.com | https://prod.vizionapi.com |
| Batch tracking | Not supported. One request per container. | Not needed. Subscriptions run continuously. |
| Webhook support | None | Optional. HMAC-signed delivery. |
| Rate limit | 100 requests / 20 seconds | Demo: 50 active references at a time, 15,000 API requests per monthly cycle. Production: no rate limits unless otherwise agreed. Demo environment limits → |
| Carrier coverage | 239 shipping lines by SCAC | 61 supported carriers, ~98% of global volume. 29 have a dedicated carrier_code value. |
| Carrier ID format | SCAC code, e.g. CMDU | carrier_code enum, e.g. CMDU |
| Reference types | Container, B/L, booking per request | Container, B/L, booking per subscription |
| Auto carrier detection | sealine=auto parameter | Omit carrier_code and ACI resolves it |
| Event classification | Free text + SMDG event codes | Free text; DCSA journey events available as an account add-on |
| AIS vessel position | Inline with tracking (route=true&ais=true) | Separate endpoint: GET /references/{id}/trace Container trace documentation → |
| ETA | route.pod.predictive_eta in response | In the standard update payload: milestones with source "Vizion" and journey_event.event_classifier "EST". estimated_event_alerts webhook events are supplemental, not the only source. |
| Shipment status | metadata.status enum | Reference status covers tracking state; shipment progress is read from milestones Reference status documentation → |
The API key moves from a query parameter to the X-API-Key request header. SeaRates keys do not carry over. Contact Vizion sales for a key.
curl -X GET "https://tracking.searates.com/tracking\ ?api_key=YOUR_SEARATES_KEY\ &number=MRKU9465770\ &sealine=MAEU\ &type=CT"
curl -X POST https://prod.vizionapi.com/references \
-H "X-API-Key: YOUR_VIZION_KEY" \
-H "Content-Type: application/json" \
-d '{"container_id": "MRKU9465770",
"carrier_code": "MAEU"}'
Replace per-request lookups with a reference lifecycle. Vizion decides when to check each data source and makes every new update available by push and by pull.
Smart Updates is enabled by default. It adjusts how often each data source is checked based on shipment status. Terminal and rail sources are checked more often than a vessel mid-ocean, which reduces latency around arrival, discharge, and transshipment.
With Smart Updates off, checks fall back to a flat configured interval. Default is 12 hours. Intervals of 6, 3, or 2 hours are available on request.
Smart Updates documentation →One call per container, B/L, or booking. Store the returned reference_id for lookups.
POST /references
{
"container_id": "MRKU9465770",
"carrier_code": "MAEU",
"callback_url": "https://your-server.com/vizion-webhook"
}
Use either mechanism, or both. The payload is identical.
A listener on your callback_url receives each update as soon as it is created. No request from you.
POST https://your-server.com/vizion-webhook
Poll on your own cadence, or request by reference ID, for the most recent update.
GET /references/{referenceId}/updates
Vizion auto-unsubscribes references, so no teardown call is required. Deactivation does not always mean delivery — check reference.deactivate_reason. Deactivate manually only to stop tracking early.
DELETE /references/{referenceId}
One SeaRates poll request becomes one reference creation.
| SeaRates parameter | Vizion equivalent | Notes |
|---|---|---|
| number | container_id / bill_of_lading / booking_number | SeaRates combines these in one param. Vizion uses typed fields. |
| type=CT | container_id | Track by container → |
| type=BL | bill_of_lading | Track by B/L → |
| type=BK | booking_number | Track by booking → |
| sealine | carrier_code | Same SCAC values for most carriers |
| sealine=auto | (omit carrier_code) | Vizion uses Automatic Carrier Identification, limited to its 29-carrier network and excluding RCLU |
| force_update | No equivalent | Vizion controls refresh cadence |
| route | Always included | Port data is always returned in updates |
| ais | GET /references/{id}/trace | AIS is a pull endpoint, not part of milestone updates |
| api_key | X-API-Key header | Query parameter becomes a header |
SeaRates accepts a combined value in one number field: BL_NUMBER/CONTAINER_NUMBER, and BOOKING_NUMBER/CONTAINER_NUMBER for bookings. Vizion takes one typed field per reference type.
Track by B/L using bill_of_lading, or by booking using booking_number. In both cases Vizion identifies every container on the document and creates a child reference for each.
If you tracked linked shipments in SeaRates, note that Vizion models the relationship on the child: each child reference carries parent_reference_id. There is no child_reference_ids array on the parent. Associate children to parents using the field on the child.
SeaRates stores locations, vessels, and facilities in top-level arrays referenced by integer ID. Vizion inlines full objects on each milestone. Your ID-resolution code can be deleted.
| SeaRates | Vizion | Notes |
|---|---|---|
| status: "success" | HTTP 200 | SeaRates puts status in the body. Vizion uses standard HTTP codes. |
| message: "OK" | No equivalent | |
| data: { ... } | Webhook body, or GET /updates response |
| SeaRates field | Vizion equivalent | Notes |
|---|---|---|
| metadata.status | Reference status | Check the reference status for tracking state, and reference.deactivate_reason for why tracking stopped. Shipment progress itself comes from milestones. Reference status documentation → |
| metadata.sealine | payload.carrier_scac | Same SCAC codes |
| metadata.number | payload.container_id / bill_of_lading / booking_number | Split into typed fields |
| metadata.api_calls, unique_shipments | No equivalent | Not exposed per response |
| metadata.from_cache, updated_at, cache_expires | No equivalent | Caching is internal to Vizion |
| SeaRates field | Vizion equivalent | Notes |
|---|---|---|
| containers[].number | payload.container_id | One container per reference |
| containers[].iso_code — "45G1" | payload.container_iso — "45G1", or "40' HIGH CUBE" | Vizion returns the ISO 6346 code when it can be mapped at payload-creation time, and a descriptive text string otherwise. Handle both shapes. |
| containers[].size_type | payload.container_iso | Same field. When container_iso falls back to descriptive text, that text is closest to SeaRates' size_type. |
| containers[].status | No direct equivalent | Inferred from milestones |
| containers[].events[] | payload.milestones[] | See milestone mapping |
| containers[].events_mirrored | No equivalent |
| SeaRates event field | Vizion milestone field | Transformation |
|---|---|---|
| date — "YYYY-MM-DD HH:MM:SS" | timestamp | Parse and convert to ISO 8601 |
| actual (boolean) | planned (boolean) | Inverted: planned = !actual |
| description | description | Carrier text is replaced by a Vizion standardized description |
| description | raw_description | Original carrier text, kept verbatim |
| vessel → vessels[].name | vessel | Vizion inlines the name |
| vessel → vessels[].imo | vessel_imo | Vizion surfaces the IMO as a top-level attribute. |
| vessel → vessels[].mmsi | vessel_mmsi | Vizion inlines the MMSI |
| voyage | voyage | Direct pass-through. The only identical field name on both APIs. |
| transport_type — VESSEL, TRUCK, RAIL | mode — Vessel, Truck, Rail | Same values, different casing |
| event_type — EQUIPMENT, TRANSPORT | journey_event.journey_type | DCSA journey events are opt-in. Contact Vizion to enable. |
| event_code — ARRI, DEPA, LOAD, DISC | journey_event.event_type | Same DCSA-derived codes, different structure |
| status (3-char code) | No direct equivalent | |
| type — sea, land | No direct equivalent | |
| order_id | No equivalent | Milestones are ordered by array position |
| facility → facilities[].name | location.facility | Facility moves onto the location object |
| is_date_from_sealine | No equivalent | |
| is_additional_event | No equivalent | |
| (none) | source — carrier, terminal, ais, rail | Where the milestone came from Data sources documentation → |
| (none) | shipment_location — PRE, POL, POD, PDE, RTP | DCSA addon classifying where in the journey the event occurred. [CONFIRM WITH ENG] whether this requires contacting support to enable, as journey_type does. DCSA event code types → |
| SeaRates location field | Vizion location field | Notes |
|---|---|---|
| name | name | Direct match |
| state | state | Direct match |
| country | country | Both use full country names |
| country_code | No equivalent | Full country name only |
| locode | unlocode | Same data, renamed field |
| lat | geolocation.latitude | Flat field becomes nested |
| lng | geolocation.longitude | Flat field, renamed and nested |
| timezone | No equivalent | Not included in responses |
| (none) | city | Dedicated city field. Requires Enhanced Location Reporting. |
| (none) | facility | Populated from facility data. Requires Enhanced Location Reporting. |
| (none) | smdg_cd, bic_cd, splc_cd, firms_cd | Facility identification codes. Requires Enhanced Location Reporting. Enhanced locations documentation → |
| SeaRates route | Vizion payload field | Meaning |
|---|---|---|
| route.prepol | inland_origin | Place of receipt / inland origin |
| route.pol | origin_port | Port of loading |
| route.pod | destination_port | Port of discharge |
| route.postpod | inland_destination | Final destination / inland delivery point |
| route[].date, route[].actual | No equivalent | Port event dates and actuality come through milestones, not port fields |
| SeaRates vessel field | Vizion milestone field | Notes |
|---|---|---|
| vessels[].name | vessel | Name string |
| vessels[].imo | vessel_imo | IMO number, surfaced as a top-level attribute |
| vessels[].mmsi | vessel_mmsi | MMSI number |
| vessels[].call_sign | No equivalent | |
| vessels[].flag | No equivalent |
SeaRates actual is inverted in Vizion: planned = !actual. Timestamps change from YYYY-MM-DD HH:MM:SS to ISO 8601 with offset.
SeaRates event.description values are free text and vary by carrier. Vizion maps them to a standardized set of roughly 130 descriptions and keeps the carrier's original string in raw_description. SeaRates strings are case-insensitive, and new ones appear over time.
The milestone lists live in the API docs. Core milestones are the eight Vizion makes an effort to provide for every reference. Standardized milestones are the full set your SeaRates descriptions resolve into.
Anything Vizion cannot map passes through as raw text in both description and raw_description. Some Vizion milestones have no SeaRates equivalent, including barge and feeder events and transshipment variants, because they come from direct carrier integrations.
Both APIs identify carriers by SCAC, and most codes are identical. Vizion supports 61 carriers in total; 29 of those have a dedicated carrier_code value.
Omitting carrier_code lets ACI resolve the carrier, but only within its supported network of 29 carriers. RCLU is explicitly excluded.
If your SeaRates traffic includes carriers outside that network, do not rely on ACI. Pass the carrier SCAC on the reference directly. Check your carrier mix against the ACI list before cutover.
ACI and reference creation reference →| Vizion carrier_code | Covers |
|---|---|
| CMDU | CMA CGM, APL, CNC, Containerships, MacAndrews, OPDR |
| MAEU | Maersk, MCC Transport, Seago Line |
| ONEY | ONE — K-Line, MOL, and NYK merged |
| HLCU | Hapag-Lloyd, CSAV, Nile Dutch, UASC |
| SUDU | Hamburg-Süd, CCNI |
Optional. SeaRates has no webhooks. Vizion can POST updates to an HTTPS endpoint you expose. Skip this section if you are staying on the polling path. Use callback_url to receive everything, or the webhooks array to subscribe to specific events and sources.
POST /references
{
"container_id": "MRKU9465770",
"carrier_code": "MAEU",
"callback_url": "https://your-server.com/vizion-webhook"
}
POST /references
{
"container_id": "MRKU9465770",
"carrier_code": "MAEU",
"webhooks": [
{
"callback_url": "https://your-server.com/vizion-webhook",
"events": ["reference_update", "estimated_event_alerts"],
"sources": ["carrier", "terminal"]
}
]
}
{
"id": "update-uuid",
"status": "data_received",
"reference_id": "ref-uuid",
"organization_id": "org-uuid",
"created_at": "2026-08-11T14:30:00.000Z",
"payload": {
"container_id": "MRKU9465770",
"carrier_scac": "MAEU",
"container_iso": "40' HIGH CUBE",
"origin_port": { "name": "Shanghai", "country": "China", "unlocode": "CNSHA", ... },
"destination_port": { "name": "Los Angeles", "country": "United States", "unlocode": "USLAX", ... },
"milestones": [
{
"timestamp": "2026-08-10T08:14:00.000+08:00",
"description": "Loaded on vessel",
"raw_description": "Loaded to Vessel",
"vessel": "MAERSK SELETAR",
"vessel_imo": "9778791",
"voyage": "234W",
"planned": false,
"mode": "Vessel",
"source": "carrier",
"location": {
"name": "Shanghai",
"country": "China",
"unlocode": "CNSHA",
"geolocation": { "latitude": 31.2304, "longitude": 121.4737 }
}
}
]
}
}
Payloads are signed with HMAC SHA-256. Verify the x-vizion-signature and digest headers. See webhook security.
POST /webhooks/trigger/test
{ "callback_url": "https://your-server.com/vizion-webhook" }
Returns SUCCESS, REJECTED, or REQUEST_ERROR with full request and response detail.
Features with no SeaRates equivalent.
| Feature | What it gives you |
|---|---|
| Webhook delivery | Optional push delivery. Removes the polling loop if you want it gone. |
| HMAC verification | Cryptographic payload verification on every delivery |
| Milestone source attribution | Each milestone tagged source: carrier, terminal, ais, or rail |
| DCSA journey events | Structured equipment, shipment, and transport events with event_classifier (ACT/PLN/EST), facility_type, and empty_indicator. Opt-in, no extra cost. |
| Raw and standardized descriptions | raw_description and description on every milestone |
| AIS position trace | GET /references/{referenceId}/trace returns vessel position history, plus a projected trace of the forward path |
| ETA change alerts | estimated_event_alerts webhook events carry day and percent delta |
| Reference lifecycle events | GET /references/{referenceId}/events returns an audit trail of extractions, status changes, activations, and deactivations |
| Last known positions | GET /references/last-known-positions for a batch current-position query |
| Tags | Up to 10 custom tags per reference for your internal metadata |
| B/L fan-out | Track by B/L or booking; Vizion creates a child reference per container, each carrying parent_reference_id |
| Demurrage & detention charges | charges data on the update payload (opt-in) |
| Cargo data | Weight, quantity, seal numbers, volume, VGM measurements (opt-in) |
| Facility codes | smdg_cd, bic_cd, splc_cd, and firms_cd on location objects. Requires Enhanced Location Reporting. |
Facility codes and the richer location fields — city, facility, smdg_cd, bic_cd, splc_cd, and firms_cd — require Enhanced Location Reporting to be enabled on your account. Contact Vizion to enable it.
SeaRates features that work differently, or that Vizion handles internally instead of exposing.
| SeaRates feature | Vizion equivalent |
|---|---|
| Shipment status enum | Reference status reports tracking state, not shipment progress. Read progress from milestones, and check reference.deactivate_reason == "shipment_completed" for delivered shipments. |
| Geographic route paths | Available as a projected trace: the vessel's forward path in addition to AIS position history. |
| Current position pin | GET /references/last-known-positions, or the AIS trace endpoint |
| Inline AIS data | Separate endpoint: GET /references/{id}/trace |
| Predictive ETA | In the standard update payload — milestones with source "Vizion" and journey_event.event_classifier "EST". The estimated_event_alerts webhook events are supplemental, not the only source. |
| Cache metadata | Not exposed. Vizion manages refresh internally. |
| Quota counters | Not exposed per response |
| Per-event structured codes | Available via opt-in DCSA journey events, with different structure |
| Force update | Not available. Vizion controls refresh cadence. |
| Historical snapshots | GET /references/{id}/updates returns all update history |
| Carrier list (239 carriers) | GET /carriers returns 61 supported carriers. 29 of those have a dedicated carrier_code value in the ACI network. |
| Location timezone | Not included in the API response |
| Location country_code | Not included. Full country name only. |
| Vessel call_sign and flag | Not included on milestones |
SeaRates returns HTTP 200 for both success and failure and puts the error in the envelope. Vizion uses standard HTTP status codes. Replace checks on response.status == "error" and message-string matching with status-code checks.
| Code | Meaning |
|---|---|
| 400 | Bad request. Malformed or missing parameter. |
| 401 | Unauthorized. API key lacks permissions. |
| 403 | Forbidden. No valid API key. |
| 404 | Not found. Reference does not exist. |
| 422 | Unprocessable entity. Valid syntax, rejected content (e.g. invalid container format). |
| 429 | Too many requests |
| 500, 502, 503, 504 | Server errors. Something went wrong on Vizion's end. These are rare. |
| SeaRates error message | Vizion equivalent |
|---|---|
| API_KEY_WRONG / API_KEY_ACCESS_DENIED / API_KEY_EXPIRED | HTTP 401 or 403 |
| API_KEY_LIMIT_REACHED / API_KEY_RATE_LIMIT | HTTP 429 |
| WRONG_PARAMETERS / WRONG_NUMBER / WRONG_TYPE | HTTP 400 |
| SEALINE_NOT_SUPPORTED | HTTP 422, or auto_carrier_not_found on the reference |
| SEALINE_HASNT_PROVIDE_INFO / NO_CONTAINERS / NO_EVENTS | last_update_status on the reference: no_data or extraction_failed |
| SEALINE_TEMPORARY_DISABLED / SEALINE_UNDER_MAINTENANCE / SEALINE_NO_RESPONSE | Not surfaced. Vizion retries internally. |
| WRONG_SEALINE | HTTP 422, invalid carrier_code |
| AUTO_CANT_DETECT_SEALINE | last_update_status: "auto_carrier_not_found" |
Every migration does the base path. Then pick one branch. The polling path is shorter because there is no endpoint for Vizion to call.