ByeLabel API (v1)
    • ByeLabel API (v1) Document
    • ByeLabel Webhooks
    • Me
      GET
    • Login
      POST
    • Refresh Token
      POST
    • Balance
      GET
    • Carrier List
      GET
    • Country List
      GET
    • State/Province List
      GET
    • Currency Rates
      GET
    • State & City From Postal Code
      POST
    • Calculate Tax
      POST
    • Get Carrier Rates
      POST
    • Create Shipment (Label)
      POST
    • Void Shipment (Label)
      POST
    • End Of Day Open Counts
      GET
    • End Of Day Open Shipments List
      GET
    • Order Counts By Status
      GET
    • Order List
      GET
    • Shipment Counts By Status
      GET
    • Shipment List
      GET
    • Shipment Item
      GET
    • Track Shipment
      GET
    • Products Counts By Category
      GET
    • Product List
      GET
    • Connected Printer List
      GET
    • Send Job To Connected Printer
      POST
    • SSE Events
      GET
    • Schemas
      • Fail Result Schema
      • Success Result Schema
      • HTTP Error Schema
      • Token Schema
      • Balance Schema
      • Tax Identifiers Schema
      • Weight Schema
      • Dimensions Schema
      • Price Schema
      • Sender Schema
      • Recipient Schema
      • Package Schema
      • Package Line Items Schema
      • Product Options Schema
      • Carrier Schema
      • Invoice Schema
      • Printing Options Schema
      • Order Schema
      • Carrier Rate Result Schema
      • Created Shipment Result Schema
      • Document To Print Schema
      • Country Schema
      • State / Province Schema
      • Shipment Activity Schema

    ByeLabel Webhooks

    Webhooks#

    Webhooks let your systems react to activity in Byelabel as it happens, instead of
    polling for changes. When an order arrives, a shipment is created, or your balance
    changes, Byelabel sends an HTTP POST to a URL you control.
    A typical use: your ERP creates a purchase order the moment a shipment is created,
    or your accounting system records a charge when your balance changes.

    Quick start#

    1.
    In Byelabel, go to Settings → Webhooks and select Add webhook.
    2.
    Enter the URL that should receive events, give it a name, and choose the events
    you want.
    3.
    Copy the signing secret shown when the webhook is created. It is displayed
    once.
    If you lose it, rotate it to generate a new one.
    4.
    Build an endpoint that accepts POST, verifies the signature, and replies 200.
    5.
    Use Send test event on the webhook to confirm delivery end to end.

    What a delivery looks like#

    Byelabel sends a POST with a JSON body:
    {
      "event": "shipment.created",
      "timestamp": "2026-10-20T09:14:22.431Z",
      "payload": {
        "id": "a3f1c9d4-7b2e-4c88-91a5-6e0d4f3b8c27",
        "...": "event-specific fields"
      }
    }

    Headers#

    HeaderMeaning
    X-Webhook-EventThe event name, matching event in the body
    X-Webhook-IdUnique id for this delivery. Stable across retries — use it for idempotency
    X-Webhook-SignatureHMAC-SHA256 of the request body, hex encoded. See Verifying signatures
    X-Webhook-TimestampWhen the event occurred, ISO 8601
    X-Webhook-AttemptDelivery attempt number, starting at 1
    User-AgentAlways ByeLabel-Webhook/1.0
    Any custom headers you configure on the webhook are sent as well. They are applied
    after the headers above, so a custom header with the same name will override it.

    Body#

    FieldTypeNotes
    eventstringThe event name
    timestampstringISO 8601, UTC
    payloadobject | nullThe event data. null for events that carry no body

    Verifying signatures#

    Always verify the signature before acting on a webhook. Your endpoint is a public
    URL; anyone can post to it. The signature proves the request came from Byelabel.
    The signature is HMAC-SHA256 over the raw request body, keyed with your signing
    secret, hex encoded.
    Use the raw body bytes, not a re-serialized object. If you parse the JSON and
    stringify it again, key order and whitespace may differ and the signature will not
    match. Most frameworks need to be configured to keep the raw body.

    Node.js (Express)#

    PHP#

    Python (Flask)#

    Use a constant-time comparison — timingSafeEqual, hash_equals,
    compare_digest — rather than ==.

    Rotating the secret#

    Settings → Webhooks → select the webhook → Rotate secret. The new secret is
    shown once and takes effect immediately; deliveries already queued are signed with the
    secret in force when they were queued. Plan a short window where your endpoint accepts
    either value if you cannot deploy the new secret at the same moment.

    Events#

    Subscribe to specific events, or use a wildcard.
    PatternMatches
    order.createdthat event only
    order.*order.created, order.updated, order.deleted
    *every event, including ones added in future

    Orders#

    EventSent when
    order.createdAn order is created manually or imported from a marketplace
    order.updatedAny field on an order changes, including status and address corrections
    order.deletedAn order is removed

    Shipments#

    EventSent when
    shipment.createdA label is purchased and a shipment is created
    shipment.updatedA shipment changes — tracking updates, status transitions
    shipment.deletedA shipment is voided or removed

    Customers#

    EventSent when
    customer.createdA new recipient record is created
    customer.updatedA recipient record changes
    customer.deletedA recipient record is removed

    Products#

    EventSent when
    product.createdA product is added to the catalogue
    product.updatedA product changes
    product.deletedA product is removed

    Batches#

    EventSent when
    batch.createdA batch is opened
    batch.updatedOrders are added to or removed from a batch, or it is closed
    batch.deletedA batch is removed

    Stores#

    EventSent when
    store.syncedA marketplace store finishes a sync
    store.deactivatedA store connection is deactivated, usually because credentials stopped working

    Account#

    EventSent when
    workspace.updatedWorkspace settings change
    workspace.deletedThe workspace is closed
    user.createdA user is added
    user.updatedA user's details or permissions change
    user.deletedA user is removed

    Support#

    EventSent when
    ticket.createdA support ticket is opened
    ticket.updatedA ticket changes
    ticket.repliedA reply is added
    ticket.closedA ticket is closed

    Billing#

    EventSent when
    balanceYour account balance changes

    Responding#

    ResponseResult
    2xxDelivery recorded as successful
    Anything elseDelivery recorded as failed and retried
    No response within 10 secondsTreated as failed and retried
    Reply first, process afterwards. Acknowledge with 200 as soon as you have
    verified the signature and stored the event, then do the work asynchronously. If your
    processing takes longer than 10 seconds, Byelabel will treat it as a failure and send
    the same event again — even though you were handling it correctly.
    Response bodies are not interpreted; the first 4 KB is recorded in the delivery log to
    help you debug.

    Retries#

    A failed delivery is retried with exponential backoff, starting at 5 seconds and
    doubling each time.
    With the default of 5 retries:
    AttemptSent
    1immediately
    2+5 seconds
    3+15 seconds
    4+35 seconds
    5+75 seconds
    6+155 seconds
    After the final attempt the delivery is marked failed and is not retried again.
    You can set retries per webhook, from 0 (no retries) to 20. Note that 20
    retries with doubling backoff spans several days — useful for an endpoint that may be
    offline for maintenance, excessive for most integrations.

    Idempotency#

    Retries mean your endpoint must tolerate receiving the same event more than once.
    A delivery can also succeed on your side and still be retried, if the response was lost
    in transit.
    Use X-Webhook-Id as the deduplication key. It stays the same across all attempts of
    the same delivery:
    Events may also arrive out of order — a retried order.updated can land after a later
    one succeeded. Where order matters, compare timestamp against what you hold rather
    than assuming arrival order.

    Configuration#

    SettingNotes
    Name1–150 characters. For your own reference
    Target URLhttp or https, up to 500 characters. Use HTTPS in production
    EventsAt least one. Specific names or wildcards
    EnabledDisable to stop deliveries without deleting the webhook or losing its secret
    Max retries0–20, default 5
    Custom headersUp to 20. Header name up to 100 characters, value up to 2000
    Custom headers are useful for a static bearer token or routing hint your gateway
    expects. They are not a substitute for verifying the signature.

    Monitoring#

    Open a webhook under Settings → Webhooks to see:
    Deliveries — every attempt, with response status, duration and the response body
    Statistics — delivery and failure counts over time, error rate, average response
    time
    A persistent error rate usually means one of: your endpoint is timing out, returning a
    non-2xx status, or rejecting signatures because the raw body is being altered before
    verification.

    Troubleshooting#

    Signature never matches. The most common cause is verifying against a
    re-serialized body. Hash the raw bytes exactly as received. Check also that no proxy
    or middleware is rewriting the body, and that the secret matches the webhook you are
    receiving from — each webhook has its own.
    Deliveries show as timeouts. Your endpoint is taking more than 10 seconds.
    Acknowledge first and process in the background.
    Duplicate events. Expected behaviour on retry. Deduplicate on X-Webhook-Id.
    No deliveries at all. Check the webhook is enabled, that the event you expect is in
    its event list, and that your firewall allows inbound requests. Use Send test event
    to isolate whether the problem is configuration or connectivity.
    Deliveries stopped after working. Check whether the secret was rotated, or whether
    the endpoint began returning non-2xx — a webhook is never auto-disabled, so deliveries
    continue to be attempted and logged as failures.

    Security#

    Verify every signature, with a constant-time comparison.
    Use HTTPS. The payload may contain recipient names and addresses.
    Treat the signing secret like a password. Rotate it if it may have been exposed.
    Do not rely on source IP addresses for authentication; they are not guaranteed to be
    stable.
    Return 401 on a signature mismatch rather than 200, so the failure is visible in
    your delivery log.
    Modified at 2026-10-20 21:37:46
    Previous
    ByeLabel API (v1) Document
    Next
    Me
    Built with