curl --request GET \
--url https://api.interchange.io/api/v2/storefront/demand-inbox/{runId}/exchange \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.interchange.io/api/v2/storefront/demand-inbox/{runId}/exchange"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.interchange.io/api/v2/storefront/demand-inbox/{runId}/exchange', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"exchangeId": "<string>",
"buyer": "<string>",
"commercialIdentity": {
"advertiser": {
"value": "<string>",
"source": "request.brand"
},
"buyingOperator": {
"value": "<string>",
"source": "request.brand"
},
"account": {
"value": "<string>",
"source": "request.brand"
}
},
"provenance": "<string>",
"runPurpose": "live",
"briefText": "<string>",
"briefFacts": {
"channels": [
"<string>"
],
"countries": [
"<string>"
],
"budgetRange": {
"min": 123,
"max": 123,
"currency": "<string>"
},
"promotedOffering": "<string>",
"brandDomain": "<string>"
},
"briefArtifactId": "<string>",
"briefArtifactAvailable": true,
"proposalArtifactId": "<string>",
"passesTruncated": true,
"result": "closed_won",
"commercialLifecycle": "closed_won",
"wonValue": [
{
"amount": 123,
"currency": "<string>"
}
],
"statedBudget": {
"min": 123,
"max": 123,
"currency": "<string>"
},
"ledBy": "agent",
"grade": "A",
"feedback": "<string>",
"receivedAt": "<string>",
"respondedAt": "<string>",
"responseTimeMs": 1,
"grouping": {
"basis": "compose_run",
"passCount": 0,
"multiPass": true,
"note": "<string>"
},
"passes": [
{
"passId": "<string>",
"sequence": 0,
"version": 0,
"kind": "<string>",
"createdAt": "<string>",
"planName": "<string>",
"planBriefAlignment": "<string>",
"planCount": 0,
"captureState": "captured",
"responseKind": "product_offer",
"artifactAvailable": true,
"products": [
{
"productId": "<string>",
"name": "<string>",
"description": "<string>",
"deliveryType": "<string>",
"placements": [
{
"placement": {
"unresolved": false,
"properties": [
{
"publisherDomain": "<string>",
"propertyName": "<string>"
}
],
"adUnit": "<string>",
"omittedPropertyCount": 0
},
"delivery": {
"kind": "full_slot",
"netAvailableImpressions": 4503599627370495,
"windowStart": "<string>",
"windowEnd": "<string>",
"provenance": "seller_available_capacity"
}
}
],
"omittedPlacementCount": 4503599627370495,
"audience": {
"facts": [
{
"statement": "<string>",
"attribution": "<string>",
"sourceRef": "<string>"
}
],
"truncated": true
},
"pricing": {
"model": "<string>",
"amount": 123,
"currency": "<string>",
"kind": "fixed"
},
"allocationPercent": 123,
"allocationValue": {
"amount": 123,
"currency": "<string>"
},
"formats": [
{
"agentUrl": "<string>",
"id": "<string>"
}
],
"snapshot": "<unknown>",
"fedBy": []
}
],
"productsTruncated": true,
"outcome": {
"result": "closed_won",
"wonValue": {
"amount": 123,
"currency": "<string>"
}
},
"origin": "agent",
"fedBy": [],
"pitch": {
"composedAt": "<string>",
"composedVia": "inline",
"claimsDropped": 4503599627370495,
"whatWeHeard": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
],
"thesis": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
],
"roles": [
{
"productId": "<string>",
"role": "<string>",
"claims": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
]
}
],
"outcomeLinkage": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
],
"valueCase": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
],
"honestCounter": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
],
"invitation": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
],
"decline": []
},
"pitchStatus": "absent",
"pitchAbsentReason": null,
"pitchAbsentDetail": {
"catalogue": {
"products": 4503599627370495,
"inventoryBundles": 4503599627370495,
"signals": 4503599627370495,
"pricingFacts": 4503599627370495,
"affordances": 4503599627370495,
"briefRefs": 4503599627370495,
"playbook": true,
"corpus": true
},
"drops": {
"modelClaims": 4503599627370495,
"citationGroundingDropped": 4503599627370495,
"entailmentDropped": 4503599627370495,
"reasons": {
"no_sources": 4503599627370495,
"unknown_source_kind": 4503599627370495,
"unsourced_reference": 4503599627370495,
"corpus_unavailable": 4503599627370495,
"affordance_unavailable": 4503599627370495,
"decapitated_section": 4503599627370495,
"section_not_permitted_for_disposition": 4503599627370495,
"cross_product_reference": 4503599627370495,
"ambiguous_owner": 4503599627370495,
"unknown_product": 4503599627370495,
"duplicate_role": 4503599627370495,
"unlabelled_role": 4503599627370495,
"empty_text": 4503599627370495,
"not_entailed": 4503599627370495,
"brief_only_outside_what_we_heard": 4503599627370495,
"numeric_not_in_sources": 4503599627370495
}
}
},
"droppedClaims": [],
"bidDecision": {
"disposition": "pitch",
"decidedBy": "no_products",
"threshold": 0.5,
"categoryFit": 0.5,
"doctrineVersion": 0,
"doctrineVariant": "house_default",
"fedBy": []
},
"story": {
"storyId": "<string>",
"title": "<string>",
"advertiserName": "<string>",
"vertical": "<string>",
"challenge": "<string>",
"method": "<string>",
"results": [
{
"metric": "<string>",
"attribution": "<string>"
}
],
"provenanceLabel": "<string>"
}
}
],
"adjustable": true,
"adjustabilityReason": "not_live_demand",
"openRevision": {
"id": "<string>",
"exchangeId": "<string>",
"state": "draft",
"overrides": {
"posture": {
"selectedPosture": "direct_fit"
},
"pricing": {
"priceAdjustmentBasisPoints": 45000,
"floorCpm": {
"amount": 1,
"currency": "<string>"
}
},
"rules": {
"requiredBundleIds": [
"<string>"
],
"excludedBundleIds": [
"<string>"
],
"maxProducts": 50
}
},
"composeResult": "ok",
"composeError": {
"code": "<string>",
"message": "<string>"
},
"proposalPreview": "<unknown>",
"proposalPreviewSnapshots": "<unknown>",
"settlementCurrency": "<string>",
"buyerStatedCurrencies": [
"<string>"
],
"composedByUserId": 0,
"composedAt": "<string>",
"approval": {
"gate": "pending",
"decidedByUserId": 0,
"decidedAt": "<string>",
"notes": "<string>"
},
"send": {
"mode": "manual",
"autoApproveReason": "storefront_auto_approve"
},
"sentProposalArtifactId": "<string>",
"delivery": {
"status": "not_delivered",
"reason": "no_delivery_lane"
},
"canApprove": true,
"canAmend": true,
"canSubmit": true,
"canDiscard": true,
"submissionGeneration": 0,
"amendCount": 0
}
}{
"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": {}
}
}{
"data": null,
"error": {
"code": "<string>",
"message": "<string>",
"field": "<string>",
"details": {}
}
}Get a demand exchange (proposal pass)
The full story of one exchange for the calling Seller Account: condensed brief facts read from the persisted brief artifact, ordered passes with product allocation + pricing rows and expand-to-inspect snapshots from the persisted proposal artifacts, per-pass commercial outcome, and an exchange-level result (won if any pass won, else lost if the most recent decided pass lost, else pending). Grouped from persisted linkage only — one compose run and its proposal artifacts, never the content-addressed brief digest — so an exchange reads as a single composition pass until persisted cross-run lineage exists. A run with no captured artifact renders as unavailable, never reconstructed; a metric with no input is null, never 0. Scoped to the caller’s Seller Account — a run outside it returns 404.
curl --request GET \
--url https://api.interchange.io/api/v2/storefront/demand-inbox/{runId}/exchange \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.interchange.io/api/v2/storefront/demand-inbox/{runId}/exchange"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.interchange.io/api/v2/storefront/demand-inbox/{runId}/exchange', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"exchangeId": "<string>",
"buyer": "<string>",
"commercialIdentity": {
"advertiser": {
"value": "<string>",
"source": "request.brand"
},
"buyingOperator": {
"value": "<string>",
"source": "request.brand"
},
"account": {
"value": "<string>",
"source": "request.brand"
}
},
"provenance": "<string>",
"runPurpose": "live",
"briefText": "<string>",
"briefFacts": {
"channels": [
"<string>"
],
"countries": [
"<string>"
],
"budgetRange": {
"min": 123,
"max": 123,
"currency": "<string>"
},
"promotedOffering": "<string>",
"brandDomain": "<string>"
},
"briefArtifactId": "<string>",
"briefArtifactAvailable": true,
"proposalArtifactId": "<string>",
"passesTruncated": true,
"result": "closed_won",
"commercialLifecycle": "closed_won",
"wonValue": [
{
"amount": 123,
"currency": "<string>"
}
],
"statedBudget": {
"min": 123,
"max": 123,
"currency": "<string>"
},
"ledBy": "agent",
"grade": "A",
"feedback": "<string>",
"receivedAt": "<string>",
"respondedAt": "<string>",
"responseTimeMs": 1,
"grouping": {
"basis": "compose_run",
"passCount": 0,
"multiPass": true,
"note": "<string>"
},
"passes": [
{
"passId": "<string>",
"sequence": 0,
"version": 0,
"kind": "<string>",
"createdAt": "<string>",
"planName": "<string>",
"planBriefAlignment": "<string>",
"planCount": 0,
"captureState": "captured",
"responseKind": "product_offer",
"artifactAvailable": true,
"products": [
{
"productId": "<string>",
"name": "<string>",
"description": "<string>",
"deliveryType": "<string>",
"placements": [
{
"placement": {
"unresolved": false,
"properties": [
{
"publisherDomain": "<string>",
"propertyName": "<string>"
}
],
"adUnit": "<string>",
"omittedPropertyCount": 0
},
"delivery": {
"kind": "full_slot",
"netAvailableImpressions": 4503599627370495,
"windowStart": "<string>",
"windowEnd": "<string>",
"provenance": "seller_available_capacity"
}
}
],
"omittedPlacementCount": 4503599627370495,
"audience": {
"facts": [
{
"statement": "<string>",
"attribution": "<string>",
"sourceRef": "<string>"
}
],
"truncated": true
},
"pricing": {
"model": "<string>",
"amount": 123,
"currency": "<string>",
"kind": "fixed"
},
"allocationPercent": 123,
"allocationValue": {
"amount": 123,
"currency": "<string>"
},
"formats": [
{
"agentUrl": "<string>",
"id": "<string>"
}
],
"snapshot": "<unknown>",
"fedBy": []
}
],
"productsTruncated": true,
"outcome": {
"result": "closed_won",
"wonValue": {
"amount": 123,
"currency": "<string>"
}
},
"origin": "agent",
"fedBy": [],
"pitch": {
"composedAt": "<string>",
"composedVia": "inline",
"claimsDropped": 4503599627370495,
"whatWeHeard": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
],
"thesis": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
],
"roles": [
{
"productId": "<string>",
"role": "<string>",
"claims": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
]
}
],
"outcomeLinkage": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
],
"valueCase": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
],
"honestCounter": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
],
"invitation": [
{
"claimRef": "<string>",
"text": "<string>",
"sources": [
{
"kind": "brief",
"ref": "<string>"
}
],
"fedBy": []
}
],
"decline": []
},
"pitchStatus": "absent",
"pitchAbsentReason": null,
"pitchAbsentDetail": {
"catalogue": {
"products": 4503599627370495,
"inventoryBundles": 4503599627370495,
"signals": 4503599627370495,
"pricingFacts": 4503599627370495,
"affordances": 4503599627370495,
"briefRefs": 4503599627370495,
"playbook": true,
"corpus": true
},
"drops": {
"modelClaims": 4503599627370495,
"citationGroundingDropped": 4503599627370495,
"entailmentDropped": 4503599627370495,
"reasons": {
"no_sources": 4503599627370495,
"unknown_source_kind": 4503599627370495,
"unsourced_reference": 4503599627370495,
"corpus_unavailable": 4503599627370495,
"affordance_unavailable": 4503599627370495,
"decapitated_section": 4503599627370495,
"section_not_permitted_for_disposition": 4503599627370495,
"cross_product_reference": 4503599627370495,
"ambiguous_owner": 4503599627370495,
"unknown_product": 4503599627370495,
"duplicate_role": 4503599627370495,
"unlabelled_role": 4503599627370495,
"empty_text": 4503599627370495,
"not_entailed": 4503599627370495,
"brief_only_outside_what_we_heard": 4503599627370495,
"numeric_not_in_sources": 4503599627370495
}
}
},
"droppedClaims": [],
"bidDecision": {
"disposition": "pitch",
"decidedBy": "no_products",
"threshold": 0.5,
"categoryFit": 0.5,
"doctrineVersion": 0,
"doctrineVariant": "house_default",
"fedBy": []
},
"story": {
"storyId": "<string>",
"title": "<string>",
"advertiserName": "<string>",
"vertical": "<string>",
"challenge": "<string>",
"method": "<string>",
"results": [
{
"metric": "<string>",
"attribution": "<string>"
}
],
"provenanceLabel": "<string>"
}
}
],
"adjustable": true,
"adjustabilityReason": "not_live_demand",
"openRevision": {
"id": "<string>",
"exchangeId": "<string>",
"state": "draft",
"overrides": {
"posture": {
"selectedPosture": "direct_fit"
},
"pricing": {
"priceAdjustmentBasisPoints": 45000,
"floorCpm": {
"amount": 1,
"currency": "<string>"
}
},
"rules": {
"requiredBundleIds": [
"<string>"
],
"excludedBundleIds": [
"<string>"
],
"maxProducts": 50
}
},
"composeResult": "ok",
"composeError": {
"code": "<string>",
"message": "<string>"
},
"proposalPreview": "<unknown>",
"proposalPreviewSnapshots": "<unknown>",
"settlementCurrency": "<string>",
"buyerStatedCurrencies": [
"<string>"
],
"composedByUserId": 0,
"composedAt": "<string>",
"approval": {
"gate": "pending",
"decidedByUserId": 0,
"decidedAt": "<string>",
"notes": "<string>"
},
"send": {
"mode": "manual",
"autoApproveReason": "storefront_auto_approve"
},
"sentProposalArtifactId": "<string>",
"delivery": {
"status": "not_delivered",
"reason": "no_delivery_lane"
},
"canApprove": true,
"canAmend": true,
"canSubmit": true,
"canDiscard": true,
"submissionGeneration": 0,
"amendCount": 0
}
}{
"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": {}
}
}{
"data": null,
"error": {
"code": "<string>",
"message": "<string>",
"field": "<string>",
"details": {}
}
}Authorizations
API key or access token
Path Parameters
Surrogate id of the chef compose run that anchors this exchange (the demand-inbox ledger row id).
0 < x <= 900719925474099142
Response
Get a demand exchange (proposal pass)
The full story of one brief → proposal → result exchange: brief facts, ordered passes with product allocation + pricing rows, per-pass outcome, and an exchange-level result. Every number is traceable to a persisted artifact or outcome record; missing inputs render unavailable, never 0.
The compose-run id anchoring this exchange.
Advertiser = BrandRef × Operator (AI-5080), projected from the persisted brief request first and the compose-run identity snapshot only as a historical fallback. CRM evidence and seller-native mappings are deliberately not joined into this identity.
Show child attributes
Show child attributes
How this brief reached the ledger: 'live' = an AdCP get_products call from a buyer agent, 'uploaded' = a seller-uploaded RFP/brief confirmed in chat (AI-4728). Reflects this run's own intake origin (AI-5025), falling back to the linked brief artifact's source column only for historical runs recorded before that origin was captured. Null when neither is available. An uploaded exchange is never presented as live buyer demand.
The compose run's own run_purpose. null means the run predates classification (an absent historical value, treated as real demand); a persisted value outside this build's known set surfaces as 'unknown', which consumers must treat exactly like a synthetic purpose — never as a live buyer. Together with provenance this is how the pass classifies the exchange into a matrix-ruling cell: any purpose other than 'live'/'unclassified' (including 'unknown') is never real buyer demand, regardless of what provenance says.
live, setup_test, simulation, probe, evaluation, unclassified, unknown Condensed brief facts read from the persisted brief artifact request (never reconstructed). Any field the buyer did not send is null.
Show child attributes
Show child attributes
False when no brief artifact was captured (historical run). Readers must say "brief unavailable" rather than reconstruct it.
The most recent seller-response artifact id (historical storage-table name), from the full persisted pass list. Presence alone does not prove a Proposal; use responseKind on the matching pass.
True when the run had more persisted proposal artifacts than the pass cap; the widget discloses the cap rather than silently dropping older passes.
Exchange-level commercial result. Derivation rule: won if ANY pass is won; else lost if the most recent decided pass is lost; else pending. With one run per exchange today this equals the run outcome.
closed_won, closed_lost, pending The most specific commercial lifecycle supported by the persisted response and attributed outcome. This supplements result so an undecided exchange is never presented as an ambiguous Pending state.
closed_won, closed_lost, awaiting_advertiser_decision, awaiting_seller_approval, forwarding_failed, no_offer_returned, response_not_recorded, response_unavailable Money won across the exchange, one entry per currency (both-or-nothing amount+currency per the AI-4726 money model; never summed cross-currency). Null when nothing won recorded a priced outcome.
Show child attributes
Show child attributes
The buyer's stated budget range. Surfaced at the exchange level so a lost exchange still shows the demand it represented (the AI-4726 lost-demand visibility).
Show child attributes
Show child attributes
agent, human A, B, C, D, F x >= 0Show child attributes
Show child attributes
Show child attributes
Show child attributes
Whether Adjust is available on this exchange right now, from the shared eligibility rule the compose mutation re-checks (AI-5571). False for anything but classified live demand with a retained brief, active operating instructions, and lifetime adjustments remaining.
Null when adjustable is true. Otherwise the server's own named reason — never a bare not-found — so the pass renders Adjust disabled with the reason instead of a button that fails when pressed.
not_live_demand, brief_not_retained, no_operating_instructions, adjustment_limit_reached, open_revision_exists The exchange's open draft or awaiting-approval revision, surfaced separately from the pass list — a seller-composed revision is never mistaken for a captured pass until it is actually sent.
Show child attributes
Show child attributes