Skip to main content
POST /api/v2/storefront/media-buy-approvals/{mediaBuyId}/retry-forward Re-attempts the upstream forward for a media buy you already approved. The buy keeps its mediaBuyId and your original approval — you are re-sending the same decision, not making a new one. Over MCP the same operation is retry_forward_media_buy_approval. This is an API control. The retry action in Pending operations and in chat covers transient failures only; a buy a source refused outright routes to escalation there, not to a retry button.

Which state is your buy in?

forwardedAt alone does not tell you. It is stamped both when a forward succeeds and when one is terminalized, so read it together with the buy’s forwarding legs. Read the legs from Get an approval or the buy timeline before deciding. Forcing a retry at a delivered buy is refused rather than duplicated, but the error will not tell you the buy is healthy. A terminal forward is stamped forwardedAt even though nothing was delivered. That stamp is what stops the background worker from re-attempting it, which is correct — re-sending an identical payload to a source that structurally refused it fails the same way every time. forceTerminal is the operator override for when the underlying cause has since been fixed.

What forceTerminal cannot recover

Precondition failures. A buy terminalized before any source was contacted — a paused storefront, a storefront not ready to transact, an unconfigured or unsupported settlement currency, an expired FX quote — records no forwarding leg at all. forceTerminal is refused on these with 400 VALIDATION_ERROR, because there is no evidence the prior forward went unsent. Fix the storefront-level condition and have the buyer submit a new media buy.Update approvals. This control applies to create approvals. On an approval with kind: "update", forceTerminal is ignored and the call returns the row unchanged with no forwardOutcome.Rejected buys. Only an entry in approved state can be re-forwarded. A buy you rejected has nothing to re-send.

Before you force a retry

The platform refuses a forced retry when it has any record of an upstream booking, and it replays the original AdCP idempotency key so a source that honors it will not double-book. Neither protection is total: a source that partially wrote before failing — an ad server that created the order and then failed trafficking its line items — can leave an order upstream that we never recorded an id for, and not every third-party sales agent honors idempotency keys. So check four things first:
  1. Look in the ad server. Search for an existing order or line item for this buy. The platform’s guard cannot see a booking it never recorded.
  2. Confirm the buyer still wants it. Nothing on this path checks whether the buyer has since canceled or moved on. A forced retry can traffic a real order for a campaign nobody is expecting.
  3. Confirm the cause is actually fixed. The identical payload is replayed. If the refusal reason still holds, the retry just fails again.
  4. Check the flight window. See below.
Legitimate reasons to force a retry: a platform-side fix shipped; the product, placement, or creative was corrected; the format or size was enabled in the ad server; a credential or authorization landed after the fact; or the source’s error was operational but got classified as a refusal.

Flight dates and budget are replayed as submitted

A forced retry re-sends the payload the buyer originally submitted. Only end_time is refreshed from the live media buy — start_time and every package budget go out exactly as approved, and a cross-currency buy keeps its original FX snapshot. Days after the original approval that matters:
  • Window partly elapsed — the buy carries a start date in the past and its full original budget over fewer remaining days. Expect front-loaded pacing, and reconfirm with the buyer before forcing.
  • Window fully elapsed — nothing refuses the retry. You would book a commitment that cannot deliver. Do not force it; the buy needs a re-issued flight, not a re-forward.

Request

Parameters

The body rejects unknown fields. force_terminal — the snake_case spelling AdCP uses elsewhere — returns 400 VALIDATION_ERROR.

Response

Returns the approval-queue entry with the outcome of the dispatch this call triggered.
Read forwardOutcome to know what happened: The endpoint responds before the upstream call finishes, so deferred is the normal outcome on a successful retry rather than a sign of trouble. Poll Get an approval for the settled result; the claim lease is 60 seconds, so wait at least that long before treating a still-unsettled buy as stuck.
If the response has no forwardOutcome, nothing was re-dispatched — do not read it as a fresh success. Three causes: the buy was already forwarded; it is terminal and you did not send forceTerminal; or the background worker holds the lease and owns the attempt. In the last case forwardedAt is null.

Errors

All are 400 VALIDATION_ERROR unless noted. Use error.field to tell them apart. 404 NOT_FOUND — no approval entry with that media buy id exists for your storefront. See Errors for the full error contract.

Get an approval

Check forwardedAt and the forwarding legs before and after a retry

Decide an approval

The original approve or reject decision

Media-buy approval tasks

All media-buy approval operations

Media-buy approvals overview

Queue lifecycle and concepts