If you are building an application that relies on constant updates for your Nash deliveries, then integrating a Nash webhook will help you receive real-time delivery events.

At Nash, we support a few webhooks types. The webhook response will include 3 fields:

  • type field. Webhook types can be of type delivery, task, courier_location.
  • event field which can be one of several possible statuses (see below).
  • data field which is a Job object, similar to the Create Job endpoint or see the example below.

To set up a webhook, you can do so in the Webhook Management page in the Nash Portal. Here, you can filter by event type and add multiple endpoints if you want to send different events to different endpoints, for example. All event schemas and types are enumerated under the Event Catalog tab. Select events will have example payloads. Note that event schemas are assumed to be batch jobs. If your job is not a batch job, there will be no key “batch” and you’ll see "isBatch": false, both nested under the key “data”.

We support webhooks in both sandbox and production environments. Failed webhook requests will be retried according to our retry policy and are sent securely.

type=delivery:

Frequency: once per state transition (e.g., from created -> assigned_driver, or dropoff_arrived-> dropoff_complete)

Guaranteed events: created, assigned_driver, pickup_enroute, pickup_arrived, dropoff_enroute, dropoff_arrived, dropoff_complete (guaranteed events may be inferred from future events)

Events:

Delivery events
created
not_assigned_driver
assigned_driver
started
pickup_enroute
pickup_arrived
pickup_complete
dropoff_enroute
dropoff_arrived
dropoff_complete
canceled_by_provider
return_in_progress
returned
scheduled
expired
failed
canceled_by_customer
canceled_by_nash
canceled_by_auto_reassign: this is triggered when using the auto-reassignment functionality in Dispatch Settings/Options Groups
proof_of_delivery: proof(s) of delivery have been added/updated in the `delivery.proofOfDelivery` field
pincode_verification: pincode of delivery when pincode is requested. it will be updated in the `delivery.proofOfDelivery` field
shipping_label: (SHIPPING ONLY) shipping label has been added/updated in the `delivery.documents` field
manifested: (SHIPPING ONLY) shipment has been manifested and manifest document has been added/updated in the `delivery.documents` field

type=task:

Frequency: once per state transition (e.g., from running -> completed) Events:

created
updated
running
completed
canceled_by_provider
failed
canceled_by_customer
canceled_by_nash
planned_selection
refund_created
refund_updated

type=courier_location:

Events: -updated

Frequency: once every 1-2 minutes (if courier_location is available)

Here’s a sample response that you can expect from our webhook for an ongoing delivery:

Note: All timestamps are in UTC and in this format “%Y-%m-%dT%H:%M:%S.%f”.

Webhook response
{
    "type": "delivery",
    "event": "dropoff_complete",
    "data": {
        "id": "job_R7FXJrfB99bpvpzf6CriJC",
        "createdAt": "2022-03-05T01:11:51.078927",
        "portalUrl": "https://portal.usenash.com/active/job_R7FXJrfB99bpvpzf6CriJC",
        "externalIdentifier": null,
        "jobMetadata": {
            "key": "val"
        },
        "isActive": false,
        "jobConfigurations": [
            {
                "package": {
                    "description": "Test package description",
                    "pickupEndTime": null,
                    "pickupStartTime": "2022-03-05T01:16:51",
                    "dropoffStartTime": null,
                    "dropoffEndTime": null,
                    "valueCents": 100,
                    "taxCents": 950,
                    "serviceFeeCents": null,
                    "itemsCount": 1,
                    "pickupLocation": {
                        "id": "loc_dB4x4pToexhgRvGhZSTHaQ",
                        "address": "185 University Ave, Palo Alto, CA 94301",
                        "formattedAddress": "185 University Ave, Palo Alto, CA 94301, USA",
                        "addressNumber": "185",
                        "addressFormattedStreet": "University Ave",
                        "addressCity": "Palo Alto",
                        "addressCountry": "US",
                        "addressState": "CA",
                        "addressZip": "94301",
                        "addressCounty": "Santa Clara County",
                        "businessName": "Test pickup Business",
                        "instructions": "Test pickup Instructions",
                        "firstName": "Test pickup FirstName",
                        "lastName": "Test pickup LastName",
                        "phoneNumber": "+12345679012",
                        "email": null
                    },
                    "dropoffLocation": {
                        "id": "loc_5heYem2xKGfNt9twg33kcT",
                        "address": "401 San Antonio Rd, Mountain View, CA 94040",
                        "formattedAddress": "401 San Antonio Rd, Mountain View, CA 94040, USA",
                        "addressNumber": "401",
                        "addressFormattedStreet": "San Antonio Rd",
                        "addressCity": "Mountain View",
                        "addressCountry": "US",
                        "addressState": "CA",
                        "addressZip": "94040",
                        "addressCounty": "Santa Clara County",
                        "businessName": "Test dropoff Business",
                        "instructions": "Test dropoff Instructions",
                        "firstName": "Test dropoff FirstName",
                        "lastName": "Test dropoff LastName",
                        "phoneNumber": "+12345679019",
                        "email": null
                    }
                },
                "tasks": [
                    {
                        "id": "tsk_7xKGR6PW2pBtuTeRg2b7Bw",
                        "createdAt": "2022-03-05T01:11:51.078927",
                        "status": "COMPLETED",
                        "providerId": "FleetSimulator",
                        "tipAmountCents": 250,
                        "winnerQuote": {
                            "id": "qot_nh5VSwxr4trHsuKHpQbGW6",
                            "providerId": "FleetSimulator",
                            "providerName": "FleetSimulator"
                        },
                        "quotes": [
                            {
                                "id": "qot_DSv9NrbiNMjQw556H33LkY",
                                "providerId": "uber_partner",
                                "providerName": "Uber",
                                "providerLogo": "https://nash-provider-logos.s3.us-west-1.amazonaws.com/uber-logo.png",
                                "createdTime": "2022-03-05T01:11:52.912584",
                                "expireTime": "2022-03-05T01:16:52.913410",
                              	"nashFeeCents": 100,
                                "priceCents": 1209,
                                "currency": "USD",
                                "pickupWindow": "2022-03-05T01:29:08",
                                "dropoffEta": "2022-03-05T02:03:39",
                                "tollFeeCents": 0,
                                "insuranceFeeCents": 0,
                                "totalPriceCents": 1209
                            },
                            {
                                "id": "qot_DSv9NrbiNMjQw556H33LkY",
                                "providerId": "doordash_partner",
                                "providerName": "DoorDash Drive",
                                "providerLogo": "https://nash-provider-logos.s3.us-west-1.amazonaws.com/doordash-logo.png",
                                "createdTime": "2022-03-05T01:11:52.912584",
                                "expireTime": "2022-03-05T01:16:52.913410",
                              	"nashFeeCents": 100,
                                "priceCents": 699,
                                "currency": "USD",
                                "pickupWindow": "2022-03-05T01:29:08",
                                "dropoffEta": "2022-03-05T02:03:39",
                                "tollFeeCents": 0,
                                "insuranceFeeCents": 0,
                                "totalPriceCents": 699
                            },
                            {
                                "id": "qot_nh5VSwxr4trHsuKHpQbGW6",
                                "providerId": "FleetSimulator",
                                "providerName": "FleetSimulator",
                                "providerLogo": "https://nash-provider-logos.s3.amazonaws.com/FleetSimulator.png",
                                "createdTime": "2022-03-05T01:11:52.417462",
                                "expireTime": "2022-03-05T02:11:52.417463",
                              	"nashFeeCents": 100,
                                "priceCents": 0,
                                "currency": "USD",
                                "pickupWindow": null,
                                "dropoffEta": "2022-03-05T01:17:52.417416",
                                "tollFeeCents": 0,
                                "insuranceFeeCents": 0,
                                "totalPriceCents": 0
                            },
                            {
                                "id": "qot_mfqxvKhCK8jqioCiVZBnXt",
                                "providerId": "frayt_partner",
                                "providerName": "Frayt",
                                "providerLogo": "https://nash-provider-logos.s3.us-west-1.amazonaws.com/frayt-logo.jpeg",
                                "createdTime": "2022-03-05T01:11:52.870453",
                                "expireTime": "2022-03-05T03:11:52.870457",
                              	"nashFeeCents": 100,
                                "priceCents": 3239,
                                "currency": "USD",
                                "pickupWindow": null,
                                "dropoffEta": null,
                                "tollFeeCents": 0,
                                "insuranceFeeCents": 0,
                                "totalPriceCents": 3239
                            },
                            {
                                "id": "qot_5DyiesH2CXYXunoavBuBux",
                                "providerId": "skipcart_partner",
                                "providerName": "Skipcart",
                                "providerLogo": "https://nash-provider-logos.s3.us-west-1.amazonaws.com/skipcart-logo.png",
                                "createdTime": "2022-03-05T01:11:52.900834",
                                "expireTime": "2022-03-05T01:21:52",
                              	"nashFeeCents": 100,
                                "priceCents": 699,
                                "currency": "USD",
                                "pickupWindow": "2022-03-05T01:26:51",
                                "dropoffEta": "2022-03-05T02:11:51",
                                "tollFeeCents": 0,
                                "insuranceFeeCents": 0,
                                "totalPriceCents": 699
                            },
                            {
                                "id": "qot_F48QHqWtNdEeZWNGJH9MzJ",
                                "providerId": "senpex_partner",
                                "providerName": "Senpex",
                                "providerLogo": "https://nash-provider-logos.s3.us-west-1.amazonaws.com/senpex-logo.png",
                                "createdTime": "2022-03-05T01:11:53.875782",
                                "expireTime": "2022-03-05T02:11:53.875797",
                              	"nashFeeCents": 100,
                                "priceCents": 3450,
                                "currency": "USD",
                                "pickupWindow": null,
                                "dropoffEta": "2022-03-05T02:41:53.875791",
                                "tollFeeCents": 0,
                                "insuranceFeeCents": 0,
                                "totalPriceCents": 3450
                            }
                        ],
                        "failedQuotes": [
                            {
                                "id": "qot_n7pBYDYawaEFb83VL9C6oc",
                                "providerId": "Entree_OnFleet",
                                "providerName": "Entree",
                                "errorMessage": "Provider Entree_OnFleet is ineligible because of location coverage: pickup_state=CA and dropoff_state=CA. Provider location_coverage=['IL']"
                            },
                            {
                                "id": "qot_cQWPW48ZDkHLpcR5Bof6Y8",
                                "providerId": "caterwheels_partner",
                                "providerName": "CaterWheels",
                                "errorMessage": "Provider caterwheels_partner is ineligible because of location coverage: pickup_state=CA and dropoff_state=CA. Provider location_coverage=['NY']"
                            },
                            {
                                "id": "qot_JzcNUsiqrBpDptZpDeuNwk",
                                "providerId": "deluxe_delivery_partner",
                                "providerName": "Deluxe Delivery",
                                "errorMessage": "Provider deluxe_delivery_partner is ineligible because of location coverage: pickup_state=CA and dropoff_state=CA. Provider location_coverage=['NY', 'CT', 'PA', 'NJ', 'DE', 'MD', 'VA']"
                            },
                            {
                                "id": "qot_gkXDGdT5wJvVbafHvLRrGf",
                                "providerId": "senpex_batch_partner",
                                "providerName": "Senpex (Batch)",
                                "errorMessage": "Provider senpex_batch_partner is ineligible because of PackageDeliveryMode is not scheduled"
                            },
                            {
                                "id": "qot_FoidPBMEvuFcs6rdVXmDvJ",
                                "providerId": "dropcar_partner",
                                "providerName": "Dropcar",
                                "errorMessage": "Provider dropcar_partner is ineligible because of location coverage: pickup_city='Palo Alto, CA' and dropoff_city='Mountain View, CA'. Provider location_coverage=['Chicago, IL', 'New York, NY']"
                            },
                            {
                                "id": "qot_QYjd23Rbo7Ca452pL6ACyt",
                                "providerId": "snap_partner",
                                "providerName": "Snap",
                                "errorMessage": "Provider snap_partner is ineligible because of location coverage: pickup_city='Palo Alto, CA' and dropoff_city='Mountain View, CA'. Provider location_coverage=['Chicago, IL']"
                            }
                        ],
                        "delivery": {
                            "id": "dlv_MwQDy3s6ajvw5aQ7eQPt7i",
                            "status": "DROPOFF_COMPLETE",
                            "isActive": false,
                            "pickupEta": null,
                            "dropoffEta": "2022-03-05T01:17:52.417416",
                            "dropoffDeadline": null,
                            "currency": "USD",
                          	"documents": [
                                {
                                    "id": "doc_ELre5GCELQ6w3UHKAgbm6F",
                                    "type": "SHIPPING_LABEL",
                                    "url": "https://nash-documents-dev.s3-us-west-1.amazonaws.com/dlv_bR7NWwhWSQRohyjs7UZd7D_fEavuZda787M70sJEhtCAA==.png",
                                    "data": null,
                                    "contentType": "image/png"
                                },
                              	{
                                    "id": "doc_nuKEL5W8mMgnXuRrFqwwsc",
                                    "type": "PICKUP_LABEL",
                                    "url": "https://nash-documents-dev.s3-us-west-1.amazonaws.com/dlv_bR7NWwhWSQRohyjs7UZd7D_QPiARbKwfJRkC94KVQrT8w==.png",
                                    "data": null,
                                    "contentType": "image/png"
                                }
                            ],
                            "nashFeeCents": 100,
                            "priceCents": 0,
                            "courierName": "Tjy Ifulu",
                            "courierPhoneNumber": "+13408480904",
                            "courierLocation": {
                                "lat": 37.4043247,
                                "lng": -122.1112215
                            },
                            "courierProfileImage":"https://nash-proof-of-delivery-sandbox.s3-us-west-1.amazonaws.com/dlv_SXnvEsXY4aEQ5YVY92sLPK_4t9WSOg3Zw-h4BT0fFUWqw==.jpg",
                            "proofOfDelivery": [
                                {
                                    "type": "photo_proof_of_delivery",
                                    "url": "https://nash-proof-of-delivery-sandbox.s3-us-west-1.amazonaws.com/dlv_SXnvEsXY4aEQ5YVY92sLPK_4t9WSOg3Zw-h4BT0fFUWqw==.jpg",
                                    "size": 12421
                                },
                                {
                                    "type": "barcode_scan",
                                    "text": "pkg_SggEeiudfNRQDvtAF35qPr",
                                    "url": "https://nash-proof-of-delivery-dev.s3-us-west-1.amazonaws.com/dlv_JJUqcMDdxDxoj6Zsk8iru3_rp_nNJtdAVItcnBpKxTHBQ==..png",
                                    "size": 566,
                                }
                            ],
                            "statusHistory": [
                                {
                                    "createdAt": "2022-03-05T01:12:00.984078",
                                    "status": "created"
                                },
                                {
                                    "createdAt": "2022-03-05T01:12:16.067396",
                                    "status": "not_assigned_driver"
                                },
                                {
                                    "createdAt": "2022-03-05T01:13:02.459762",
                                    "status": "assigned_driver"
                                },
                                {
                                    "createdAt": "2022-03-05T01:14:32.532602",
                                    "status": "pickup_enroute"
                                },
                                {
                                    "createdAt": "2022-03-05T01:15:17.533789",
                                    "status": "pickup_complete"
                                },
                                {
                                    "createdAt": "2022-03-05T01:16:02.598233",
                                    "status": "dropoff_enroute"
                                },
                                {
                                    "createdAt": "2022-03-05T01:17:32.690484",
                                    "status": "dropoff_arrived"
                                },
                                {
                                    "createdAt": "2022-03-05T01:18:17.945368",
                                    "status": "dropoff_complete"
                                }
                            ],
                            "tollFeeCents": 0,
                            "waitFeeCents": 0,
                            "waitTimeMinutes": 0,
                            "cancellationFeeCents": 0,
                            "returnFeeCents": 0,
                            "insuranceFeeCents": 0,
                            "taxAmountCents": 0,
                            "totalPriceCents": 0
                        },
                        "failureReason": null
                    }
                ]
            }
        ]
    }
}

Best Practices

Nash jobs can include multiple delivery attempts (see Job Overview). When processing our webhook updates, please ensure that cancellations / failures of one task does not cause issues in your application.

Furthermore, since there are multiple tasks, you should be prepared to handle multiple instances of the same webhook event. For example, if a job has two tasks - one assigned to Fleet A and another assigned to Fleet B - both fleets might send pickup arrived events. Refer to this section for more details on the guaranteed statuses we will send.

You should also be prepared for some fleets erroneously sending statuses such as pickup complete or dropoff complete when their drivers have not completed a delivery yet.

Verifying Webhooks

We use a service called Svix to send webhooks. Svix prevents attacks and forgeries as well as handles retries.

To verify the webhook, you have a couple of options:

  1. Use the Svix SDK
  2. Manually verify

In order to verify you’ll need the signing secret, which can be found in the portal under Settings > Webhooks > Click on an Endpoint > Signing Secret

Retry Policy

A webhook retry is an attempt to send a webhook message that has already failed. Our automatic retry schedule is as follows:

  • Immediately
  • 5 seconds
  • 5 minutes
  • 30 minutes
  • 2 hours
  • 5 hours
  • 10 hours
  • 10 hours (in addition to the previous)

We also offer manual retries, or you can automatically retry (“Recover”) all failed messages starting from a given date on the Nash Portal.

After the conclusion of the above attempts, the message will be marked as Failed for this endpoint, and you will get a webhook of type message.attempt.exhausted notifying you of this error.

If all attempts to a specific endpoint fail for a period of 5 days, the endpoint will be disabled, and a webhook (EndpointDisabledEvent) will be sent to your account (not to the failing endpoint).