LLM-readable planning output
Key-value forecast with order context as JSON
Resolve the GAM order, resolve custom targeting IDs, run a constrained forecast, then return one stable JSON object that another LLM can read without guessing.
"Codex, prepare an LLM-readable JSON forecast for order OR-2026-SUMMER. Resolve the order, resolve key-values audience=sports and hb_pb=20, forecast Homepage/Sports ad units from 2026-07-01 to 2026-07-31 for 500000 impressions with 300x250 and 728x90, split availability by format, then return only the decision JSON."
A normalized forecastDecision JSON object with order metadata, resolved key/value IDs, forecast numbers, format split, risk level and the next safe action.
Agent workflow
- 01
Find the order with list_orders, then call get_order so the JSON carries orderId, status, advertiserId and traffickerId.
- 02
Resolve every key-value with search_custom_targeting and get_custom_targeting_values; never pass only labels such as audience=sports to the forecast.
- 03
Run get_standalone_forecast for a draft need, get_delivery_forecast_by_line_item for an existing line item, or get_prospective_delivery_forecast when several planned line items must be simulated together.
- 04
Add breakdownTargets by creative format so the LLM can compare 300x250 and 728x90 instead of reading one blended capacity number.
- 05
Map the raw forecast into a strict forecastDecision object before asking the LLM for a recommendation.
MCP functions
Parent MCP call shown with the reporting action.
| Function | Cost | Purpose |
|---|---|---|
reporting(action="list_orders") | 0 cr | Find the GAM order by name. |
reporting(action="get_order") | 0 cr | Fetch full order metadata. |
reporting(action="search_custom_targeting") | 0 cr | Resolve key names to key IDs. |
reporting(action="get_custom_targeting_values") | 0 cr | Resolve allowed value IDs for each key. |
reporting(action="get_standalone_forecast") | 0 cr | Forecast the resolved targeting before booking. |
reporting(action="get_delivery_forecast_by_line_item") | 0 cr | Compare with an existing line item forecast. |
reporting(action="get_prospective_delivery_forecast") | 0 cr | Simulate several planned line items together. |
JSON payload
{
"objective": "forecast_key_values_order_json",
"prerequisiteCalls": [
{
"tool": "orders",
"arguments": {
"action": "list",
"params": {
"q": "OR-2026-SUMMER",
"limit": 5
}
}
},
{
"tool": "orders",
"arguments": {
"action": "get",
"params": {
"orderId": "9482"
}
}
},
{
"tool": "targeting",
"arguments": {
"action": "search_custom_targeting",
"params": {
"q": "audience",
"limit": 10
}
}
},
{
"tool": "targeting",
"arguments": {
"action": "get_custom_targeting_values",
"params": {
"keyId": "1871",
"limit": 200
}
}
}
],
"forecastCall": {
"tool": "reporting",
"arguments": {
"action": "get_standalone_forecast",
"params": {
"adUnitIds": [
"1234567",
"1234568"
],
"startDate": "2026-07-01T00:00:00",
"endDate": "2026-07-31T23:59:59",
"primaryGoalUnits": 500000,
"lineItemType": "STANDARD",
"priority": 8,
"keyValues": [
{
"keyId": 1871,
"valueIds": [
9912
]
},
{
"keyId": 2450,
"valueIds": [
3301
]
}
],
"geoTargeting": [
"2250"
],
"creativeSizes": [
{
"width": 300,
"height": 250
},
{
"width": 728,
"height": 90
}
],
"breakdownTargets": [
{
"name": "format_300x250",
"creative": {
"width": 300,
"height": 250
}
},
{
"name": "format_728x90",
"creative": {
"width": 728,
"height": 90
}
}
],
"frequencyCaps": [
{
"maxImpressions": 3,
"numTimeUnits": 1,
"timeUnit": "DAY"
}
],
"includeTargetingCriteriaBreakdown": true
}
}
},
"llmJsonContract": {
"forecastDecision": {
"order": [
"id",
"name",
"status",
"advertiserId",
"traffickerId"
],
"targeting": [
"adUnitIds",
"keyValues",
"geoTargeting",
"creativeSizes"
],
"forecast": [
"availableUnits",
"matchedUnits",
"deliveredUnits",
"utilizationPercent",
"formatSplit",
"contendingLineItems"
],
"decision": [
"riskLevel",
"status",
"relaxFirst",
"nextAction"
]
}
}
}Representative output
- {"order":{"id":"9482","name":"OR-2026-SUMMER","status":"DRAFT","advertiserId":"7712","traffickerId":"4431"},"targeting":{"adUnitIds":["1234567","1234568"],"keyValues":[{"keyId":1871,"keyName":"audience","valueIds":[9912],"valueNames":["sports"]},{"keyId":2450,"keyName":"hb_pb","valueIds":[3301],"valueNames":["20"]}]}}
- {"forecast":{"availableUnits":612400,"matchedUnits":544900,"deliveredUnits":184200,"utilizationPercent":81.6,"formatSplit":[{"format":"300x250","availableUnits":388100,"matchedUnits":352900,"riskLevel":"LOW"},{"format":"728x90","availableUnits":224300,"matchedUnits":192000,"riskLevel":"REVIEW"}],"contendingLineItems":[{"lineItemId":"90031","name":"Summer Roadblock","priority":6}]}}
- {"decision":{"riskLevel":"LOW","status":"safe_to_review","relaxFirst":null,"nextAction":"regenerate_before_booking"},"llmSummary":"Order context is resolved, targeting IDs are explicit, forecast is read-only."}
Dimensions and metrics
| Name | Source | Description |
|---|---|---|
| ORDER_ID | GAM | Order identifier |
| ORDER_NAME | GAM | Order name |
| AD_UNIT_ID | GAM | Target inventory IDs |
| CREATIVE_TARGET_AD_UNIT_SIZE | GAM | Format split |
| KEY_VALUES_ID | GAM | Resolved key-value IDs |
| KEY_VALUES_NAME | GAM | Human-readable key-value labels |
| Name | Source | Description |
|---|---|---|
availableUnits | Derived | Forecast availability |
matchedUnits | Derived | Units matching targeting |
deliveredUnits | Derived | Already delivered units in context |
utilizationPercent | Derived | Inventory pressure indicator |
formatSplit | Derived | Availability split by creative format |
riskLevel | Derived | Decision risk label |
Limits
- Future availability is not a HISTORICAL REST report; do not use run_custom_report for this question.
- Order context is descriptive: it does not reserve inventory and does not mutate the order.
- Key-values must be stored as keyId/valueIds in the JSON so another agent can replay the same forecast.
- Forecasts should be regenerated near booking time, especially after priority, sizes, caps or targeting change.
Use the editorial guide for the audience framing, then come back here for exact MCP actions, fields and payloads.
