The DoorDash Drive Refunds API has exactly one operation: POST /drive/v2/deliveries/{external_delivery_id}/refunds. You send a reason. DoorDash decides. It is the smallest of the 20 API pages DoorDash carries on the network, and it is the most interesting, because it is a business policy written as a contract.
The request is one field
The body is a RefundRequest with a single required property, refund_reason, drawn from nine values: cancelled_order, delivered_late, delivered_early, never_delivered, entire_order_wrong, missing_main, missing_side, incorrect_items, and poor_delivery_experience. That list is DoorDash’s taxonomy of what goes wrong in the last mile, published as an enum. Nothing else is defined: no amount, no line items, no evidence.
The answer is the policy
The response is where the design earns attention. A 200 returns a RefundResult that splits the money three ways, tip_refund, order_value_refund and delivery_fee_refund, each an integer in the currency’s smallest unit, plus a status of partial_refund or full_refund. It also returns a code naming who DoorDash decided was responsible: doordash_cancelled, order_delivered_late, order_delivered_early, dasher_at_fault, or doordash_at_fault.
The failures are just as explicit. A 409 returns already_refunded, so a retry cannot pay out twice and the caller learns why. A 422 returns one of five rejection codes: rejected, refund_limit_passed, could_not_determine, unsupported_payment_method, and blocked. Every result carries a human-readable message alongside the static code, so a support tool can show the reason and a program can branch on it.
| Outcome | Status | Codes |
|---|---|---|
| Granted | 200 | 5 fault codes, full or partial |
| Duplicate | 409 | already_refunded |
| Refused | 422 | 5 rejection codes |
What the contract does not say
The catalog record says it plainly: no eligibility window is published. refund_limit_passed tells you a limit exists and gives no hint of its size, whether it is per delivery, per day or per account. could_not_determine is an outcome with no documented next step. The contract states what DoorDash will tell you, not what DoorDash will decide.
The provenance is also worth reading. The provider-published contract is version 0.0.3, its description reads “Last updated: September 21, 2022,” and all three release notes are labelled “internal release.” A refund API that moves real money is running on a contract whose version number never reached 1.0.
Why an agent should care
For an agent handling a failed delivery, this is close to the ideal shape. The decision is made server-side, the duplicate is a named 409 rather than a second payout, and every outcome is a code the agent can act on without parsing prose. It pairs with its sibling, the Drive Redelivery API, which re-attempts a failed delivery against the same external_delivery_id. Refund or retry is a choice an agent can make with both contracts in hand.
The gap is the one a merchant would ask first: when will this be refused? Publishing the eligibility window and the meaning of refund_limit_passed would turn the enum from a list of outcomes into a policy you can plan around. The API reference is at developer.doordash.com, and the network record is at apis.io/apis/doordash/doordash-drive-refunds-api/.