When is this event triggered?This webhook is sent only when the delivery was dispatched with
logistic_data.pickup_verification.pincode_owner = "abbiamo"in the Delivery request payload (the driver to seller pincode model — see Pickup pincode).Abbiamo has already validated the PIN typed by the store operator against its own copy of the code. This call asks the carrier to unlock the driver in the carrier's app so the physical collection can proceed.
This webhook is synchronousAbbiamo waits for the carrier's response on the same HTTP request — there is no callback. The HTTP status code and
codefield returned by the carrier directly decide whether the collection is released to the store operator.
- Default timeout: 5 seconds. If your handler needs longer processing, respond
200 / driver_unlockedas soon as the unlock is committed in your database and finish the rest asynchronously on your side.- Retries: Abbiamo retries once on
5xx/ timeout. There are no retries on4xxresponses.
Whenever the store operator submits the pickup PIN in the Abbiamo dashboard and Abbiamo confirms it locally, this event is fired to the carrier's webhook URL. The carrier must unlock the driver in its own app and respond synchronously.
The payload mirrors the same identifying blocks already sent on the original Delivery request (seller, carrier, delivery identifiers, logistic_data), so the carrier can locate the delivery in its own systems and reuse any context that arrived at dispatch time (e.g. a seller-specific token inside logistic_data.headers):
{
"event_type": "PICKUP_PIN_VALIDATION_REQUEST",
"event_at": "2026-05-12T14:34:17.890Z",
"seller": {
"seller_name": "Go Go Fruits",
"seller_id": "eb064ede-08f3-470e-a37c-5b796a17cca8",
"seller_document_number": "88399480000156",
"seller_group_id": "b7d56bca-606e-405e-bf4d-9b0a3291b61d",
"seller_contacts": [
{
"name": "Eduardo Silveira",
"phone": "21999999999",
"phone_country_code": "55",
"email": "[email protected]"
}
]
},
"carrier": {
"name": "CARRIER_BRAND_NAME",
"max_dispatched_time": "14:00:00-03",
"expected_delivery_date": "2022-12-22T23:59:00.000-03:00",
"total_expected_delivery_price": 1200,
"method": {
"external_id": "name/id",
"id": "e84b2788-5b78-40dd-95cf-75807f70aaaa",
"name": "CARRIER_BRAND_NAME_D0",
"type": "D0"
}
},
"invoice_number": "example_invoice_number_1",
"invoice_access_key": "42081183123141000200550010000007010046403276",
"delivery_id": "851dc274-e090-4881-8f3c-5b660cecf059",
"order_number": "example_carrier_payload_1",
"logistic_data": {
"headers": {
"Authorization": "Bearer xxx"
},
"pickup_verification": {
"pincode": true,
"pincode_owner": "abbiamo",
"pincode_value": "8745"
}
}
}
This is a release call, not a re-validationAbbiamo is the source of truth for the PIN in the driver to seller pincode model and has already validated it locally before firing this webhook. The carrier must not re-validate the
pincode_valueechoed insidelogistic_data.pickup_verification— the only purpose of this endpoint is to unlock the driver in the carrier's app.The
pincode_valueis echoed here only because the wholelogistic_datablock is re-sent for convenience (so the carrier can reuse any context it relied on at dispatch — most often a seller-specific token insidelogistic_data.headers). If the carrier does not need that context, it can safely ignore everything other thandelivery_id.
Expected responses
The carrier must reply on the same HTTP response. Abbiamo uses the response to decide whether to transition the delivery to COLLECTED and release the collection on the store side.
| HTTP | code | Meaning |
|---|---|---|
| 200 | driver_unlocked | Driver was unlocked in the carrier's app. Abbiamo transitions the delivery to COLLECTED and returns success to the store operator. |
| 200 | already_unlocked | Driver was already unlocked (idempotent retry of the same delivery_id). Same effect as driver_unlocked. |
| 404 | DELIVERY_NOT_FOUND | The carrier does not recognize this delivery_id. Abbiamo surfaces the error to the operator. No retry. |
| 409 | INVALID_DRIVER_STATUS | The driver is no longer in a valid state to collect (already gave up, already left the pickup point, etc.). Abbiamo blocks the collection. No retry. |
| 5xx / timeout | — | Abbiamo retries once immediately. If it still fails, the operator sees a "carrier unavailable" error in the dashboard and the delivery stays put. |
Example response for 200 / driver_unlocked:
{
"code": "driver_unlocked",
"delivery_id": "851dc274-e090-4881-8f3c-5b660cecf059",
"unlocked_at": "2026-05-12T14:34:18.014Z",
"driver": {
"name": "Carlos Silva",
"document_number": "12345678900"
}
}
Idempotency is requiredThe carrier endpoint must accept a second call with the same
delivery_idwithout side effects and reply200 / already_unlocked. Abbiamo treatsdriver_unlockedandalready_unlockedequivalently as success, which keeps the retry behavior safe.
Where to register the URL
The endpoint that listens for this event lives at the same URL the carrier registers for DELIVERY_REQUEST and CANCELLATION_REQUEST events — or at a separate URL if you prefer. See Receive events for the registration step. Carriers that do not yet support the driver to seller pincode model can skip registering this URL; in that case, Abbiamo simply never dispatches deliveries with pincode_owner = "abbiamo" to your integration.

