Shelfless Webhook Service Documentation

Webhook Service

The Shelfless Webhook Service allows you to receive real-time notifications about events in your Shelfless integration. By subscribing to webhooks, your application can automatically receive updates about order statuses, inventory changes, and other important events.

Getting Started

  1. Create a webhook endpoint in your application that can receive POST requests
  2. Subscribe to events using the Shelfless API
  3. Verify webhook signatures to ensure message authenticity
  4. Process the webhook payloads in your application

Subscription Management

Creating and Managing Subscriptions

You can manage your webhook subscriptions through the Shelfless API. Available operations include:

  • Create new subscriptions
  • Update existing subscriptions
  • List active subscriptions
  • Activate/deactivate subscriptions
  • Delete subscriptions

A subscription can contain one or more events to be forwarded to one endpoint. Multiple subscriptions can be created, however each event can only be present in one of those subscription. If the receiver needs to duplicate the message to multiple endpoints thathas to be done by the receiver, Shelfless does not support that scenario. The possibility to create multiple subscriptions is intended for the scenario where the receiver needs to receive different events/messages on different endpoints.

Important: To modify a subscription, use the update endpoint rather than unsubscribing and resubscribing. Unsubscribing may result in missed messages.

Message Delivery

Shelfless ensures reliable message delivery through an automated retry system:

Feature Description
Retry Mechanism If a webhook request fails (non-2XX response), Shelfless will automatically retry with an exponential backoff pattern
Dead-Letter Queue If all retries are exhausted, messages are stored in a dead-letter queue
Requeuing Messages can be requeued for delivery at any time, with no limit on retry attempts
Delivery Confirmation Successfully delivered messages (2XX response) are confirmed and cannot be replayed
Message Persistence No messages are lost as long as a subscription is active, even if the receiving endpoint is unreachable for an extended period
Message Ordering Messages will be processed as soon as possible, but order is not guaranteed. Use the timestamps in the messages instead of relying on delivery order
Subscription Status If a subscription is deleted, no messages are generated. There is no possibility of generating messages for events that occurred during an inactive subscription period

For detailed API documentation on managing webhook subscriptions, visit the Shelfless API Documentation.

Message available for subscriptions

These events/messages are currently available for subscription: The messages are kept lightweight as in most cases the receiver knows what was ordered etc. For details if needed it is possible to act on a received message and poll details from the Shelfless API.

Available Event Types

These events are available for webhook subscription. The webhook messages are intentionally lightweight, containing only essential information. For detailed data, you can query the Shelfless API using the information provided in the webhook payload.

Event Type Description
sales_order.status Reports status updates for sales orders
purchase_order.status Reports status updates for purchase orders
article_master.updated Reports changes to master data
return_order.status Reports status updates for return orders
stock.adjustment Reports non-operational stock level changes (e.g., inventory checks, damaged goods)

Message Format

Event Structure

Each webhook event contains the following fields:

Field Type Description
id string Unique identifier for the event. Use this to prevent duplicate processing.
version string API version identifier. Currently always “1”.
timestamp number Unix timestamp when the event was sent.
type string Event type identifier (e.g., “sales_order.status”).
data object Contains the event details and related object data.

Example Event

{
    "id": "45cf7e84-842a-4e3e-b3cf-cc466ddcd953",
    "version": "1",
    "timestamp": 1732019759,
    "type": "sales_order.status",
    "data": {
        "event": {},
        "object": {}
    }
}

Detailed Event Example

Here’s an example of a sales order status event:

{
    "id": "45cf7e84-842a-4e3e-b3cf-cc466ddcd953",
    "version": "1",
    "timestamp": 1732019759,
    "type": "sales_order.status",
    "data": {
        "event": {
            "customer_number": "TESTOCS1",
            "fulfillment_order_number": "20240903-9_1",
            "items": [
                {
                    "articleId": "SKU1",
                    "detailedItems": [
                        {
                            "batchNumber": "L0343-Y",
                            "expiryDate": "2021-12-08",
                            "quantity": 1
                        }
                    ],
                    "lineId": "1",
                    "lineReference": "1",
                    "quantity": 1
                }
            ],
            "order_number": "20240903-9",
            "shipment_number": [
                "70707730149100260"
            ],
            "shipments": [
                {
                    "carrier": "BPN",
                    "shipment_number": "70707730149100260",
                    "tracking_numbers": [
                        {
                            "tracking_number": "id-1"
                        },
                        {
                            "tracking_number": "id-2"
                        }
                    ]
                }
            ],
            "status": 5,
            "status_text": "InTransit",
            "updated_at": 1732019758
        }
    }
}

Security

Verifying Webhook Signatures

To ensure the authenticity and integrity of webhook messages, each request includes a shelfless-signature header. The header follows this format:

shelfless-signature: t=1731940023,v1=7774b82d476eca1b902d3b47c27bc375d705cba7d8939a26a7e444693e2a3ef3

Where:

  • t: Timestamp when the message was sent
  • v1: HMAC signature of the payload

Signature Verification Steps

  1. Extract the timestamp and signature from the header
  2. Construct the signed payload string:
    {timestamp}.{raw_payload}
    
  3. Calculate the HMAC-SHA256 of the signed payload using your webhook secret. Please note that the secret is a hexadecimal string. Code example in Go:
    hmacKey, _ := hex.DecodeString("secretKey")
    mac := hmac.New(sha256.New, hmacKey)
    
    mac.Write([]byte(fmt.Sprintf("%s.%s", timestamp, rawPayload)))
    macSum := mac.Sum(nil)
    
    calcValue := fmt.Sprintf("%x", macSum)
    
  4. Compare your calculated signature with the received signature

Best Practices

  1. Always store the webhook secret securely
  2. Implement signature verification for all webhook requests
  3. Respond quickly to webhook requests (under 15 seconds) and process async if needed

Support

For additional support or questions about the webhook service: