How to Build for Parcels
Overview​
DashLink is a delivery service that runs on top of the DoorDash Drive API. While it can be used in tandem with our traditional Drive product (eg. a one-off delivery from a storefront direct to a customer) the request and response payloads vary greatly between these two offerings. This doc should exclusively and solely be used for building a DashLink delivery integration.
Getting Started​
Account creation and authentication​
Since the DashLink offering is built on top of the Drive product, the steps you take to create an account, add users and generate access keys can be found in our published documentation.
- If you intend on building a ship-from-store (ie. one-off scheduled deliveries), you may experiment with the API at this time. If you are only focused on a DashLink integration, please wait for the step below.
[Important] Account configuration​
The DashLink team will need to enable your developer account for the parcel fulfillment method. Once configured, we will provide you with some key values you will use when making requests to our service. Please email your DashLink contact with the email address used to create your developer account. Note: It will take a few days to enable your account for the parcel fulfillment method.
Postman collection​
Click ths link to access a DashLink specific postman collection. Note: this collection is different from the postman collection linked on the official DoorDash Drive developer documentation.
Published documentation​
While this PDF is the most comprehensive resource for building a DashLink integration, the link below will provide additional context into our Drive endpoints for parcel fulfillment type. Specifically adding context into some of the extraneous response fields not covered in this document, as well as error response handling.
(READ ME) Important Integration Information​
Critical configurations​
There are account level settings that can impact the scheduling of deliveries you create with DashLink, as well as what fields we return in the API. These settings are maintained by DashLink and configured during onboarding, but it's worth calling them out in the integration documentation since they may affect your integration strategy.
- Order cutoff times - There is a set and static time each day when DashLink will assume packages created before that time will arrive the same day. Anything created after will be expected to arrive the following day.
- Days of operation - Knowing your days of operations helps us understand what day a package is expected to arrive at our facility
- Eg. If we only pick up from your warehouse Mon-Fri, when shipments get created Sat/Sun we will know to expect them on Monday.
- Package arrival delay - Knowing the number of days between when a shipment is created and when it is expected to arrive at a DashLink facility is critical to ensuring your deliveries are adequately scheduled and planned for. This setting will mostly be relevant for packages that take greater than one day from label creation to DashLink facility injection.
- Eg. If your packages are prelabeled overseas and are then imported into the US
- Tracking code source - DashLink can generate a unique tracking code for each delivery, or we allow the shipper to provide their own tracking code. If you intend on passing us the tracking code, please follow the guidelines below:
- Each tracking code must be unique
- Tracking code must be between 15-35 characters long
- [recommended] Do not use leading 0s in the tracking code
- [recommended] Prepend a 3 letter alpha code identifying your company. Please clear with DashLink first so we can ensure there is not another shipper with the same code.
- Eg. a company named DashLink might use “DLK” at the beginning.
- Each tracking code must be unique
- Shipping label source - You can decide whether you wish to generate your own shipping label or if one should be returned to you in the response. If you wish DashLink to generate the shipping label, we offer the following static configurations that can be configured by your account manager.
- ZPL 203 DPI, ZPL 300 DPI, or PDF label types
- NOTE: all label options are 4”x6” in dimension
Best Practices​
Order creation flows​
- Synchronous label generation workflows [recommended]:
- This is when you select DashLink as your carrier for a shipment and create deliveries in real-time via create delivery endpoint or delivery quote + accept quote endpoints. If for some reason you are unable to successfully create a delivery in DashLink (bad address, out of service area, etc.), you would receive an error from DashLink and be able to select another carrier for the shipment.
- This option is preferred and less prone to downstream issues. Since you are waiting on a response from DashLink before placing a shipping label on the package, you can be assured that DashLink will have information regarding your shipment when it arrives at our facilities.
- This is when you select DashLink as your carrier for a shipment and create deliveries in real-time via create delivery endpoint or delivery quote + accept quote endpoints. If for some reason you are unable to successfully create a delivery in DashLink (bad address, out of service area, etc.), you would receive an error from DashLink and be able to select another carrier for the shipment.
- Asynchronous / Specialized label generation workflows
- This is when you select DashLink as your carrier for a shipment and generate tracking codes and labels “in-house” and apply them to packages. You then send the shipment data over to DashLink in batches, either once a day or every few hours.
- Benefits: This flow reduces latency and dependencies by eliminating the need for external API requests during the label creation/order fulfillment process. This is often the preferred method for shippers with large fulfillment operations, specialized shipping label requirements, or unique sortation workflows.
- However convenient, this option is more susceptible to error. We see timing issues where packages arrive at facilities before being created in DashLink’s system. We also see create delivery requests fail (eg. bad address, unserviceable address, etc.) leaving a package labeled and bound for DashLink with no ability to create the delivery in DashLink. Please ensure you have spoken to the DashLink team before embarking down this integration workflow.
- This is when you select DashLink as your carrier for a shipment and generate tracking codes and labels “in-house” and apply them to packages. You then send the shipment data over to DashLink in batches, either once a day or every few hours.
Zip code coverage - serviceable areas​
The serviceable zip codes by DashLink may be updated as frequently as once a quarter. For shippers that will not be using our rate endpoint to validate the address as deliverable, please make sure that the serviceable zip list is configured in a way that allows easy updates (adding and removing zips).
For context, DashLink does not deliver to all zip codes across the contiguous US, but is constantly working to increase our coverage and refine the zips we already cover.
Proof of delivery images​
Upon a successful delivery, you will get a URL for a proof of delivery (POD) image. For long term access to the image, we recommend you download and store the image on your servers, as the image URL will expire 7 days after it was generated. At any time, you can get a refreshed Image link (valid for another 7 days) by calling our delivery status endpoint.
SMS notifications​
We strongly encourage shippers to utilize our SMS services. They are highly customizable (you can select which events trigger SMS messages and completely customize the text) and have been shown to improve successful delivery rate through increased delivery awareness. It also opens up the potential for real-time communication between dashers and recipients to exchange instructions or last minute delivery guidance.
- Eg. dasher texts recipient for access gate code for apartment complex
To activate this setting, we will need a valid recipient's phone number (must be their mobile). During onboarding, we can work to ensure your DashLink account is properly set up and configured for SMS messages. Here is the public documentation showing how to access SMS settings in your DoorDash portal.
Address validation​
DashLink will attempt to validate the address on every delivery that is created in our system. We will geocode the latitude and longitude of the delivery based on the validators' suggestions. If updates to the address are made, they can be found in the API response (dropoff_address_components object) when creating a delivery. Note, we will not print the updated address onto the label, we will pass through the exact address sent to us in the request.
We strongly encourage shippers to perform address validation as far upstream in the ordering process as possible, ideally in the shopping cart. This enables customers to make updates directly in real-time and don’t need to be contacted for updates later on in the fulfillment or delivery process.
Tracking links​
DoorDash tracking links have a standard syntax so shippers can predict the tracking link for any of their packages by inserting a valid DashLink tracking code into the URL. This allows our shippers to easily send customers clickable tracking URLs in emails, tracking apps, etc.
DoorDash tracking pages also enable users to add or edit delivery instructions, gate codes, apartment numbers, building names, etc. to help ensure successful delivery.
Platform integrators (more than one shipper will be using the integration)​
For our shipping software and platform integrators, you will need to decide which integration method is best for you and your shippers:
- Require each shipper on your platform to have their own unique accounts and set of credentials. The shipper will need to plug in their credentials within your software to begin using the DashLink service.
- Pros:
- Ideal when the platform is outside the payment chain and shipment invoicing will occur directly between the shipper and DashLink.
- Ideal solution if shippers need to ingest tracking data outside your platform. Since our webhook service will fire events for ALL packages created on an account with no method to filter by individual business or store.
- Cons:
- Shippers will need to manage their own account credentials and store configurations.
- If your engineers need to view logs or look at any account level settings maintained by DashLink, you will need to either be added as a user on the shippers DoorDash account OR have the shipper team get the information for you.
- Pros:
- The integrator has a master account with all subsequent shippers being nested underneath as unique businesses and stores.
- Pros:
- Ideal for platforms that intend to be in the payment chain and sell DashLink shipping services to their shippers.
- Integrator has complete control over the account to adjust DashLink controlled settings and review logs at anytime
- Shippers can be completely hands off in the process to activate DashLink
- Cons:
- If shippers would like to receive data that is unique to their shipments, DashLink may not be able to filter data by the individual shipper (eg. webhook tracking subscriptions include all events for every package).
- Pros:
Rate limiting and testing our service​
If we notice >300 requests to our APIs in a 60 second time frame, it will alert our eng team. If activity continues at this rate, we will disable the API credentials.
If you are a high volume shipper or plan to perform load/resiliency testing, please work with your account manager to get your limits raised. .
POST Delivery Quote & Create Delivery​
Endpoint(s)​
Delivery quote: POST https://openapi.doordash.com/drive/v2/quotes
Create delivery: POST https://openapi.doordash.com/drive/v2/deliveries
Details: The primary behavioral difference between the quote (ie. rate request) and create delivery (ie. shipment or package) endpoints is that a successful quote request will still need to be “accepted” to create a delivery in our database. The requests payloads are identical, while the response payloads vary slightly.
Notable payload discrepancy: the quote response will not contain any information regarding the shipping label. If using Dashlnk generated shipping labels, you will need to capture the shipping label info from the accept response.
Field details
NOTE: For sample request and response payloads (create delivery response is comprehensive, so we will use it as the example), see Appendix A. below.
Request fields​
This is a list of all the fields (required and/or recommended) in the request payload.
Field Name | Description | Details |
---|---|---|
order_fulfillment_method | string | Required Value must be “parcel” |
pickup_business_name | string | Strongly recommended This value will be used on the tracking page and in SMS communications to the package recipient. If you are a 3pl, you will want to pass the brand name of the order being fulfilled. |
external_delivery_id | string | Required If you are providing your own tracking code. Please refer to the “tracking code source” guidance above for ideal formatting and pass your unique tracking code here. Character limits: 15-35 If DashLink is generating tracking code, please pass an empty string [eg. ""]. |
origin_facility_id | string | Required Set value provided by DashLink during onboarding that represent each unique address (ie. warehouse or storefront) where packages will be originating. If the shipper has unique facility IDs they prefer to use, we can configure the DashLink system to use those IDs. |
pickup_external_business_id | string | Required Set value provided by DashLink during onboarding representing the business name of the shipper. |
dropoff_address | string | Required Address, City, State, Zip (all in a single string) |
dropoff_business_name | string | Business name for delivery address to help a delivery driver find the correct commercial location. Character limit: 50 |
dropoff_location | object | If lat/lng are provided in the request, it will override any geocoding done by the DashLink platform. Note: If you enable customers to confirm delivery location with a map UI, it is strongly recommended that you include these data points to avoid DashLink assuming an incorrect lat/long location. |
lat | number | Latitude of the delivery address |
lng | number | Longitude of the delivery address |
dropoff_contact_given_name | string | Required First name of package recipient Character limit: 25 |
dropoff_contact_family_name | string | Required Last name of package recipient Character limit: 25 NOTE: if you are unable to split the first and last name in your system, you may send the entire name in both the “given” and “family” name fields. It will print out twice on the label, but the delivery will not be negatively affected. |
dropoff_phone_number | string | Required Used to communicate with package recipients. If you do not have the recipient's phone number, you will need to hardcode a valid phone number. E164 phone number formatting required [eg. +16505555555] |
dropoff_address_components | object | Required |
street_address | string | Address 1 Character limit: 50 |
sub_premise | string | Unit, floor, apt #, etc. [commonly referred to as address 2] Character limit: 50 |
city | string | City name |
state | string | 2 letter state code [eg. “CA”] |
zip_code | integer | 5 digit zip code |
country | string | Value must be “US” for not until we begin supporting international shipments. |
dropoff_instructions | string | Strongly recommended Instructions for the delivery driver to follow when dropping off the order. Character limit: 100 |
dropoff_contact_send_notifications | boolean | Whether the contact will receive notifications from DashLink for this delivery. The default is true. |
order_value | number | The subtotal for all items in the package denominated in cents. i.e. $19.99 = 1999 This value may be used to settle claims, so please ensure it is accurate |
currency | string | Value must be “USD” |
items | array | Required NOTE: when using the DashLink service, the “item” will represent the entire package being shipped. Please use the outer packaging (shipping box, poly mailer, etc) as the item. Although this is an array, currently, we only allow a single item to be passed with each shipment request. |
name | string | Required Name of the goods being shipped (eg. Character limit: 50 “Womens jacket”) |
description | string | Description of the goods being shipped (eg. Character limit: 50 “clothing”) |
external_id | string | Shippers can pass any value they wish in this field. It will get printed onto the label. We commonly see external order Ids, etc. NOTE: if you are utilizing our multi-drop service, please pass the shared order ID for all associated packages. This field will be used to tie orders together for invoicing. Character limit: 50 |
quantity | integer | Required Value must be 1 |
height | number | Required Height of the package in inches (ie. 12 inches = 12) |
width | number | Required Width of the package in inches (ie. 12 inches = 12) |
length | number | Required Length of the package in inches (ie. 12 inches = 12) |
volume | number | Volume of the package size represented in cubic feet Formula: (height inches x width inches x length inches) / 1,728 = cubic ft. |
weight | number | Required Weight of the package in lbs (ie. 3.5lbs = 3.5) |
price | number | Cost of the goods in the package denominated in cents. i.e. $11.43 = 1143. |
contactless_dropoff | boolean | Unless your delivery will be “signature required”, this value should always be set to true. The default is true if not declared in the request. |
signature_required | boolean | If your package requires a signature, please pass true in this field and false in the “contactless_dropoff” field. NOTE: most deliveries are not “signature_required” as there is typically an extra fee associated with these deliveries. The default is false if not declared in the request. |
Response fields​
- If a field was already described above, we may exclude it from the table below unless additional context is needed.
- We will only describe the fields relevant to the DashLink service, please see our published documentation for a complete list of explanations.
- For error codes and their meanings, please refer to the published documentation. This will include useful errors with specific messaging if a delivery is failing due to the delivery address being out of the service area, driving distance being too long, ect.
Field Name | Description | Details |
---|---|---|
order_fulfillment_method | string | All of these fields represent the unique tracking code for this package, whether you provided this value in the request or DashLink generated it internally. |
pickup_reference_tag | string | All of these fields represent the unique tracking code for this package, whether you provided this value in the request or DashLink generated it internally. |
items.barcode | string | All of these fields represent the unique tracking code for this package, whether you provided this value in the request or DashLink generated it internally. |
delivery_status | string | For Quote request: ”quote” For Delivery request: ” created” |
fee | number | The cost 3DashLink will charge for this delivery denominated in cents. i.e. $7.49 = 749 |
dropoff_location | object | Geo location for the updated address (DashLink automatically performs an address validation) |
lat | number | Latitude of the updated dropoff address |
lng | number | Longitude of the updated dropoff address |
dropoff_address_components (not included in accept response) | object | (Updated address) DashLink performs an address validation on every delivery request and the updated address components will be returned in these fields. NOTE: This means these values may differ from the address submitted in the request. |
street_address | string | Updated Address 1 |
sub_premise | string | Unit, floor, appt #, etc. [commonly referred to as address 2] |
city | string | Updated City name |
state | string | Updated 2 letter state code [eg. “CA”] |
zip_code | integer | Updated 5 digit zip code |
dropoff_time_estimated | string | Date for the expected delivery and the latest time we would expect packages to be delivered. The vast majority of the packages will be delivered prior to the time provided, with a small minority being delivered after. NOTE: the delivery date will be highly dependent on DashLink receiving the package on the day we anticipate. Please see the "Critical configurations" section above to understand how cutoff times affect these calculations. |
tracking_url | string | Publicly accessible tracking URL for this package. This can be sent directly to the recipient for tracking throughout the package lifecycle. |
shipping_label (not included in accept response) | object | There is an account level setting if you wish to have a label returned (we allow shippers to create their own tracking numbers and labels) |
label_format | string | Expect “ZPL” or “PDF” depending on account settings. |
label_size | string | Value will be “4x6” |
print_density | string | If format is ZPL, expect settings “203dpi” or “300dpi” depending on account |
label _string | string | Base64 encoded string. Label format is an account level setting configured during onboarding. ZPL & PDF formats are supported at this time. |
action_if_undeliverable | string | Value will be “return_to_pickup” |
POST Accept delivery quote​
Endpoint(s)​
Accept quote: POST https://openapi.doordash.com/drive/v2/quotes/{external_delivery_id}/accept
Details: After you have created a quote, you can accept the quote using this endpoint. This will schedule a delivery for your package.
DashLink will generate a tracking code in the quote response which will remain the same if the quote is accepted within the allowable timeline.
Timeline to accept the quote
Quotes will be valid for five minutes. If quotes are not accepted within that timeline, you will be required to generate a new quote or you can just use the create delivery endpoint directly.
Field details
Request URL parameter:
- In the quote response, there will be a field called external_delivery_id (this field could be provided by the requestor or by DashLink depending on the account settings). This value should be inserted as a path parameter on the accept quote endpoint
Response fields​
For successful response field descriptions, see the “Delivery quote & Create delivery” response information above.
Notable payload discrepancy: If you are using dropoff_address_components fields, this will not be returned in the accept quote endpoint. You will need to log these values from the quote endpoint if you wish to capture any changes made by our address validation.
PUT Cancel Delivery​
Endpoint(s)​
Cancel delivery: PUT https://openapi.doordash.com/drive/v2/deliveries/{external_delivery_id}/cancel
Details
Packages that were created but will not be handed off to DashLink can be cancelled. NOTE: If you cancel an order that ends up at a DashLink facility, we will reactivate the order in our system and schedule for delivery.
Field details
Request URL parameter:
- Use the external_delivery_id (this field could be provided by the requestor or by DashLink depending on the account settings) as a path parameter to cancel the delivery.
Response fields​
To confirm that your delivery has successfully been canceled, look for the fields and their values provided in the table below. If you wish to see all the fields in the response, view our published documentation.
Field Name | Description | Details |
---|---|---|
delivery_status | string | Value should be cancelled |
cancellation_reason | string | Value should be cancelled_by_creator |
Tracking updates via webhooks [recommended]​
Details
It is strongly preferred that merchants use our webhook service to receive tracking updates. It offers the most comprehensive data set and events are sent in near real time. NOTE: For each configured webhook URL, DoorDash will send all events on all packages created on the account.
Setup​
See official webhook setup documentation to add your webhook endpoint through the developer portal.
NOTE: please use the table in Appendix B. or this published web page to interpret parcel tracking the events and reason codes. Please ignore all other published webhook event interpretation docs as it does not pertain to the parcel fulfillment method.
Event payload​
Below is a table that describes the fields in the webhook payload. See Appendix C. for a few sample webhook payloads with a complete list of fields..
NOTE: Fields that have already been described or are frivolous will be omitted from the table below. This includes static value fields included in the quote/create delivery responses (ie. address info, order dimensions, etc.).
Field Name | Description | Details |
---|---|---|
created_at | string | This timestamp should be used as the date and time of this tracking event. ISO-8601 format |
event_name | string | Tracking status for this event See Appendix B below for all webhook event status values and corresponding mappings |
external_delivery_id / pickup_reference_tag | string | Both of these fields represent the unique tracking code for this package, whether you provided this value in the request or DashLink generated it internally. NOTE: we strongly encourage you to use the reference_pickup_tag when mapping tracking. This will always remain constant even if there are multiple delivery attempts. |
dropoff_verification_image_url | string | Link to the picture taken by the Dasher to indicate where the order was dropped off. The link will expire 7 days after the webhook was fired. |
dasher_name | string | When a dasher gets assigned to the delivery, their first and last name/initial will be available in this field. Eg. “John Driver” |
dasher_dropoff_phone_number | string | Phone number for the delivery Dasher; can only be called from dropoff_phone_number. |
dasher_pickup_phone_number | string | Phone number for the delivery Dasher; can only be called from pickup_phone_number. |
dasher_vehicle_make | string | Make of the Dasher's vehicle Eg. “Toyota” |
dasher_vehicle_model | string | Model of the Dasher's vehicle Eg. “Camry” |
dasher_vehicle_year | string | Year of the Dasher's vehicle Eg. “2020” |
dasher_location | object | Near real-time location of the dasher |
lat | number | Latitude of the location |
long | number | Longitude of the location |
dropoff_time_estimated | string | Most up to date expected delivery date and time. ISO-8601 timestamp. |
package_location | object | |
city | string | City where the event occurred |
state | string | 2 letter state code [eg. “CA”] where the event occurred |
zip_code | string | 5 digit zip code where the event occurred |
timezone | string | This will tell you the local time zone where the event is taking place. Enum: “US/Pacific”, “US/Mountain”, “US/Central”, “US/Eastern” |
description | string | A user-friendly display string in english explaining the webhook event, meant to show to customers on a tracking page. If you need a list of potential description strings, please reach out to your DashLink contact. Note: these values are subject to change (albeit infrequently) to always reflect the most accurate description of the event. Eg. “Your package has been delivered.” |
GET Delivery status via API endpoint(s)​
We strongly recommend using our webhook service as a primary source of tracking data and only using our tracking APIs as a supplement.
Endpoint(s)​
- Endpoint # 1: GET https://openapi.doordash.com/webhooks/drive/geteventhistory/{external_delivery_id}
- Endpoint # 2: GET https://openapi.doordash.com/drive/v2/deliveries/{external_delivery_id}
Details
We offer tracking events via API, but you will need to utilize a combination of two different endpoints to get the information that is provided through our webhooks subscription.
- Endpoint # 1: This is an unauthenticated endpoint ideal for capturing the package statuses. Pass the external_delivery_id in the URL path and you will get an array of all the events for the package.
- Endpoint # 2: This endpoint belongs to the core DoorDash Drive collection and will require the same authentication used to create deliveries. Its primary utility should be to capture proof of delivery images and a few other delivery metadata updates (dasher car details, expected delivery timestamp, etc).
- The status types returned in the response are more appropriate for same day/restaurant type deliveries. We do not recommend using this endpoint to fetch tracking status updates for a package.
- NOTE: The response will only return the current status of the delivery. It will not provide a history of past events.
Request URL parameter​
Insert the external_delivery_id (this field could be provided by the requestor or by DashLink depending on the account settings) as a path parameter on both tracking endpoints to fetch tracking details regarding the specific shipment.
Response fields​
See Appendix D. for tracking payloads
Endpoint # 1 (unauthenticated status endpoint)​
Field Name | Description | Details |
---|---|---|
eventHistory | array | Events listed in ascending order (oldest to newest). |
event_name | string | High level tracking status of the delivery. For potential enum values, see Appendix B for mappings and descriptions. |
timestamp | string | Date and time of when the event took place. ISO-8601 timestamp |
event_location | object | |
city_name | string | City where the event occurred |
state | string | 2 letter state code [eg. “CA”] where the event occurred |
postal_code | string | 5 digit zip code where the event occurred |
NOTE: Fields that have already been described or are frivolous will be omitted from the table below. This includes static value fields included in the quote/create delivery responses (ie. address info, order dimensions, etc.)
Endpoint # 2 (authenticated Drive status endpoint)​
Field Name | Description | Details |
---|---|---|
external_delivery_id / pickup_reference_tag / items.barcode | string | All of these fields represent the unique tracking code for this package, whether you provided this value in the request or DashLink generated it internally. NOTE: we strongly encourage you to use the reference_pickup_tag when mapping tracking. This will always remain constant even if there are multiple delivery attempts. |
delivery_status | string | These values are more relevant for single pickup→ delivery (eg. food delivery). We do not recommend using this value for parcel fulfillment method tracking. See published documentation for enum values and more details |
cancellation_reason | string | If the delivery_status is “cancelled” , then we provide a reason for the cancellation here. See published documentation for enum values and more details |
pickup_time_actual | string | This timestamp represents when a dasher picked up the package for delivery. Field will be null if the package has not yet been picked up. ISO-8601 format |
dropoff_time_estimate | string | If the delivery is still in progress, this field will have the most up to date estimated delivery timestamp. ISO-8601 format |
dropoff_time_actual | string | This timestamp represents when a dasher delivered the package. Field will be null if the package has not yet been delivered. ISO-8601 format |
return_time_actual | string | This timestamp represents when a dasher returned the package to a DashLink facility. Field will be null if the package has not yet been returned. ISO-8601 format |
dropoff_verification_image_url | string | Link to the picture taken by the Dasher to indicate where the order was dropped off. The link will expire 7 days after the API request was made. |
dasher_name | string | When a dasher gets assigned to the delivery, their first and last name/initial will be available in this field. Eg. “John Driver” |
dasher_dropoff_phone_number | string | Phone number for the delivery Dasher; can only be called from dropoff_phone_number. Should include the country code. |
dasher_pickup_phone_number | string | Phone number for the delivery Dasher; can only be called from pickup_phone_number. Should include the country code. |
dasher_vehicle_make | string | Make of the Dasher's vehicle Eg. “Toyota” |
dasher_vehicle_model | string | Model of the Dasher's vehicle Eg. “Camry” |
dasher_vehicle_year | string | Year of the Dasher's vehicle Eg. “2020” |
dasher_location | object | Near real-time location of the dasher |
lat | number | Latitude of the location |
lng | number | Longitude of the location |
package_location | object | |
city | string | City where the event occurred |
state | string | 2 letter state code [eg. “CA”] where the event occurred |
zip_code | string | 5 digit zip code where the event occurred |
timezone | string | This will tell you the local time zone where the event is taking place. Enum: “US/Pacific”, “US/Mountain”, “US Central”, “US/Eastern” |
Shipping label criteria​
DashLink generated label​
In the response of the quote or create delivery requests, DashLink will return a base64 encoded label string.
- If you wish to receive a label in the response, this is an account level setting managed by DashLink.
- See Appendix E. below for a sample image of the label
- For label options and sizes, see the Critical Configurations - Shipping label section above
Shipper generated labels​
You can generate your own labels using your own tracking code or a DashLink generated tracking code returned in the response.
- Label requirements:
- Recipients' name and full address should be prominent on the label.
- Scannable barcode should be on the label that represents the external_delivery_id / pickup_reference_tag
- Acceptable barcode types: Data Matrix, AZTEC, Code 128, Code 39, Code 93, CODABAR, EAN 13, EAN 8, ITF, UPC A, UPC E, PDF417.
- Label recommendations:
- There should not be any other prominent barcodes on the label. This could result in our scanners picking up the incorrect barcode and not being able to lookup the package data.
- Printing the ship date on the label can help teams visually identify packages with older ship dates.
- Printing the shipper name on the top left hand corner of the label can be useful to our operations team if ever the need arises to isolate a shipper's packages visually.
- There should not be any other prominent barcodes on the label. This could result in our scanners picking up the incorrect barcode and not being able to lookup the package data.
Appendix​
A. Request and Response for Delivery Creation​
Sample request and response payloads [Create Endpoints]
Click here to access request and response payloads for all endpoints in Postman.
Request w/ sample data
{
"order_fulfillment_method": "parcel",
"pickup_business_name": "Best Clothing Brand",
"external_delivery_id": "",
"pickup_external_business_id": "BestClothingBrand",
"origin_facility_id": "BestClothingBrand-CA-1",
"dropoff_address": "12952 14th St, Yucaipa, CA 92399",
"dropoff_business_name": "",
"dropoff_contact_given_name": "Jane",
"dropoff_contact_family_name": "Doe",
"dropoff_phone_number": "+16505555555",
"dropoff_address_components": {
"street_address": "12952 14th St",
"sub_premise": "Apt# 45",
"city": "Yucaipa",
"state": "CA",
"zip_code": 92399,
"country": "US"
},
"dropoff_instructions": "Place package behind garden gnome",
"dropoff_contact_send_notifications": true,
"order_value": 4999,
"currency": "USD",
"items": [
{
"name": "Package 1",
"description": "Clothing",
"external_id": "order-1234",
"quantity": 1,
"height": 12,
"width": 10,
"length": 16,
"volume": 5.3,
"weight": 2.8,
"price": 4999
}
],
"contactless_dropoff": true,
"signature_required": false
}
Response w/ sample data
{
"external_delivery_id": "DDVXXGRZTQGYSJCUD",
"currency": "USD",
"delivery_status": "created",
"fee": 600,
"order_fulfillment_method": "parcel",
"pickup_address": "2270 Camino Vida Roble, Carlsbad, CA 92011-1503, United States",
"pickup_business_name": "Best Clothing Brand",
"pickup_phone_number": "+118003772753",
"pickup_reference_tag": "DDVXXGRZTQGYSJCUD",
"pickup_external_business_id": "BestClothingBrand",
"pickup_external_store_id": "INE-11",
"dropoff_address": "12952 14th St, Yucaipa, CA 92399-1824, United States",
"dropoff_business_name": "",
"dropoff_location": {
"lat": 34.01852,
"lng": -117.095529
},
"dropoff_phone_number": "+16505555555",
"dropoff_instructions": "Place package behind garden gnome",
"dropoff_contact_given_name": "Jane",
"dropoff_contact_family_name": "Doe",
"dropoff_contact_send_notifications": true,
"dropoff_options": {
"signature": "none",
"id_verification": "none",
"proof_of_delivery": "none",
"catering_setup": "none"
},
"dropoff_address_components": {
"street_address": "12952 14th St",
"city": "Yucaipa",
"state": "CA",
"zip_code": "92399",
"country": "United States"
},
"order_value": 4999,
"items": [
{
"name": "Package 1",
"quantity": 1,
"description": "Clothing",
"external_id": "DDVXXGRZTQGYSJCUD",
"volume": 5.3,
"weight": 2.8,
"length": 16.0,
"width": 10.0,
"height": 12.0,
"price": 4999,
"barcode": "order-1234"
}
],
"updated_at": "2024-10-07T16:08:41.523161Z",
"pickup_time_estimated": "2024-10-09T05:11:24Z",
"dropoff_time_estimated": "2024-10-09T05:59:00Z",
"fee_components": [],
"tax": 0,
"tax_components": [],
"support_reference": "2334377777",
"tracking_url": "https://track.doordash.com/order/DDVXXGRZTQGYSJCUD/track",
"shipping_label": {
"label_format": "pdf",
"label_size": "4x6",
"label_string": "JVBERi0xLjQKJfbk…<TRUNCATED>"
},
"contactless_dropoff": true,
"action_if_undeliverable": "return_to_pickup",
"tip": 0,
"order_contains": {
"alcohol": false,
"pharmacy_items": false,
"age_restricted_pharmacy_items": false,
"tobacco": false,
"hemp": false,
"otc": false
},
"dropoff_requires_signature": false,
"dropoff_cash_on_delivery": 0
}
B. Webhook tracking status mapping​
DashLink utilizes a few different fields to communicate tracking status information at a granular level. Below we will map out all our potential combinations and their real-world meanings so you can map.interpret them accurately on your side.
* = Terminal status These events should represent the end of a package journey. You should not expect more events on the package.
Event Status [passed in event_name field] | Corresponding reason field and reason value | Event description |
---|---|---|
PARCEL_LABELED | n/a | A delivery has been created with Dashlink. |
PARCEL_AWAITING | Reason field: parcel_awaiting_reason Enum values: "missing_from_truck", "other" | DashLink has yet to receive the package by the expected handoff date and time. Additional insight: "missing_from_truck” - DashLink was expecting the package to arrive at the facility, but it did not. Common reason for this are: 1) the package did not make it onto the truck before it left the shippers facility 2) the package was accidentally sorted to another carrier by accident and will not arrive at a DashLink facility without intervention from the shipper and their other carrier partners |
PARCEL_SCANNED | n/a | First scan of the package at final delivery facility |
PARCEL_ORIGIN_ARRIVED | n/a | When a driver has arrived to pickup a package from the shippers facility *not relevant for most shippers |
PARCEL_ORIGIN_PICKED_UP | n/a | When a package is confirmed picked up via scan from a shippers facility *not relevant for most shippers |
PARCEL_MID_MILE_ARRIVED | n/a | First scan of the package at DashLink sortation facility |
PARCEL_MID_MILE_DEPARTED | n/a | Package departed a DashLink sortation facility |
DASHER_PICKED_UP | n/a | Delivery driver has picked up the package for final delivery (ie. out for delivery) |
DASHER_CONFIRMED_DROPOFF_ARRRIVAL | n/a | Delivery drivers' GPS location is near the final delivery address. A delivery attempt should be made soon. |
* DASHER_DROPPED_OFF | n/a | The delivery driver has successfully completed the package delivery. |
DASHER_ATTEMPTED_DELIVERY | Reason field: undeliverable_reason_code Enum values: “missing_unit_gate_code”, “cant_find_apartment_unit”, “business_closed”, “incorrect_address”, “technology_issue”, “route_abandoned”, “recipient_refused”, “emergency“, "other” | A delivery attempt was made, but was unsuccessful. These reason codes are feedback input by the driver as to why the package could not be delivered. NOTE: there is an additional field called “Undeliverable_reason_additional_details” that may contain additional open text notes from the driver. Additional insight: “incorrect_address” - typically means the address is incomplete, doesn’t exist, etc. “technology_issue” - there was an driver app issue (bad routing, app crash, etc) preventing the delivery“ "route_abandoned” - the delivery driver was unable to finish delivering packages. The package should get returned to our facility and rescheduled for delivery tomorrow.“ "emergency" - typically means there was inclement weather, the location was unsafe, or there was a driver related emergency "other” - generic reason bucket when another more granular reason is not selected |
PARCEL_RECEIVED_TO_REDELIVER * PARCEL_RETURN_TO_MERCHANT | Reason field: return_reason Enum values: “missing_unit_gate_code”, “cant_find_apartment_unit”, “business_closed”, “incorrect_address”, “technology_issue”, “route_abandoned”, “recipient_refused”, ”emergency“, "damaged", "other” | A delivery attempt was made, but was unsuccessful. These reason codes are feedback input by the team receiving the packages at the delivery hub. event_name details: PARCEL_RECEIVED_TO_REDELIVER - this top level event is sent when DashLink intends on trying another delivery attempt PARCEL_RETURN_TO_MERCHANT - this top level event means the package will be returned to the shipper and will not be re-attempted for delivery For additional insight regarding the reason codes, see above cell |
PARCEL_DELAYED | Reason field: parcel_delayed_reason Enum values: “missing_from_truck”, “driver_unassigned”, “misplaced_at_sortation”, “other” | Package is delayed within the DashLink network. Specific causes can be found in the “parcel_delayed_reason” field. “Other” will be chosen when the reason doesn’t |
* PARCEL_LOST_IN_TRANSIT | n/a | The package was lost after being received at a DashLink facility |
PARCEL_DAMAGED | n/a | If the package is damaged, we will trigger an event declaring the package is damaged. This will typically be followed by a return or dispose event (depending on what the shipper prefers) |
* PARCEL_DISPOSED | n/a | If DashLink is disposing of packages, we will push an event signifying that the package has been disposed of. |
C. Webhook payload samples - multiple statuses​
Remember, DashLink payloads will contain different fields depending on the status of a delivery.
Delivered successfully
{
"created_at": "2024-10-08T01:07:10.102523Z",
"event_name": "DASHER_DROPPED_OFF",
"external_delivery_id": "DDVXXGRZTQGYSJCUD",
"dasher_id": 10000001,
"dasher_name": "John Driver",
"dasher_phone_number": "+13023064157",
"dasher_dropoff_phone_number": "+13023064157",
"dasher_pickup_phone_number": "+14842558605",
"dasher_location": {
"lat": 34.00730852408077,
"lng": -84.6281955301558
},
"dasher_vehicle_make": "Toyota",
"dasher_vehicle_model": "Tundra Regular Cab",
"dasher_vehicle_year": "",
"pickup_address": "2200 Thornton Rd # 100## 100, Lithia Springs, GA 30122",
"pickup_phone_number": "+118003772753",
"pickup_instructions": "",
"pickup_reference_tag": "DDVXXGRZTQGYSJCUD",
"pickup_external_business_id": "BestClothingBrand",
"pickup_external_store_id": "ATL-11",
"dropoff_address": "111 Hawks Rd., Kennesaw, GA 30152",
"dropoff_phone_number": "16505555555",
"dropoff_instructions": "Place package behind garden gnome",
"dropoff_contact_given_name": "Jane",
"dropoff_contact_family_name": "Doe",
"dropoff_contact_send_notifications": true,
"order_value": 0,
"currency": "USD",
"pickup_time_estimated": "2024-10-07T21:29:33.000000Z",
"pickup_time_actual": "2024-10-07T21:29:33.569724Z",
"dropoff_time_estimated": "2024-10-08T04:09:09.000000Z",
"dropoff_time_actual": "2024-10-08T04:01:06.741457Z",
"fee": 775,
"tip": 0,
"support_reference": "1234567890",
"tracking_url": "https://track.doordash.com/order/DDVXXGRZTQGYSJCUD/track",
"contactless": true,
"updated_at": "2024-10-07T11:41:44.192199Z",
"dropoff_verification_image_url": "https://drive-asset.doordash.com/dasher-dropoff-photos/media/delivery_verification/delivery/<TRUNCATED>",
"batch_id": "<UUID>",
"package_location": {
"city": "Kennesaw",
"state": "GA",
"zip_code": "30152",
"timezone": "US/Eastern"
},
"description": "Your package has been delivered."
}
Received back at facility to re-attempt delivery (see return_reason field)
{
"created_at": "2024-10-08T03:46:09.066759Z",
"event_name": "PARCEL_RECEIVED_TO_REDELIVER",
"external_delivery_id": "DDVXXGRZTQGYSJCUD",
"dasher_id": 35388888,
"dasher_name": "John Driver",
"dasher_phone_number": "+14246000000",
"dasher_dropoff_phone_number": "+14246000000",
"dasher_pickup_phone_number": "+19452622222",
"dasher_location": {
"lat": 39.26073671939668,
"lng": -76.6710735696587
},
"dasher_vehicle_make": "Nissan",
"dasher_vehicle_model": "Sentra",
"dasher_vehicle_year": "2023",
"pickup_address": "1420 Joh Ave Ste E#Ste E, Halethorpe, MD 21227",
"pickup_phone_number": "+17865725523",
"pickup_instructions": "",
"pickup_reference_tag": "DDVXXGRZTQGYSJCUD",
"pickup_external_business_id": "BestClothingBrand",
"pickup_external_store_id": "BLT-1",
"dropoff_address": "1 Maryland Dr",
"dropoff_phone_number": "+13023064157",
"dropoff_instructions": "Drop at front door inside the gate",
"dropoff_contact_given_name": "Jane",
"dropoff_contact_family_name": "Doe",
"dropoff_contact_send_notifications": false,
"order_value": 0,
"currency": "USD",
"pickup_time_estimated": "2024-10-07T17:51:21.000000Z",
"pickup_time_actual": "2024-10-08T03:39:26.572086Z",
"dropoff_time_estimated": "2024-10-08T03:39:26.000000Z",
"dropoff_time_actual": "2024-10-08T03:46:06.905651Z",
"fee": 278,
"tip": 0,
"support_reference": "2334077777",
"tracking_url": "https://track.doordash.com/order/DDVXXGRZTQGYSJCUD/track",
"contactless": true,
"updated_at": "2024-10-08T03:46:06.905651Z",
"batch_id": "<UUID>",
"return_reason": "missing_unit_gate_code",
"package_location": {
"city": "Baltimore",
"state": "MD",
"zip_code": "21213",
"timezone": "US/Eastern"
},
"description": "Your scheduled delivery date has been updated. Ensure that your delivery instructions are accurate."
}
D. Tracking payloads​
Endpoint #1 Response from unauthenticated endpoint for tracking statuses
{
"eventHistory": [
{
"event_name": "parcel_labeled",
"timestamp": "2024-06-24T23:43:44Z"
},
{
"event_name": "arrived_at_mid_mile_facility",
"timestamp": "2024-06-25T03:45:48Z",
"event_location": {
"city_name": "Lynnwood",
"state": "WA",
"postal_code": "98046"
}
},
{
"event_name": "departed_mid_mile_facility",
"timestamp": "2024-06-25T03:56:50Z",
"event_location": {
"city_name": "Lynnwood",
"state": "WA",
"postal_code": "98046"
}
},
{
"event_name": "arrived_at_mid_mile_facility",
"timestamp": "2024-06-25T12:49:14Z",
"event_location": {
"city_name": "Seattle",
"state": "WA",
"postal_code": "98121"
}
},
{
"event_name": "parcel_scanned",
"timestamp": "2024-06-25T12:55:21Z",
"event_location": {
"city_name": "Seattle",
"state": "WA",
"postal_code": "98101"
}
},
{
"event_name": "dasher_picked_up",
"timestamp": "2024-06-25T18:22:36Z"
},
{
"event_name": "dasher_attempted_delivery",
"timestamp": "2024-06-25T18:58:23Z"
},
{
"event_name": "parcel_received_to_redeliver",
"timestamp": "2024-06-25T22:05:14Z"
},
{
"event_name": "dasher_picked_up",
"timestamp": "2024-06-26T18:33:28Z"
},
{
"event_name": "dasher_confirmed_dropoff_arrival",
"timestamp": "2024-06-26T19:01:21Z",
"event_location": {
"city_name": "Seattle",
"state": "WA",
"postal_code": "98101"
}
},
{
"event_name": "dasher_dropped_off",
"timestamp": "2024-06-26T19:02:02Z",
"event_location": {
"city_name": "Seattle",
"state": "WA",
"postal_code": "98101"
}
}
]
}
E. Sample tracking label​
Example label generated by DashLink, found in the shipping_label.label_string field.