Integration
Get started
To start receiving webhook events in your app:
- Create and test a webhook endpoint handler to receive event data POST requests.
- Contact your InPost Account Manager or the Integration Team.
- Share events you want to subscribe to (see Tracking Events).
- Share your HTTPS URL that should receive the notifications.
- Secure webhook by choosing your authentication method and exchange secrets with InPost.
Payload
Every webhook call is a HTTP POST with a JSON body and a fixed set of headers.
Headers
| Header | Example | Description |
|---|---|---|
| x-inpost-api-version | 2024-06-01 | Version of the payload being used in the request |
| x-inpost-topic | Shipment.Tracking | All tracking events have this header set to Shipment.Tracking |
| x-inpost-event-id | XXX123 | Unique id of the event |
| x-inpost-timestamp | 2024-04-26T14:00:03.165Z | Date and time when the webhook event is sent, in UTC |
| x-inpost-signature | XXXXXXX12345 | Signature of the request |
Body
As of today, there is only one webhook event object structure, used for the Shipment.Tracking topic.
A field reference and a JSON example are below.
Example
{
"customerReference": "XXXXXX",
"trackingNumber": "XXXXXX",
"eventId": "XYZ123",
"eventCode": "ABC987",
"timestamp": "2024-04-26T14:00:03.165Z",
"location": {
"id": "PL_ASDF",
"type": "PUDO_POINT",
"name": "ASDF",
"address": "Street Example 1",
"postalCode": "12-345",
"city": "Town Example 1",
"country": "PL",
"description": "On the left side of Petrol Station XYZ"
},
"delivery": {
"recipientName": "John Doe",
"deliveryNotes": "Leave behind a flower pot"
},
"shipment": {
"type": "OUTBOUND"
},
"returnToSender": {
"trackingNumber": "XXXXXXXX"
},
"newDestination": {
"id": "PL_XYZ",
"type": "LOCKER_POINT",
"name": "XYZ",
"address": "Street Example 2",
"postalCode": "98-765",
"city": "Town Example 2",
"country": "PL",
"description": "Behind a shop building"
}
}
- Event Object (root object)
| Field | Nullable? | Type | Description |
|---|---|---|---|
| customerReference | Yes | String | Reference/ID passed by the merchant when creating the shipment |
| trackingNumber | No | String | Tracking number generated by InPost |
| eventId | No | String | Unique id of the event (same as x-inpost-event-id header) |
| eventCode | No | String | Code of the event (refer to the event catalogue documentation for the possible values) |
| timestamp | No | String | Date and time when the event occurred, in an ISO 8601 standard format, e.g. 2026-01-01T01:01:01.123Z |
| location | Yes | Location object | Location of the event |
| delivery | Yes | Delivery object | Information about the delivery. Returned only for delivery events (see Tracking Events for the full catalogue). |
| shipment | Yes | Shipment object | Information about the shipment, when it's an outbound or return event |
| returnToSender | Yes | ReturnToSender object | The parcel's data for return-to-sender. Returned only for return-to-sender events (RTS.1001) |
| newDestination | Yes | Location object | Information about the new destination for a redirected parcel. Returned only for redirection events: LMD.3001, LMD.3002, LMD.3003, LMD.3004, LMD.3005, LMD.3006, LMD.3007, LMD.3012, LMD.3013, LMD.3014 |
- Location Object
| Field | Nullable? | Type | Description |
|---|---|---|---|
| id | Yes | String | ID of the location, returned only when type is LOCKER_POINT or PUDO_POINT |
| type | No | String | Type of location, allowable values: LOCKER_POINT, LOGISTIC_CENTER, PUDO_POINT, ADDRESS, MPOK_POINT |
| name | Yes | String | Name of the location, returned only when type is LOCKER_POINT or PUDO_POINT |
| address | Yes | String | Street, door number |
| postalCode | Yes | String | Postal code |
| city | Yes | String | City name |
| country | Yes | String | Country code (ISO 3166-1 alpha-2), e.g. PL |
| description | Yes | String | Description of the location, returned only when type is LOCKER_POINT or PUDO_POINT |
- Delivery Object
| Field | Nullable? | Type | Description |
|---|---|---|---|
| recipientName | Yes | String | Name of person who received the parcel |
| deliveryNotes | Yes | String | Notes provided by the courier upon delivery |
- Shipment Object
| Field | Nullable? | Type | Description |
|---|---|---|---|
| type | Yes | String | Type of shipment, allowable values: OUTBOUND, RETURN |
- ReturnToSender Object
| Field | Nullable? | Type | Description |
|---|---|---|---|
| trackingNumber | Yes | String | Tracking number of the returned parcel |
Security
No authentication is enforced by default, but it is strongly recommended that you implement one of the following, so your endpoint isn't open to spoofed requests.
| Method | How it works | Best for |
|---|---|---|
| Webhook Signature | InPost signs each request, subscriber system verifies the signature using a shared secret | Recommended — no extra network exposure, verifies both an integrity and an origin |
| Custom Header(s) | A shared secret value sent as a header (e.g. x-api-key) on every request | Simple setups where header-based checks are enough |
| Basic Authentication | Standard HTTP Authorization: Basic <credentials> | Legacy integrations with an existing Basic Auth gateway |
Webhook Signature (recommended)
We are supporting two methods of signing webhooks:
- HMAC signature generated using a shared secret key
- Digital signature generated based on a rotated InPost public key (deprecated)
InPost signs the request and sends the signature in the x-inpost-signature header.
During configuration, subscriber must choose if signature should include request <body> or <x-inpost-timestamp>.<body>.
See Webhook Signature Verification with a detailed explanation, verified examples, and code samples in Python, Java, .NET, PHP and JavaScript.
Custom Header(s)
A value previously agreed with InPost is sent as an HTTP header on every request, e.g. x-api-key: <value>.
The header name is configurable, and you can request up to 3 custom headers.
Share with the Integration Team:
- header name (e.g.
x-api-key) - header value
Basic Authentication
Standard HTTP Basic access authentication: Authorization: Basic <credentials>, where <credentials> is the Base64 encoding of user:password.
Share with the Integration Team:
- user
- password (12-30 characters)