Scheduled webhooks
Receive complete Ocean tracking JSON on your schedule through HTTPS with configurable receiver authentication. Manage subscriptions, delivery retries and replay.
Webhook API product access must be enabled for your organization.
API integrations
Bring ocean and air tracking into your TMS, ERP or logistics application. Your backend calls our API; Panvaya returns structured shipment data in the same request.
Your TMS / ERP / logistics app
Your backend or integration middleware
↓ POST shipment reference + API key
↑ JSON tracking result or error
Panvaya Logistics API
Ocean milestones · Air cargo · Sailing schedules
Keep your shipment records in your system. Decide which fields to update and when to request the next result.
Enable the required API products and store your key securely in your backend or middleware.
Call the Ocean API with a container, B/L or booking, or the Air API with a full AWB.
Read the synchronous JSON response, update the matching shipment and call again when needed.
Use the API, receive scheduled updates or bring tracking into your existing tools.
Receive complete Ocean tracking JSON on your schedule through HTTPS with configurable receiver authentication. Manage subscriptions, delivery retries and replay.
Webhook API product access must be enabled for your organization.
Add a configurable Ocean tracker to your website or customer portal. Choose approved references, website restrictions and optional private access.
The embedded tracker does not expose your permanent API key.
Import Ocean or Air shipments into your dashboard from CSV. Export shipment tables for spreadsheets and your own reporting workflows.
Batch upload is included with Premium and Enterprise.
Need a webhook for a specific event change? Contact support to discuss your requirements.
Enable daily Ocean shipment reports by email. Review shipment exceptions and risk alerts in your dashboard.
Use JSON responses or exported CSV files in your own reporting pipeline. Available fields depend on the product and source; emissions outputs are estimates.
Download API field mappings, a Postman collection and a webhook receiver example for your implementation.
Set credentials locally. Postman live calls are disabled until you enable them and can consume credits. The receiver is a local inbox example; adapt it to your production hosting and shipment workflow.
Built for your data model
Choose a reference to explore our request, response and suggested mappings.
curl -X POST "https://api.panvaya.com/api/v1/track/ocean" \
-H "X-API-Key: YOUR_PANVAYA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"container": "MEDU8611713",
"shipping_line_scac": "MSCU"
}'JavaScript and Python read PANVAYA_API_KEY from your server environment.
{
"data": {
"reference": {
"number": "MEDU8611713",
"type": "container"
},
"shipping_line": {
"scac": "MSCU",
"name": "Mediterranean Shipping Company (MSC)"
},
"status": "in_transit",
"journey": {
"origin": null,
"port_of_lading": {
"location_id": 1,
"estimated_departure_at": "2026-10-24T00:00:00",
"actual_departure_at": null,
"estimated_arrival_at": null,
"actual_arrival_at": null
},
"port_of_discharge": {
"location_id": 3,
"estimated_departure_at": null,
"actual_departure_at": null,
"estimated_arrival_at": "2026-11-11T00:00:00",
"actual_arrival_at": null
},
"destination": null
},
"locations": [
{
"id": 1,
"name": "Montreal",
"state": "QC",
"country": "Canada",
"country_code": "CA",
"locode": "CAMTR",
"latitude": 45.545,
"longitude": -73.528,
"timezone": "America/Toronto"
},
{
"id": 2,
"name": "Gioia Tauro",
"state": null,
"country": "Italy",
"country_code": "IT",
"locode": "ITGIT",
"latitude": 38.442,
"longitude": 15.902,
"timezone": "Europe/Rome"
},
{
"id": 3,
"name": "Mersin",
"state": "33",
"country": "Türkiye",
"country_code": "TR",
"locode": "TRMER",
"latitude": 36.798,
"longitude": 34.642,
"timezone": "Europe/Istanbul"
}
],
"transports": [
{
"id": 1,
"mode": "truck",
"name": null,
"imo": null,
"call_sign": null,
"mmsi": null,
"flag": null,
"vehicle_number": null,
"voyage_number": null
},
{
"id": 2,
"mode": "vessel",
"name": "MSC KILIMANJARO IV",
"imo": 9318175,
"call_sign": "A8JX3",
"mmsi": 636013001,
"flag": "LR",
"vehicle_number": null,
"voyage_number": "CD643R"
},
{
"id": 3,
"mode": "vessel",
"name": "MSC PAMIRA III",
"imo": 9239903,
"call_sign": "5LCZ6",
"mmsi": 636021246,
"flag": "MH",
"vehicle_number": null,
"voyage_number": "AH645R"
}
],
"containers": [
{
"number": "MEDU8611713",
"equipment": {
"carrier_code": "40 HIGH CUBE",
"iso_code": "45G1",
"description": "High Cube Dry Standard",
"size": 40,
"length": "40'",
"height": "9'6''",
"width": "8'",
"bulk": false,
"liquid": false,
"reefer": false,
"high_cube": true,
"dry": true
},
"status": "in_transit",
"events": [
{
"id": 1,
"location_id": 1,
"event_code": "PICK",
"event_name": "Empty equipment picked up",
"event_category": "equipment",
"carrier_event_name": "Start Export Cycle",
"event_time": "2026-10-14T00:00:00",
"actual": true,
"transport_id": 1
},
{
"id": 2,
"location_id": 1,
"event_code": "GTIN",
"event_name": "Gate in",
"event_category": "equipment",
"carrier_event_name": "Export received at CY",
"event_time": "2026-10-16T00:00:00",
"actual": true,
"transport_id": 1
},
{
"id": 3,
"location_id": 1,
"event_code": "DEPA",
"event_name": "Vessel departed",
"event_category": "transport",
"carrier_event_name": "Estimated Time of Departure",
"event_time": "2026-10-24T00:00:00",
"actual": false,
"transport_id": 2
},
{
"id": 4,
"location_id": 2,
"event_code": "DISC",
"event_name": "Discharged at transshipment port",
"event_category": "equipment",
"carrier_event_name": "Full Intended Transshipment",
"event_time": "2026-11-07T00:00:00",
"actual": false,
"transport_id": 2
},
{
"id": 5,
"location_id": 2,
"event_code": "LOAD",
"event_name": "Loaded at transshipment port",
"event_category": "equipment",
"carrier_event_name": "Full Intended Transshipment",
"event_time": "2026-11-07T00:00:00",
"actual": false,
"transport_id": 3
},
{
"id": 6,
"location_id": 3,
"event_code": "ARRI",
"event_name": "Vessel arrived",
"event_category": "transport",
"carrier_event_name": "Estimated Time of Arrival",
"event_time": "2026-11-11T00:00:00",
"actual": false,
"transport_id": 3
}
]
}
]
},
"errors": null
}Excerpt from our developer example. Static sample; live data and availability vary. Optional route geometry is omitted. These examples do not send API requests.
Suggested destination fields for your TMS, ERP or logistics app. Exact field names and required fields depend on your system and configuration.
| Your application field | Panvaya response fields | Mapping guidance |
|---|---|---|
| Tracking reference & carrier | data.reference.numberdata.reference.typedata.shipping_line.scac | Match the queried reference and carrier to your shipment. Keep your own order, PO and shipment IDs in your application. |
| Container records & status | data.containers[].numberdata.containers[].statusdata.status | Create or update each returned container separately. Map shipment and container statuses to your own status vocabulary. |
| Load & discharge ports | data.journey.port_of_lading.location_iddata.journey.port_of_discharge.location_iddata.locations[].iddata.locations[].locode | Resolve each location_id against locations[].id to get the port UN/LOCODE. Lookup IDs are local to this response, not permanent port identifiers. |
| Departure & arrival dates | data.journey.port_of_lading.estimated_departure_atdata.journey.port_of_lading.actual_departure_atdata.journey.port_of_discharge.estimated_arrival_atdata.journey.port_of_discharge.actual_arrival_at | Map ETD, ATD, ETA and ATA separately. A missing actual date stays null; an estimate is not proof of departure or arrival. |
| Milestone history | data.containers[].events[].event_codedata.containers[].events[].event_timedata.containers[].events[].actual | Map canonical event codes into your milestone model. Preserve actual versus planned and source date precision; do not append duplicates on each refresh. |
| Event place & timezone | data.containers[].events[].location_iddata.locations[].namedata.locations[].timezone | Resolve the event location within this response. Preserve timezone and date-only precision; do not assume a timestamp without an offset is UTC. |
| Vessel & voyage | data.containers[].events[].transport_iddata.transports[].iddata.transports[].modedata.transports[].namedata.transports[].imodata.transports[].voyage_number | Resolve each event's transport_id. Use vessel fields only for vessel movements and retain each voyage when the journey changes ships. |
| Equipment type | data.containers[].equipment.iso_codedata.containers[].equipment.description | Map equipment on the matching container. Carrier-supplied details may be missing; leave unavailable values empty. |
[] means each item in an array. Fields depend on carrier availability. Preserve missing data rather than inventing a value.
Retry-After on 429 responses and use bounded backoff for transient failures.For a mapping review, share your TMS or ERP name and version, a redacted target schema, required fields, milestone codes, shipment matching rules and expected refresh volume.
Your internal order IDs, PO numbers and business workflow remain yours. Our stateless tracking API does not automatically create dashboard shipments or write into your ERP.
Your team or integration partner connects your backend or middleware through our REST APIs or scheduled Ocean webhooks, then maps the returned JSON to your system. Embedded tracking and dashboard CSV tools offer other ways to use Panvaya. No native vendor connector, marketplace app or platform partnership is implied.
No. Generate a key once in your API dashboard, save it securely on your backend and reuse it in the X-API-Key header. The secret is shown only at creation. Replace it when rotated, revoked or expired; product access, credits and rate limits still apply.
Yes. Each tracking call returns its result or error in the same HTTP request. Results use Panvaya's tracking pipeline and shared caches; they do not guarantee a new carrier fetch on every call. Freshness and response time depend on the carrier and cache. Your application decides when to request another update.
Yes, where the carrier supports it. Send the bol reference to the Ocean endpoint and process every returned item in data.containers. You can also scope a supported B/L or booking request with a container number. Do not copy one container's milestones onto another.