curl --request POST \
--url https://api.interchange.io/api/v2/storefront/media-buy-approvals/{mediaBuyId}/retry-forward \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"forceTerminal": false
}
'import requests
url = "https://api.interchange.io/api/v2/storefront/media-buy-approvals/{mediaBuyId}/retry-forward"
payload = { "forceTerminal": False }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({forceTerminal: false})
};
fetch('https://api.interchange.io/api/v2/storefront/media-buy-approvals/{mediaBuyId}/retry-forward', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"id": "42",
"kind": "create",
"storefrontId": "1234",
"mediaBuyId": "<string>",
"buyerCustomerId": 0,
"submittedPayload": "<unknown>",
"status": "pending",
"reviewedBy": "<string>",
"reviewedAt": "2023-11-07T05:31:56Z",
"reviewerNotes": "<string>",
"forwardedAt": "2023-11-07T05:31:56Z",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"readiness": {
"packages": [
{
"mediaProductId": "<string>",
"buyerRef": "<string>",
"assignedCreativeIds": [
"<string>"
],
"unusableCreatives": [
{
"creativeId": "<string>",
"reason": "<string>"
}
],
"unusableCreativeCount": 4503599627370495,
"compatibleUnattachedCreativeIds": [
"<string>"
],
"compatibleUnattachedCreativeCount": 4503599627370495
}
],
"packageCount": 4503599627370495,
"creativelessPackageCount": 4503599627370495,
"creativeSyncFailures": [
{
"creativeId": "<string>",
"status": "<string>",
"detail": "<string>"
}
],
"creativeSyncFailureCount": 4503599627370495
},
"forwardOutcome": "deferred",
"forwardResult": [
{
"sourceId": "<string>",
"status": "<string>",
"upstreamMediaBuyId": "<string>"
}
]
}{
"data": null,
"error": {
"code": "<string>",
"message": "<string>",
"field": "<string>",
"details": {}
}
}{
"data": null,
"error": {
"code": "<string>",
"message": "<string>",
"field": "<string>",
"details": {}
}
}{
"data": null,
"error": {
"code": "<string>",
"message": "<string>",
"field": "<string>",
"details": {}
}
}Retry forwarding an approved media buy
Re-attempt the upstream forward for an already-approved media buy whose previous forward did not complete. Idempotent: the storefront reuses the same idempotency key, so a source that already received the buy is not double-booked. Returns the approval-queue entry with its refreshed forwarding state. A buy terminalized by a structural failure is recoverable in place with forceTerminal: true, which re-forwards it under the same mediaBuyId and keeps the original approval — the request is refused unless every persisted source route is a failed, unsent leg, so a forced retry cannot duplicate an upstream buy.
curl --request POST \
--url https://api.interchange.io/api/v2/storefront/media-buy-approvals/{mediaBuyId}/retry-forward \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"forceTerminal": false
}
'import requests
url = "https://api.interchange.io/api/v2/storefront/media-buy-approvals/{mediaBuyId}/retry-forward"
payload = { "forceTerminal": False }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({forceTerminal: false})
};
fetch('https://api.interchange.io/api/v2/storefront/media-buy-approvals/{mediaBuyId}/retry-forward', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"id": "42",
"kind": "create",
"storefrontId": "1234",
"mediaBuyId": "<string>",
"buyerCustomerId": 0,
"submittedPayload": "<unknown>",
"status": "pending",
"reviewedBy": "<string>",
"reviewedAt": "2023-11-07T05:31:56Z",
"reviewerNotes": "<string>",
"forwardedAt": "2023-11-07T05:31:56Z",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"readiness": {
"packages": [
{
"mediaProductId": "<string>",
"buyerRef": "<string>",
"assignedCreativeIds": [
"<string>"
],
"unusableCreatives": [
{
"creativeId": "<string>",
"reason": "<string>"
}
],
"unusableCreativeCount": 4503599627370495,
"compatibleUnattachedCreativeIds": [
"<string>"
],
"compatibleUnattachedCreativeCount": 4503599627370495
}
],
"packageCount": 4503599627370495,
"creativelessPackageCount": 4503599627370495,
"creativeSyncFailures": [
{
"creativeId": "<string>",
"status": "<string>",
"detail": "<string>"
}
],
"creativeSyncFailureCount": 4503599627370495
},
"forwardOutcome": "deferred",
"forwardResult": [
{
"sourceId": "<string>",
"status": "<string>",
"upstreamMediaBuyId": "<string>"
}
]
}{
"data": null,
"error": {
"code": "<string>",
"message": "<string>",
"field": "<string>",
"details": {}
}
}{
"data": null,
"error": {
"code": "<string>",
"message": "<string>",
"field": "<string>",
"details": {}
}
}{
"data": null,
"error": {
"code": "<string>",
"message": "<string>",
"field": "<string>",
"details": {}
}
}Authorizations
API key or access token
Path Parameters
Buyer-supplied media buy identifier (AdCP media_buy_id).
1Body
Request body for retrying forwarding. The terminal override is an operator recovery control and is guarded against duplicate upstream writes.
Buyer customer id that disambiguates a buyer-scoped media-buy id. Omit only when the id is known to be unique for this storefront.
0 < x <= 9007199254740991Allow retrying an incorrectly terminalized approval only when every persisted source route is a failed, unsent leg. The request is rejected if any source has an upstream media-buy or task id.
Why this retry is being made — recorded against the attempt so a later reviewer can tell a considered recovery from a reflexive one. Strongly recommended with forceTerminal, which overrides a terminal state in front of an ad server.
1 - 500"Dimension-derivation fix shipped in v4.118.0; GAM order absent."
Response
Retry forwarding an approved media buy
An approval-queue entry returned from a retry-forward attempt, carrying the outcome of the dispatch when one ran.
Surrogate id of the approval row (BIGINT serialized as string).
"42"
Approval workstream kind. create is an initial create_media_buy approval; update is a material update_media_buy approval for an already-created buy.
create, update Storefront the pending buy was submitted to (BIGINT serialized as string).
"1234"
Buyer-supplied media buy identifier (AdCP media_buy_id). Unique per storefront — re-submitting the same id is idempotent.
Customer id of the buyer who submitted the media buy.
-9007199254740991 <= x <= 9007199254740991Raw AdCP create_media_buy payload as the buyer submitted it, with buyer webhook credentials (push_notification_config / pushNotificationConfig) removed before it reaches operator-facing responses. Not normalized — the operator UI renders a summary directly from this object.
Lifecycle state. pending until the operator decides; approved once the operator accepts (forwarding upstream happens out-of-band and is reflected by forwardedAt); rejected when the operator declines; revoked for buyer- or system-initiated cancellation after a decision.
pending, approved, rejected, revoked User id of the operator who recorded the decision (BIGINT serialized as string). Null while pending.
When the operator decision was recorded (ISO 8601). Null while pending.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$Operator note attached to the decision. Null while pending.
When forwarding to the underlying sales agent settled (ISO 8601) — stamped both when every source accepted the buy and when the forward was terminalized, because the stamp is also what stops the background worker re-attempting a dead forward. Null means the forward has not been attempted or is still in flight. Read it with the per-source legs to tell a delivered buy from a refused one: a delivered buy carries an upstreamMediaBuyId.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$When the buyer submitted the media buy (ISO 8601).
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$When the row was last modified — submission, decision, or forwarding stamp (ISO 8601).
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$Structural fillability of the buy. Present on pending create entries; null when the buy has already been decided, when it is an update approval, or when the projection could not be computed — never as a way of saying "nothing is wrong".
Show child attributes
Show child attributes
Result of the dispatch this call triggered. deferred means the retry was accepted and is running asynchronously — poll GET /media-buy-approvals/{mediaBuyId} for the settled result. Absent when no dispatch ran.
deferred, all_completed, all_submitted, partial, all_failed, precondition_failed Per-source forwarding legs for this dispatch. Empty while forwardOutcome is deferred.
Show child attributes
Show child attributes