Webhooks

Webhooks are notifications sent by us to an HTTP endpoint on one of your services. They are useful for when you want to be notified whenever something important happens on our side that you should know (eg: an order state change).

All the notifications are sent as a POST HTTP request to an endpoint that you are going to provide to us along with an authentication key, so you can check if the notification is coming from us. This authentication key is optional, but highly recomended.

To configure the webhook, get in contact with us.

Request Header

This is an example of the request header you will receive:

host: YOUR_WEBHOOK_URL
Accept: */*
Content-Type: application/json
User-Agent: Typhoeus - https://github.com/typhoeus/typhoeus
X-API-KEY: YOUR_API_KEY_HERE
X-APIKEY: YOUR_API_KEY_HERE
X-Signature: sha1=148a6d4a0e95dada696d20f702caf027b548704a
Content-Length: 1373
Connection: keep-alive

X-Signature

We are going to provide you with a unique token (which should never be exposed) so you can check the HMAC signature on each request we send to you. The signature is on the X-Signature field on the request header (see above).

This is how it works:

  1. You receive a X-Signature field on the header of each webhook request with a value (eg: sha1=148a6d4a0e95dada696d20f702caf027b548704a)
  2. This value is generated by us. It’s a result of the request body of the webhook + the unique TOKEN we gave to you. They are used in an hash algorithm called HMAC, which is going to return the value on the X-Signature.
  3. As we did, you are going to do exactly the same process in order to generate the X-Signature value. If the value you generated matches with the value we sent to you, then you know the webhook was not compromised and the content is original and safe. You are supposed to repeat the same process on each webhook request you receive using the same token we provided you with.

All the popular programming languages have support for easily generating the HMAC signature from a payload and a signature token.

Types of Webhooks

There are 4 types of webhooks in order to follow updates:

Job webhook (on demand)

It is triggered whenever a Job is created or gets updated (eg: when its state gets changed)

Payload example

{
    "action": "update",
    "payload": {
        "id": "20191107-85bddcc4",
        "job": {
            "allowed_transport_modes": [
                "scooter"
            ],
            "billing_identifier": null,
            "courier": null,
            "created_at": "2019-11-07T14:24:37.048+00:00",
            "earliest_collection_at": "2019-11-23T07:33:34Z",
            "feedback_given": false,
            "id": "20191107-85bddcc4",
            "kind": "partner_on_demand",
            "known_costs": {
                "adjustment_cost": "0.0",
                "delivery_cost": "0.0",
                "pickups_cost": "0.0",
                "service_fee": "0.0",
                "service_fee_percent": "0.0",
                "subtotal_cost": "0.0",
                "surcharge_cost": "0.0",
                "total_cost": "0.0"
            },
            "metadata": {},
            "orders": [
                {
                    "dropoff": {
                        "arrived_at": null,
                        "constraint": null,
                        "contact_name": "Tim Linssen",
                        "contact_phone": "+971599999998",
                        "finished_at": null,
                        "id": "o-2061866",
                        "item_quantity_count": 5,
                        "items": [
                            {
                                "allowed_eans": [],
                                "children": [],
                                "dimensions": null,
                                "ean": null,
                                "gid": "gid://quiqup/Job::Order::Item/3032928",
                                "id": 3032928,
                                "image": null,
                                "metadata": {},
                                "name": "Chelo Kebab",
                                "notes": null,
                                "parcel_barcode": null,
                                "price": "0.0",
                                "product_image_url": null,
                                "quantity": 2,
                                "quiqee_picking_order": null,
                                "section": [],
                                "source_gid": null,
                                "state": null,
                                "total_cost": -1,
                                "weight": null
                            },
                            {
                                "allowed_eans": [],
                                "children": [],
                                "dimensions": null,
                                "ean": null,
                                "gid": "gid://quiqup/Job::Order::Item/3032929",
                                "id": 3032929,
                                "image": null,
                                "metadata": {},
                                "name": "Slice of Margherita pizza",
                                "notes": null,
                                "parcel_barcode": null,
                                "price": "0.0",
                                "product_image_url": null,
                                "quantity": 3,
                                "quiqee_picking_order": null,
                                "section": [],
                                "source_gid": null,
                                "state": null,
                                "total_cost": -1,
                                "weight": null
                            }
                        ],
                        "location": {
                            "address1": "Emirattes Hills",
                            "address2": "1006 B",
                            "apartment_number": null,
                            "building_name": null,
                            "coords": [
                                25.0616772,
                                55.1599898
                            ],
                            "county": null,
                            "name": null,
                            "notes": null,
                            "partner_location_id": null,
                            "postcode": null,
                            "town": "Dubai"
                        },
                        "notes": "",
                        "position": 2,
                        "state": "pending",
                        "tracking_token": "881838045653bc7eb9306b5a9b93741d",
                        "tracking_url": "https://track.staging.quiqup.com/881838045653bc7eb9306b5a9b93741d",
                        "waypoint_notification": {
                            "id": 18600,
                            "job_pickup_id": 1160413,
                            "sent_at": null
                        },
                        "waypoint_type": "dropoff"
                    },
                    "id": 248665,
                    "items": [
                        {
                            "allowed_eans": [],
                            "children": [],
                            "dimensions": null,
                            "ean": null,
                            "gid": "gid://quiqup/Job::Order::Item/3032928",
                            "id": 3032928,
                            "image": null,
                            "metadata": {},
                            "name": "Chelo Kebab",
                            "notes": null,
                            "parcel_barcode": null,
                            "price": "0.0",
                            "product_image_url": null,
                            "quantity": 2,
                            "quiqee_picking_order": null,
                            "section": [],
                            "source_gid": null,
                            "state": null,
                            "total_cost": -1,
                            "weight": null
                        },
                        {
                            "allowed_eans": [],
                            "children": [],
                            "dimensions": null,
                            "ean": null,
                            "gid": "gid://quiqup/Job::Order::Item/3032929",
                            "id": 3032929,
                            "image": null,
                            "metadata": {},
                            "name": "Slice of Margherita pizza",
                            "notes": null,
                            "parcel_barcode": null,
                            "price": "0.0",
                            "product_image_url": null,
                            "quantity": 3,
                            "quiqee_picking_order": null,
                            "section": [],
                            "source_gid": null,
                            "state": null,
                            "total_cost": -1,
                            "weight": null
                        }
                    ],
                    "partner_order_id": "XYZ123456",
                    "payment_amount": "10.5",
                    "payment_mode": "paid_on_delivery",
                    "pickup": {
                        "arrived_at": null,
                        "constraint": null,
                        "contact_name": "Rafael Soares",
                        "contact_phone": "+971599999999",
                        "finished_at": null,
                        "id": "o-2671689",
                        "item_quantity_count": 5,
                        "items": [
                            {
                                "allowed_eans": [],
                                "children": [],
                                "dimensions": null,
                                "ean": null,
                                "gid": "gid://quiqup/Job::Order::Item/3032928",
                                "id": 3032928,
                                "image": null,
                                "metadata": {},
                                "name": "Chelo Kebab",
                                "notes": null,
                                "parcel_barcode": null,
                                "price": "0.0",
                                "product_image_url": null,
                                "quantity": 2,
                                "quiqee_picking_order": null,
                                "section": [],
                                "source_gid": null,
                                "state": null,
                                "total_cost": -1,
                                "weight": null
                            },
                            {
                                "allowed_eans": [],
                                "children": [],
                                "dimensions": null,
                                "ean": null,
                                "gid": "gid://quiqup/Job::Order::Item/3032929",
                                "id": 3032929,
                                "image": null,
                                "metadata": {},
                                "name": "Slice of Margherita pizza",
                                "notes": null,
                                "parcel_barcode": null,
                                "price": "0.0",
                                "product_image_url": null,
                                "quantity": 3,
                                "quiqee_picking_order": null,
                                "section": [],
                                "source_gid": null,
                                "state": null,
                                "total_cost": -1,
                                "weight": null
                            }
                        ],
                        "location": {
                            "address1": "1st Road",
                            "address2": "104G",
                            "apartment_number": null,
                            "building_name": null,
                            "coords": [
                                25.0559987,
                                55.1631158
                            ],
                            "county": null,
                            "name": null,
                            "notes": "Go directly to the kitchen on the first floor",
                            "partner_location_id": null,
                            "postcode": null,
                            "town": "Dubai"
                        },
                        "notes": "",
                        "position": 1,
                        "state": "pending",
                        "tracking_token": "1d66a26b2a51861d3026eef4900047e2",
                        "tracking_url": "https://track.staging.quiqup.com/1d66a26b2a51861d3026eef4900047e2",
                        "waypoint_notification": {
                            "id": 18599,
                            "job_pickup_id": 1160412,
                            "sent_at": null
                        },
                        "waypoint_type": "pickup"
                    }
                }
            ],
            "package_detail": null,
            "scheduled_for": null,
            "state": "pending_assignment",
            "state_updated_at": "2019-11-07T14:26:34.219+00:00",
            "submitted_at": "2019-11-07T14:26:33.949+00:00",
            "transport_mode": "scooter"
        },
        "metadata": {},
        "state": "pending_assignment"
    },
    "sent_at": "2019-11-07T14:26:34Z",
    "type": "job"
}

Order Webhook (Ecommerce)

This is going be triggered whenever an order is updated. This means that not only state changes could trigger this, but pretty much any value that is updated.

Payload example

{
    "action": "update",
    "type": "order",
    "payload": {
        "id": 275530,
        "uuid": "73516e53-5065-4176-839d-ca9330450f80",
        "state": "ready_for_collection",
        "state_updated_at": "2021-02-04T22:38:21.330+04:00",
        "kind": "partner_same_day",
        "service_kind": "partner_same_day",
        "scheduled_for": null,
        "submitted_at": "2021-02-04T22:38:21.304+04:00",
        "item_quantity_count": 1,
        "delivery_attempts": 0,
        "payment_mode": "paid_on_delivery",
        "payment_amount": "10.0",
        "delivery_failure_reason": null,
        "required_documents": [
            "customer_identification_photo"
        ],
        "partner_order_id": "PARTNER-ORDER-ID",
        "allowed_payment_types": [
            "card"
        ],
        "tracking_url": "https://track-parcel.staging.quiqup.com/73516e53-5065-4176-839d-ca9330450f80",
        "sku_info": "",
        "region_name": "Dubai",
        "created_at": "2021-02-04T22:38:16.385+04:00",
        "brand_name": "Rafael",
        "billing_identifier": "rafael-company",
        "origin": {
            "id": 1210694,
            "contact_name": "Contact name",
            "contact_phone": "972033343434",
            "arrived_at": null,
            "finished_at": null,
            "tracking_token": "deed2766a542746a091f12957313047f",
            "tracking_url": "https://track-develop.qa.quiq.ly/deed2766a542746a091f12957313047f",
            "notes": "",
            "signature": {
                "url": null
            },
            "address": {
                "id": 4584514,
                "address1": "Partner's address",
                "address2": null,
                "town": null,
                "building_name": null,
                "apartment_number": null,
                "country": "UAE",
                "coordinates": {
                    "lat": 51.5300206409701,
                    "lng": -0.26923870233607
                }
            }
        },
        "destination": {
            "id": 1210695,
            "contact_name": "John Doe",
            "contact_phone": "0618181358",
            "arrived_at": null,
            "finished_at": null,
            "tracking_token": "242414bb48ab5f40e03efe86b0393835",
            "tracking_url": "https://track-develop.qa.quiq.ly/242414bb48ab5f40e03efe86b0393835",
            "notes": "",
            "signature": {
                "url": null
            },
            "address": {
                "id": 4584515,
                "address1": "Customer's address",
                "address2": null,
                "town": null,
                "building_name": null,
                "apartment_number": null,
                "country": "UAE",
                "coordinates": {
                    "lat": 51.5315001341995,
                    "lng": -0.237550370032044
                }
            }
        },
        "items": [
            {
                "id": 3054986,
                "name": "Item's name here",
                "quantity": 1,
                "parcel_barcode": "12123124124124",
                "parcel_barcode_generated_by": "partner"
            }
        ]
    },
    "sent_at": "2021-02-04T18:38:21Z"
}

Tracking Location Webhook

This webhook is going to notify the endpoint on each 30 seconds with the last captured position of the courier.

Payload example

{
    "action": "update",
    "type": "tracking_location",
    "payload": {
        "courier": {
            "name": "Courier Name",
            "mobile_number": "+972999999999"
        },
        "coords": {
            "lat": 52.3596393746056,
            "lng": 4.98885135423016
        },
        "job": {
            "id": "20201215-d7ac3a67",
            "metadata": {},
            "next_waypoint": {
                "id": "o-2905543",
                "waypoint_type": "pickup",
                "postcode": null,
                "estimated_arrival_minutes": 7853
            }
        }
    },
    "sent_at": "2021-02-04T18:27:30Z"
}

Waypoint Webhook

It is triggered whenever a Waypoint gets updated (eg: when its state changes).

Payload example

{
    "action": "update",
    "type": "waypoint",
    "payload": {
        "id": "o-5473376",
        "contact_name": "Tim Linssen Pickup",
        "contact_phone": "+971599999999",
        "waypoint_type": "pickup",
        "notes": "Go directly to the kitchen on the first floor",
        "tracking_token": "289969397c37061b002ec92b1514fb00",
        "tracking_url": "https://track-develop.qa.quiq.ly/289969397c37061b002ec92b1514fb00",
        "state": "arrived",
        "arrived_at": "2021-02-04T22:32:58.903+04:00",
        "finished_at": null,
        "item_quantity_count": 5,
        "position": 1,
        "location": {
            "name": null,
            "address1": "1st Road",
            "address2": "104G",
            "apartment_number": null,
            "building_name": null,
            "town": "Dubai",
            "county": null,
            "postcode": null,
            "coords": [
                55.1631158,
                25.0559987
            ],
            "partner_location_id": null,
            "notes": null
        },
        "signature_image": {
            "signature": {
                "url": null,
                "full": {
                    "url": null
                },
                "medium": {
                    "url": null
                }
            }
        },
        "constraint": null,
        "waypoint_notification": {
            "id": 21469,
            "job_pickup_id": 1210299,
            "sent_at": "2021-02-04T22:32:55.382+04:00"
        },
        "items": [
            {
                "id": 3054793,
                "gid": "gid://quiqup/Job::Order::Item/3054793",
                "name": "Slice of Margherita pizza",
                "quantity": 3,
                "image": null,
                "price": "0.0",
                "notes": null,
                "total_cost": -1,
                "source_gid": null,
                "section": [],
                "weight": null,
                "product_image_url": null,
                "dimensions": null,
                "ean": null,
                "allowed_eans": [],
                "state": null,
                "quiqee_picking_order": null,
                "metadata": {},
                "parcel_barcode": null,
                "children": []
            },
            {
                "id": 3054792,
                "gid": "gid://quiqup/Job::Order::Item/3054792",
                "name": "Chelo Kebab",
                "quantity": 2,
                "image": null,
                "price": "0.0",
                "notes": null,
                "total_cost": -1,
                "source_gid": null,
                "section": [],
                "weight": null,
                "product_image_url": null,
                "dimensions": null,
                "ean": null,
                "allowed_eans": [],
                "state": null,
                "quiqee_picking_order": null,
                "metadata": {},
                "parcel_barcode": null,
                "children": []
            }
        ]
    },
    "sent_at": "2021-02-04T18:32:59Z"
}