Saltar al contenido principal

Managing your Inventory

Once catalog items have been assigned to a store, you'll use the inventory endpoint to keep their store-level state — pricing and availability — accurate over time. This page walks through the day-to-day update workflows, the rate limits you should design against, and the FAQs we see most often from partners.

When to use POST vs PATCH

DoorDash expects partners to maintain inventory through two complementary mechanisms on the same endpoint:

MethodPurposeWhen to use
POSTAdds new items to a store and updates existing ones. Like PATCH, only the fields you include are written; unspecified fields remain unchanged.Whenever you need to introduce an item to a store for the first time. POST is the only way to add a new item to inventory — PATCH cannot create items. It's also required when adding or updating an item's category or subcategory attributes. Once an item exists, you can use either verb to update it.
PATCHUpdates existing items only. Same partial-update semantics as POST.Day-to-day price and availability updates for items already in the store's inventory. The rest of this page focuses on these flows.
note

POST and PATCH are both partial-update operations — neither replaces a store's full inventory snapshot. The only mechanism that performs a full feed replace is Inventory Pull, a partner-exposed endpoint DoorDash calls to retrieve a complete snapshot. See Set up Inventory Pull for that pattern. New items must be introduced via POST (or via Pull) before they can be updated with PATCH.

Endpoint

PATCH https://openapi.doordash.com/marketplace/api/v2/stores/{store_location_id}/items

Each request applies to a single store and includes an array of items. Each item object must include merchant_supplied_item_id plus only the fields you want to update. Fields omitted from the payload remain unchanged.

What to support after launch

DoorDash triggers the partner-exposed Pull endpoint once, at initial store onboarding — there is no recurring DoorDash-scheduled inventory pull for live stores. Once a store is live, third-party partners are expected to support two complementary patterns:

  1. Real-time updatesPOST/PATCH as merchants change availability and pricing, so what customers see reflects in-store reality.
  2. A nightly full refresh — a complete reconciliation of each store's inventory against your system of record.

For the nightly refresh, DoorDash recommends you initiate an Inventory Pull yourself rather than pushing a full POST/PATCH sweep. You trigger one by creating a pull job — POST /api/v2/jobs with pull_mode: "REPLACE", one request per store location — as described in Set up Inventory Pull. Two reasons this is the better path:

  • It's a lighter lift. You expose one endpoint and fire a small job-creation request per store, instead of packaging every store's entire inventory into 10K-item batches and managing that throughput yourself.
  • It fully replaces the store's inventory. DoorDash overwrites the store's StoreItem attributes with what your endpoint returns, so the result matches your system of record exactly rather than accumulating drift from partial updates.

Core update scenarios

The three scenarios below cover the vast majority of PATCH traffic. Each section shows a single representative payload — combine fields in one request when you have multiple changes for the same item.

Update pricing

Use this when a price changes — for example, a base-price update reflecting a new vendor cost, or a markdown after a holiday.

base_price is the only price field a price update requires. For an item that is not discounted, send it on its own:

{
"items": [
{
"merchant_supplied_item_id": "item-1024",
"price_info": {
"base_price": 1399
}
}
]
}

Add sale_price only while the item is actively marked down. When both are present, DoorDash shows base_price struck through and highlights sale_price as the price the customer pays, and the item becomes eligible for the Deals category:

{
"items": [
{
"merchant_supplied_item_id": "item-1024",
"price_info": {
"base_price": 1399,
"sale_price": 1199
}
}
]
}
  • Leave sale_price out of the payload entirely when an item isn't discounted. Don't send it as 0 or as a copy of base_pricesale_price must be less than base_price and between 1 and 1000000, so both are rejected.
  • Because POST and PATCH are partial updates, a sale_price already on an item persists until it's overwritten — omitting it does not clear it. To reset a store's pricing wholesale after a promotion, use an Inventory Pull with pull_mode: "REPLACE", which overwrites the store's StoreItem attributes with whatever your endpoint returns.
  • All prices are in cents (1399 = $13.99). See FAQ for the full list of money/tax field formats.

Remove an item (item_availability: INACTIVE)

DoorDash does not support deleting store-assigned items. To stop offering an item at a specific store, mark it inactive — this hides the item from search, browse, and ordering flows while preserving its pricing, modifiers, and metadata.

