Connect your backend
Create a widget in Integrations → Web embedding. Use an API key created by an active organization administrator, kept in a server environment variable. Existing keys, rotation, revocation and per-key rate limits apply. Keys created by ordinary members cannot manage references or launch private sessions. The widget and key must belong to the same organization; no organization ID is accepted from your request.
Read approved references
GET /api/v1/tracking-widgets/{widgetId}/references
Retrieve the widget’s complete approved-reference list from your backend with the same organization-admin API key. Works for paused widgets too, so you can check configuration before publishing. Returns only the widget UUID and canonical references, with at most 500 entries.
curl \
"https://api.panvaya.com/api/v1/tracking-widgets/YOUR_WIDGET_ID/references" \
--header "X-API-Key: $PANVAYA_API_KEY"{"id":"YOUR_WIDGET_ID","allowedReferences":["CT:MSKU8094830","BL:YOUR-BILL"]}This read is free, does not invalidate sessions, and logs safe organization and API-key attribution without storing an audit row. The private key stays on your backend; the public iframe cannot list approved references.
Update approved references
PATCH /api/v1/tracking-widgets/{widgetId}/references
Send add, remove, or both. Use CT:number, BL:number or BK:number. A document reference allows its complete response; append +CT:number to approve only that container within the document. Up to 500 references may remain on a widget.
curl --request PATCH \
"https://api.panvaya.com/api/v1/tracking-widgets/YOUR_WIDGET_ID/references" \
--header "X-API-Key: $PANVAYA_API_KEY" \
--header "Content-Type: application/json" \
--data '{"add":["CT:MSKU8094830","BL:YOUR-BILL"],"remove":["BK:OLD-BOOKING"]}'{"id":"YOUR_WIDGET_ID","allowedReferences":["CT:MSKU8094830","BL:YOUR-BILL"]}Duplicate additions and missing removals are harmless. Concurrent patches merge safely. A changed list invalidates existing sessions and unused launch codes; an unchanged list does not. Pause an enabled widget before removing its final reference in approved-reference mode. Removing references preserves usage history and consumed shipment slots. This API manages the widget allowlist; it does not create or delete dashboard shipments.
Launch private access
Enable Require private access in the widget settings. Keep your allowed website origins configured. Anonymous session creation is blocked, including when hosted-page access is enabled.
POST /api/v1/tracking-widgets/{widgetId}/launch
- Your backend authenticates the visitor and chooses references they may view.
- It calls Panvaya with its API key, the exact parent website origin, and a nonempty list of authorized references.
- Panvaya returns a one-time launch code valid for 60 seconds.
- Your website immediately loads a fresh iframe with that code in the URL fragment. Panvaya removes the fragment and exchanges the code for a 15-minute session.
// Server-side only. First authenticate your visitor and determine
// their references from your own records. Never trust a browser-supplied list.
const response = await fetch(
"https://api.panvaya.com/api/v1/tracking-widgets/YOUR_WIDGET_ID/launch",
{
method: "POST",
headers: {
"X-API-Key": process.env.PANVAYA_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
parentOrigin: "https://tracking.example.com",
references: ["CT:MSKU8094830"], // Authorized for this visitor
}),
cache: "no-store",
},
);
if (!response.ok) throw new Error("Could not authorize tracking");
const { launchCode } = await response.json();
// Return only this temporary URL to the authorized visitor. Set your
// backend response to Cache-Control: private, no-store as well.
const iframeUrl = "https://panvaya.com/embed/YOUR_WIDGET_ID#launch="
+ encodeURIComponent(launchCode);{"launchCode":"ONE_TIME_CODE","expiresAt":"2026-10-11T12:01:00"}<iframe src="AUTHORIZED_IFRAME_URL" title="Shipment tracking"
style="width:100%;height:720px;border:0"
referrerpolicy="strict-origin"></iframe>Load private iframes immediately rather than lazily. Never place an API key in the iframe URL, browser JavaScript or storage. A session can search only its launch references; approved-reference mode additionally requires every launch reference to be on the widget’s allowlist. Open-search mode still enforces the launch’s visitor-specific scope.
For an authorized direct link, enable hosted-page access and omit parentOrigin when creating the launch. The one-time code is still required. After expiry, a failed exchange or a settings/reference change, obtain a fresh launch from your backend and create a new iframe. Revoking the key or disabling/demoting its owner also blocks pending launches and active sessions.
Security and billing
Reference reads and updates, launch creation and session exchanges are free. Successful tracking costs 5 credits by default, including cache hits, from your shared API balance. Your organization’s configured EMBED_SEA_TRACKING price overrides this default. Existing tracking idempotency, daily budgets and distinct-reference limits apply. Public widgets keep their existing behavior; enable private access when visitor authorization is required.
Retry the same submission after a lost connection. A completed search returns 409 REQUEST_ALREADY_COMPLETED without another carrier request or charge. Responses are not stored for replay; select Start a new search to retrieve tracking again at the configured credit cost.
For account balance and enabled product costs, use GET /api/v1/usage. For embedding-only billed activity, use GET /api/v1/usage/report?productCode=EMBED_SEA_TRACKING with optional from and to dates. These existing APIs are free and use your server-side API key.
Your backend must enforce visitor access before requesting a launch. A public endpoint that issues launches to anyone would make your integration public again. Launch codes and session tokens are temporary bearer credentials: protect them with HTTPS, avoid shared caches and logs, and never share them with another visitor. Website restrictions support this flow but do not replace authentication.
| Status | Meaning |
|---|---|
| 400 | Invalid references, conflicting add/remove, or widget not private |
| 401 | Missing, expired or revoked API key; invalid, expired or consumed launch code |
| 403 | Key owner lacks admin access, product disabled, or website not allowed |
| 404 | Widget unavailable or belongs to another organization; reference outside session scope |
| 409 | Tracking submission is running, already completed, or conflicts with its original input/session |
| 429 | API-key, widget rate limit or tracking budget reached |
API responses include a request ID and rate-limit headers. Private mutations and launches retain client, widget, key and outcome audits. Reads use safe logs. Permanent keys, launch codes and session tokens are never logged. Download the OpenAPI specification.