Webhooks
Globe can send HTTP POST notifications to your server when key events occur in your store. Use webhooks to build custom automations — update your WMS, trigger fulfilment workflows, send notifications, or sync data with external systems.
- Go to Settings → Webhooks in the Globe admin.
- Click Add webhook, enter an HTTPS endpoint URL, and choose the events you want to receive.
- Copy the secret shown after creation — it is displayed only once. Store it securely.
Include label PDF
Section titled “Include label PDF”Subscriptions receive the label PDF in shipping_label.created events by default. The PDF contains the customer’s name, address and phone number. If your integration does not need it, turn off Include label PDF in the subscription settings: events then carry only the documentUrl, which you open with a Globe API key (Settings → API).
Payload envelope
Section titled “Payload envelope”Every webhook is a POST request with Content-Type: application/json. The body always follows this structure:
{ "event": "shipping_label.created", "eventId": "evt_9wB3kLm2pQx7", "shopName": "your-store.myshopify.com", "sentAt": "2026-01-15T10:30:00.000Z", "deliveryId": "b3d1e4f2-9c2a-4f1b-8e3d-1a2b3c4d5e6f", "data": { ... }}| Field | Description |
|---|---|
event | Event type (see below) |
eventId | Unique ID of the event (evt_…) — the same across all subscriptions, retries and resends of this event. Use it for deduplication |
shopName | Your Shopify store domain |
sentAt | ISO 8601 timestamp of when Globe sent the request |
deliveryId | Unique UUID for this delivery attempt — every retry and resend gets a new one, so it cannot be used for deduplication |
data | Event-specific payload (see events below) |
Events
Section titled “Events”shipping_label.created
Section titled “shipping_label.created”Fired when a shipping label is successfully generated for an order.
Key fields in data:
| Field | Description |
|---|---|
labelId | Label ID (lbl_…) — the same ID the Globe API returns |
orderId | Shopify order GID |
orderName | Order name, e.g. #1001 |
fulfillmentOrderIds | Fulfillment order GIDs this label covers |
direction | outbound or return |
supersedesLabelIds | IDs of older labels this label replaces. The replaced label may still be a valid, paid shipment at the carrier |
carrier | Carrier code, e.g. packeta |
carrierAccountId | ID of the carrier account used, as a raw hex ID. The Globe API ID is ca_ followed by this value |
internalBatchId | Globe’s internal batch ID |
trackingNumber | Tracking number |
trackingUrl | Tracking page URL |
documentUrl | URL of the label PDF in the Globe API (https://api-globe.appfleece.app/v1/labels/{id}/document). Requires a Globe API key — without one it returns 401, which is intentional |
labelData | Base64-encoded PDF, or null — see the note below |
additionalData | Carrier-specific extras (see below) |
createdAt | ISO 8601 timestamp of when the label was created |
additionalData carries values that only one carrier can produce, so the rest of the payload keeps the same shape for every carrier. Packeta sends consignPassword — the 9-digit consign code that opens a Z-BOX when you drop the parcel in. It is filled in when the carrier account has Show consign code (Z-BOX) enabled, and null otherwise. Carriers with no extras of their own send an empty object.
Labels created through the Globe API carry five more fields:
| Field | Description |
|---|---|
labelCreationId | The label creation (lcr_…) that created the label |
source | api |
clientReference | The client_reference of the request, or null |
cod | {amount, currency, source}: what the courier collects |
labelFormat | label. For these labels labelData is the stored PDF in the label-printer format, not the account’s print format |
label_creation.updated
Section titled “label_creation.updated”Fired when a label creation from POST /v1/labels changes:
- it leaves
processingand becomessucceeded,failedorneeds_attention; - a creation in
needs_attentiongets its label after all, is resolved, fails because PPL refused the shipment at import, or becomesabandonedafter 24 hours; - the fulfillment and order tags of a succeeded creation finish;
- the PDF of a succeeded creation is stored after a delay (Packeta through an external carrier).
A POST /v1/labels refused after its creation record exists (the error carries details.label_creation_id) fires it with status: failed. A refusal before that, such as a validation error, a missing scope, a rate limit or idempotency_conflict, fires nothing. Dry runs never fire it.
Key fields in data:
| Field | Description |
|---|---|
labelCreationId | The label creation (lcr_…) |
status | succeeded, failed, needs_attention or abandoned |
previousStatus | The status before this change. Equal to status when only the side effects or the PDF changed |
nextAction | The creation’s next_action, the same value the API returns. For succeeded it is fetch_document, wait_for_document or none |
labelIds | The labels (lbl_…) of the creation |
orderId | Shopify order GID |
errorCode | For failed, the error code, e.g. carrier_rejected or resolved_not_created. Otherwise null |
sideEffects | {fulfillment: {mode, status, reason}, orderTags: {status}}, or null. The same values as side_effects in the API |
clientReference | The client_reference of the request, or null |
The payload never contains the label PDF or text from the carrier. Include label PDF does not apply to this topic. Read the full state with GET /v1/label-creations/{id}.
Each change is a new event with its own eventId. Retries, resends from the delivery log, and a re-publish after Globe failed to queue the event all carry the same eventId, so deduplicate on it.
pickup_point.selected
Section titled “pickup_point.selected”Fired when a pickup point is selected or changed on an order.
Key fields in data: orderId, orderName, pickupPoint
The pickupPoint field contains the full pickup point object including name, address, GPS coordinates, and carrier-specific data.
pickup_point.not_selected
Section titled “pickup_point.not_selected”Fired approximately 5 minutes after order creation when the order requires a pickup point but none has been selected yet.
Key fields in data: orderId, orderName, customerEmail
order.cod_paid
Section titled “order.cod_paid”Fired when the carrier confirms that a cash-on-delivery order has been paid.
Key fields in data: orderId, orderName, carrier
delivery_status.updated
Section titled “delivery_status.updated”Fired when the carrier reports a change in delivery status.
Key fields in data: orderId, orderName, carrier, status, previousStatus
email_reminder.sent
Section titled “email_reminder.sent”Fired when Globe sends a pickup-point selection reminder email to the customer.
Key fields in data: orderId, orderName, customerEmail, reminderType
Inspecting payloads
Section titled “Inspecting payloads”To explore the exact payload structure for each event, you can point a subscription at a request inspector such as webhook.site:
- Open webhook.site and copy your unique URL.
- Add it as a webhook endpoint in Globe (Settings → Webhooks) with Include label PDF turned off.
- Trigger the event using a test order — place a test order, export its label, etc.
- The full request body will appear on webhook.site in real time.
Verifying requests
Section titled “Verifying requests”Each request includes the following headers:
| Header | Description |
|---|---|
X-Globe-Signature-V2 | t=<unix>,v1=<hex> — HMAC-SHA256 over t + "." + <raw body>, signed with your secret. The timestamp is inside the signature |
X-Globe-Signature | sha256=<hmac> — legacy HMAC-SHA256 of the raw request body (kept for compatibility) |
X-Globe-Event | Event type |
X-Globe-Event-Id | Event ID (evt_…) — same value as eventId in the body |
X-Globe-Delivery | Delivery UUID |
X-Globe-Timestamp | Unix timestamp in seconds (legacy, unsigned — prefer the signed t in X-Globe-Signature-V2) |
Verify with the v2 signature. The v1 signature covers only the body, so the legacy X-Globe-Timestamp header next to it is unsigned — an attacker replaying a captured request could rewrite it. In v2 the timestamp is part of the signed string, so checking t actually protects you:
Node.js verification example:
import crypto from "crypto";
function verifyGlobeWebhook(rawBody, headers, secret) { const header = headers["x-globe-signature-v2"] ?? ""; const match = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header); if (!match) return false;
const [, t, v1] = match;
// Reject stale requests (replay attack prevention) — t is signed if (Math.abs(Math.floor(Date.now() / 1000) - Number(t)) > 300) return false;
const expected = crypto .createHmac("sha256", secret) .update(`${t}.${rawBody}`) .digest("hex");
return crypto.timingSafeEqual( Buffer.from(v1), Buffer.from(expected) );}Retries & reliability
Section titled “Retries & reliability”Globe retries failed deliveries up to 7 times with exponential backoff:
30 s → 5 min → 30 min → 2 h → 8 h → 24 h → dead letter
Your endpoint must return a 2xx status within 10 seconds. After that the request is treated as failed.
If an endpoint fails repeatedly, Globe temporarily suspends deliveries for 24 hours and retries automatically. After 3 suspension cycles with no successful delivery the subscription is disabled. You can re-enable it at any time from Settings → Webhooks.