{
"items": [
{
"merchant_supplied_item_id": "item-1024",
"item_availability": "INACTIVE"
}
]
}
  • Configuration is preserved, not deleted — you can reactivate without re-posting.
  • Use this for seasonal pauses, temporary stockouts, or items you intend to bring back.

Reactivate an item (item_availability: ACTIVE)

To bring a previously inactive item back, send a PATCH setting availability back to ACTIVE. The item reappears with its prior pricing and modifiers intact.

{
"items": [
{
"merchant_supplied_item_id": "item-1024",
"item_availability": "ACTIVE"
}
]
}
  • Do not re-POST the item to reactivate it — that path is for new store items.
  • Avoid rapid toggling between ACTIVE and INACTIVE; frequent flips can cause caching delays and inconsistent visibility.

Rate limits

DoorDash enforces rate limits at both the merchant and store level. The limits below are the guidance partners should design against. If your throughput needs exceed these consistently, submit a support request in the Developer Portal or coordinate with your Technical Account Manager (TAM).

API EndpointBatch SizeRate Limit
Inventory POSTUp to 10K items per request5–10 QPS
Inventory PATCHUp to 10K items per request5–10 QPS
Inventory PullDefault 10K items per response (raisable on request)5–10 QPS
note

The default Inventory Pull batch limit is 10K items per response. There is no hard upper bound — to raise yours, submit a support request in the Developer Portal or coordinate with your TAM. Partners running large catalogs are commonly raised to 100K items on both inventory and catalog pull.

When you exceed the limit, DoorDash returns 422 request_rate_limited or 429 request_rate_limited. Handle these with exponential backoff — retry after 5 seconds, then 15 seconds, then 45 seconds. Avoid immediate retries, which can compound throttling.

Monitoring

Review request and job logs in the Developer Portal — see Inventory API Event Logs for the full schema, item-level success/failure breakdowns, and error reference. Watch for FAILED or PARTIAL_SUCCESS operation statuses and resolve item-level errors promptly.

FAQ

When should I use POST vs PATCH? Use POST to add new items to a store's inventory — it's the only way to introduce an item that doesn't exist yet, and it's also required when adding or updating category or subcategory attributes. Use PATCH for updates to existing items (price and availability). Both verbs perform partial updates: only the fields you include are written. For a true full feed replace, see Inventory Pull.

How often should I send PATCH updates? Most partners refresh data every 5–15 minutes to reflect sales, restocks, and manual adjustments. Send updates only when something has actually changed — repeated PATCH calls with identical payloads add load without benefit.

Should I batch updates? How many items per call? Yes — batch related updates for the same store into a single request. Inventory POST and PATCH accept up to 10K items per request. For a single store, combining price + availability changes in one call is generally better than two sequential calls.

Why use INACTIVE instead of deleting? DoorDash doesn't support deletion of assigned store items. Marking an item INACTIVE hides it from customer-facing surfaces while preserving its pricing, modifiers, and metadata, so reactivation is a single PATCH — no re-onboarding required.

Why does my PATCH return a "missing price" error when I'm only sending an availability change? This usually means the item isn't yet in the store's inventory. PATCH updates existing items only — it cannot create them. If you PATCH an item that hasn't been added to a store, the API rejects the call with a missing price error even though your payload looks complete. To resolve, first add the item via POST (including all required fields — at minimum merchant_supplied_item_id, price, and item_availability) or via Inventory Pull. Once the item exists in inventory, subsequent PATCH calls will succeed.

Should I send balance_on_hand, and can I use balance_on_hand: 0 to make an item unavailable? balance_on_hand is an optional, informational field — sending it is not required, and balance_on_hand: 0 does not make an item unorderable. To take an item out of search, browse, and ordering, use item_availability: "INACTIVE"; that is the only mechanism that removes it from customer-facing surfaces.

What happens if I hit a rate limit? You'll receive 422 or 429 with code request_rate_limited. Back off exponentially (5s / 15s / 45s) and resume. See Rate limits above.

How do I confirm an update succeeded? Check the synchronous response (operation_status of SUCCESS, FAILED, or PARTIAL_SUCCESS), and review the asynchronous event log in the Developer Portal for item-level results. The Inventory API Event Logs page covers the full schema and common error reasons.

What format should price and tax fields take? base_price, sale_price, and bottle_fee are integers in cents (a $10.99 item has base_price: 1099). tax_rate is a double in percent (8% = 8, 5.5% = 5.5).