Webhooks
Webhooks are automated messages sent from our system when something happens. They have a message or payload and are sent to a unique URL, essentially a simple way for Karla to communicate with your systems automatically. This allows you to receive real-time data about specific events without needing to poll our server continuously for updates.
See API Webhooks Reference for more information in how to set them up programmatically.
How to setup
See the Webhook Entity for more details on the API operations.
You can enable the webhooks using the Create Webhook endpoint.
{
"enabled_events": [
"shipments/in_delivery/DELIVERY_ATTEMPTED",
"shipments/delivered"
],
"secret": "41013bd9-9072-42cd-9902-66da38361be9",
"description": "Shipment Deliveries",
"status": "active",
"url": "https://example.com/my-webhook-endpoint"
}
If no enabled_events
is provided, the webhook will listen to ALL
events (["*"]
).
You can check which webhooks are defined in your shop using the Search Webhook endpoint.
Webhooks can be updated once they are live, using the Update Webhook endpoint.
{
"description": "My new description",
"url": "https://example.com/my-new-webhook-endpoint"
}
You can delete webhooks with the Delete Webhook endpoint.
Securing your endpoint
You should secure your integration by making sure your handler verifies that all webhook requests are generated by Karla.
We include a Karla-Signature
header in each signed event that contains a timestamp and a signature
that you should verify. The timestamp has a t=
prefix, and the signature has a v1=
prefix.
Karla-Signature:
t=1710864000,
v1=7f3a8b2c1d9e4f6a5b8c7d0e3f2a1b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1
We provide newlines for clarity, but a real Karla-Signature
header is on a single line.
Karla generates signatures using a hash-based message authentication code (HMAC) with SHA-256.
Verify the signature
- Extract the timestamp and signatures from the header.
- Concatenate the timestamp as a string with
.
and the actual JSON payload. - Compute an HMAC with the SHA256 hash function. Use the provided signing secret as the key.
- Compare the signature in the header to the expected signature. For an equality match, compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your tolerance.
Retry strategy
Karla sends data to your handler via POST
. In case of an unsuccessful event (non 2xx response), or if your endpoint takes longer than 10s to respond, Karla attempts to deliver your webhooks for up to 15 times with an exponential back off. The event will be lost if all attempts are exhausted.
Specification
Header
Host: api.gokarla.io
Content-Length: 12345
Accept: application/json
Karla-Signature: t=1710864000,v1=7f3a8b2c1d9e4f6a5b8c7d0e3f2a1b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1
Content-Type: application/json
Body
Payload examples
Shipment event
[
{
"source": "shipments",
"ref": "shipments/in_transit/DISPATCHED_FROM_SORTING_CENTER",
"version": 1,
"triggered_at": "2025-05-21T12:00:00Z",
"event_data": {
"shipment_id": "ee5c4b53-f661-455e-85d2-a7b7bcaf81bf",
"carrier_reference": "dhl",
"event_name": "DISPATCHED_FROM_SORTING_CENTER",
"phase": "in_transit",
"tracking_number": "123456",
"tracking_url": "https://www.dhl.de/de/privatkunden/pakete-empfangen/verfolgen.html?lang=de&idc=123456",
"updated_at": "2025-02-04T09:34:10+00:00"
},
"context": {
"order": {
"uuid": "b4fadda9-61f4-4041-94d2-7a01ee0082b4",
"order_number": "1234",
"order_name": "IXF1234",
"external_id": "2205783916624",
"order_placed_at": "2025-02-02T07:08:10+00:00",
"total_order_price": 29.99,
"shipping_price": 4.99,
"sub_total_price": 40,
"discount_price": 4.99,
"currency": "EUR",
"order_status_url": "https://shop.gokarla.io/1234067358984/orders/aabbcc/authenticate?key=secret",
"products": [
{
"title": "Product A",
"quantity": 1,
"price": 10,
"images": [],
"tax_lines": [],
"bundled_products": [],
"type": "product"
}
],
"address": {
"city": "Berlin",
"country": "Germany",
"country_code": "DE",
"name": "John Doe",
"street": "123 Fake Str",
"zip_code": "10001"
}
},
"customer": {
"external_id": "3305783916624",
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"full_name": "John Doe"
},
"shipments": [
{
"uuid": "ee5c4b53-f661-455e-85d2-a7b7bcaf81bf",
"updated_at": "2025-02-04T09:34:10+00:00",
"events": [
{
"time": "2025-02-04T08:34:10+00:00",
"phase": "in_transit",
"event_name": "DISPATCHED_FROM_SORTING_CENTER"
},
{
"time": "2025-02-03T05:14:12+00:00",
"phase": "order_processed",
"event_name": "SHIPMENT_INFO_SENT_TO_LAST_MILE_SERVICE_PROVIDER"
},
{
"time": "2025-02-03T05:14:12+00:00",
"phase": "order_processed",
"event_name": "ORDER_PROCESSED"
},
{
"time": "2025-02-02T07:08:10+00:00",
"phase": "order_created",
"event_name": "ORDER_CREATED"
}
],
"estimated_arrival": {
"from": "2025-02-05T07:49:31+00:00",
"to": "2025-02-05T11:20:27+00:00"
},
"carrier": {
"tracking_number": "123456",
"carrier_reference": "dhl",
"tracking_url": "https://www.dhl.de/de/privatkunden/pakete-empfangen/verfolgen.html?lang=de&idc=123456"
},
"flag": "normal",
"pickup": {},
"products": [
{
"title": "Product A",
"quantity": 1,
"price": 10,
"images": [],
"tax_lines": [],
"bundled_products": [],
"type": "product"
}
]
}
],
"claims": []
}
}
]
Claim event
{
"source": "claims",
"ref": "claims/CREATED",
"version": 1,
"triggered_at": "2025-05-21T12:00:00Z",
"event_data": {
"claim_id": "38fdc365-7de9-4313-afbd-0ed23717c5e0",
"event_name": "CREATED",
"created_at": "2025-02-06T11:20:27+00:00",
"updated_at": "2025-02-06T11:20:27+00:00",
"resolution_preference": "refund",
"reason": "partial_damage",
"status": "pending",
"description": "Package was damaged on the right side",
"customer_signature_image_url": "https://cdn.gokarla.io/12d6cceb-efa5-4bbc-a557-a6d31ed9f68b/df4f85de-1580-4c33-9178-cee6729e010a.png",
"selected_items": [],
"image_urls": [],
"net_invoice_amount": 30,
"dropoff_permission": true,
"weight_kg": 1,
"scan_date": "2025-02-03T05:14:12+00:00"
},
"context": {
"order": {
"uuid": "b4fadda9-61f4-4041-94d2-7a01ee0082b4",
"order_number": "1234",
"order_name": "IXF1234",
"external_id": "2205783916624",
"order_placed_at": "2025-02-02T07:08:10+00:00",
"total_order_price": 29.99,
"shipping_price": 4.99,
"sub_total_price": 40,
"discount_price": 4.99,
"currency": "EUR",
"order_status_url": "https://shop.gokarla.io/1234067358984/orders/aabbcc/authenticate?key=secret",
"products": [
{
"title": "Product A",
"quantity": 1,
"price": 10,
"images": [],
"tax_lines": [],
"bundled_products": [],
"type": "product"
}
],
"address": {
"city": "Berlin",
"country": "Germany",
"country_code": "DE",
"name": "John Doe",
"street": "123 Fake Str",
"zip_code": "10001"
}
},
"customer": {
"external_id": "3305783916624",
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"full_name": "John Doe"
},
"shipments": [
{
"uuid": "ee5c4b53-f661-455e-85d2-a7b7bcaf81bf",
"updated_at": "2025-02-05T11:30:27+00:00",
"events": [
{
"time": "2025-02-05T11:20:27+00:00",
"phase": "delivered",
"event_name": "SUCCESSFULLY_DELIVERED"
},
{
"time": "2025-02-05T07:49:31+00:00",
"phase": "in_delivery",
"event_name": "OUT_FOR_DELIVERY"
},
{
"time": "2025-02-04T08:34:10+00:00",
"phase": "in_transit",
"event_name": "DISPATCHED_FROM_SORTING_CENTER"
},
{
"time": "2025-02-03T05:14:12+00:00",
"phase": "order_processed",
"event_name": "SHIPMENT_INFO_SENT_TO_LAST_MILE_SERVICE_PROVIDER"
},
{
"time": "2025-02-03T05:14:12+00:00",
"phase": "order_processed",
"event_name": "ORDER_PROCESSED"
},
{
"time": "2025-02-02T07:08:10+00:00",
"phase": "order_created",
"event_name": "ORDER_CREATED"
}
],
"estimated_arrival": {
"from": "2025-02-05T07:49:31+00:00",
"to": "2025-02-05T11:20:27+00:00"
},
"carrier": {
"tracking_number": "123456",
"carrier_reference": "dhl",
"tracking_url": "https://www.dhl.de/de/privatkunden/pakete-empfangen/verfolgen.html?lang=de&idc=123456"
},
"flag": "normal",
"pickup": {},
"products": [
{
"title": "Product A",
"quantity": 1,
"price": 10,
"images": [],
"tax_lines": [],
"bundled_products": [],
"type": "product"
}
]
}
],
"claims": [
{
"uuid": "38fdc365-7de9-4313-afbd-0ed23717c5e0",
"resolution_preference": "refund",
"reason": "partial_damage",
"status": "pending",
"description": "Package was damaged on the right side",
"customer_signature_image_url": "https://cdn.gokarla.io/12d6cceb-efa5-4bbc-a557-a6d31ed9f68b/df4f85de-1580-4c33-9178-cee6729e010a.png",
"selected_items": [],
"image_urls": [],
"dropoff_permission": true
}
]
}
}
Event Groups
Karla provides the following event groups to your handler in relation to your customer orders.
You can subscribe to them specifically in the enabled_events
array.
Claims
claims
: all claim eventsclaims/created
: created claimsclaims/updated
: updated claims
Shipments
shipments
: all shipment eventsshipments/{phase}
: specific phases (see Shipment phases), e.g.shipments/delivered
shipments/{phase}/{name}
: specific event name (see Shipment event names by phase), e.g.shipments/in_transit/AT_SORTING_CENTER
.
Webhook subscriptions are mutually exclusive, you cannot have two webhooks listening to the same type of events at the same time. For instance, you cannot have a webhook listening on shipments
and another one on shipments/delivered
, but you can have two webhooks listening on shipments/delivered
and shipments/in_transit
respectively.
IP Whitelisting
If your service has a Firewall restricting public IPs, please add 34.77.48.225
to the allow list.