Update a promotion

See the Promotions API Guides for prerequisites and the full upload lifecycle.

Summary

Apply a single-promotion update outside the daily bulk upload. The request body is a full promotion block; it atomically replaces the existing promotion with this promotion_id (last write wins). Async — returns a job_id of type single_promotion_update which the partner polls for completion.

Usage scenario

  • Intraday correction: re-send the full block with corrected fields (price, items, sites, time window).
  • Emergency removal: send the block with end_at set to a past timestamp.

Business constraints

  • The promotion_id in the URL path must match the promotion_id in the request body.
  • If a bulk upload covering this promotion_id is still processing, the request returns 409 JOB_IN_PROGRESS. Retry once the bulk job reaches a terminal state.
  • No built-in duplicate detection — guard retries on the client side with your own request ID if you need at-most-once semantics.
  • promotion_id is preserved across updates — use it as your stable handle. The underlying campaign reference may change after an update (the pipeline cancels and recreates the campaign), so do not store campaign-level identifiers long-term.

Operational constraints

  • Rate limit: 60 requests per brand per minute.
Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…
Path Params
string
required

The unique identifier for the brand, provided during onboarding by the Deliveroo integration team. Use the exact value supplied by Deliveroo rather than constructing it yourself.

string
required
length ≤ 128
^[A-Za-z0-9_.\-]+$

Partner-supplied external promotion identifier. Mandatory on every promotion — the API does not auto-generate IDs. One promotion_id = one mechanic = one reward, unique within a file. A promotion_id can be reused in a later upload once the previous instance reaches a terminal state (completed or failed). Max 128 chars, ASCII printable (A–Z, a–z, 0–9, _, -, .).

Body Params
string
required
length ≤ 128
^[A-Za-z0-9_.\-]+$

Partner's external promotion identifier. Mandatory — the API does not auto-generate IDs. Unique within a file: one promotion_id = one mechanic = one reward. Max 128 chars, ASCII printable (A–Z, a–z, 0–9, _, -, .).

string
enum
required

The promotion mechanic. Determines which condition and reward sub-fields are required (see those schemas). A single-item multibuy triggers when the customer buys condition.quantity units of the same item; a multiple-item multibuy triggers when the customer assembles a bundle of condition.quantity units across different items from condition.items.

string

Human-readable promotion name (for partner-side reporting and reconciliation).

string
enum

Customer segment. Defaults to ALL_CUSTOMERS if omitted. LOYALTY_CUSTOMER requires the partner's loyalty programme to be set up with Deliveroo — partners should consult their Account Manager before integrating loyalty promotions. PLUS_SUBSCRIBER is incompatible with FREE_DELIVERY (Plus already includes free delivery). Enforcement is handled by Deliveroo's consumer-side validation; no additional partner integration is required for loyalty gating.

Allowed:
date-time
required

Promotion start. Use explicit UTC (Z) or offset (e.g. +01:00). Inclusive — the promotion is active AT this timestamp.

date-time
required

Promotion end. Must be strictly greater than start_at. Inclusive — the promotion is active UNTIL AND INCLUDING this timestamp. No minimum lead time — partners may shrink an active promotion to end at the current time.

sites
array of strings
required

Partner location IDs the promotion applies to. Must already be synced to Deliveroo. Each promotion carries its own sites.

sites*
string
enum
Defaults to ANY

Restricts the promotion to a specific order fulfillment channel. Defaults to ANY. Grocery partners typically use DELIVERY or COLLECTION.

Allowed:
condition
object
required

What the basket must satisfy for the promotion to apply. Field requirements depend on promotion_type:

  • items is required for every item-level type (all types except PERCENTAGE_OFF_ON_BASKET and FREE_DELIVERY).
  • quantity is required on PERCENTAGE_OFF_ON_SECOND_ITEM, every *_MULTIBUY type, and the BUY_X_* types — it is the qualifying "buy N" count the basket must contain.
  • min_order_value and alcohol_allowed are valid on PERCENTAGE_OFF_ON_BASKET and FREE_DELIVERY only.

Currency for min_order_value is derived from the brand_id (a brand is bound to a single market at onboarding). Values are in minor currency units (pence for GBP, cents for EUR, etc.).

reward
object
required

What the customer gets. Field requirements depend on promotion_type:

  • percentage is required on every PERCENTAGE_* type and on BUY_X_PLUS_SAVE_Y_PERCENT.
  • amount_off is required on every AMOUNT_* type.
  • fixed_price is required on every FIXED_PRICE_* type.
  • quantity is the reward-side quantity — the number of items received, required on BUY_X_GET_Y.
  • max_discount is valid on PERCENTAGE_* types only.
  • FREE_DELIVERY takes no reward fields — send an empty object ({}).

Currency for amount_off / fixed_price / max_discount is derived from the brand_id (a brand is bound to a single market at onboarding). Values are in minor currency units (pence for GBP, cents for EUR, etc.).

Responses

Language
Credentials
OAuth2
LoadingLoading…
Response
Choose an example:
application/json