Overview
One plan of yours as the person sees it and as you sign it: each line with the creator's name (its X handle and profile link once the plan's order is paid), format, date and all-in price, the totals (creators, measured reach, cost per 1,000 views, budget left), every payment option with when it clears, the current brand terms, and the terms_fingerprint approve_plan needs. It also says whether this key's mandate lets it sign the plan now, and if not which limit and by how much. A key that writes gets the quote at each creator's current price. over_budget names how far the plan is over its campaign's budget (budget_cents, total_cents, over_by_cents), at current prices when a creator's price rose past it; null within the budget.
- Server
https://app.distribution.tech/api/mcp- Scope
campaigns:read- Changes data
- No, a read
- REST endpoint
- GET /plans/{id}/quote
Arguments
| Name | Type | Required | Description |
|---|---|---|---|
plan_id | string (uuid) | Yes | A plan id, from create_campaign or campaign_status. |
Call with curl
The server speaks streamable HTTP, so one JSON-RPC tools/call request runs the tool. Set DISTRIBUTION_API_KEY to a key from Developers with the campaigns:read scope; the arguments shown are the required ones.
curl -X POST "https://app.distribution.tech/api/mcp" \
-H "Authorization: Bearer $DISTRIBUTION_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "plan_quote",
"arguments": {
"plan_id": "<uuid>"
}
}
}'Result
The answer's structuredContent follows the tool's output schema (the same JSON is in its text content). It has these fields:
| Name | Type | Required | Description |
|---|---|---|---|
plan_id | string (uuid) | No | |
campaign_id | string (uuid) | No | |
version | integer | No | |
status | one of "awaiting_approval", "approved" | No | |
currency | string | No | |
launch_window_start | string (date) | No | |
launch_window_end | string (date) | No | |
terms_fingerprint | string | No | Send exactly this to approve. It changes when a line, a price or the dates change. |
total_cents | integer | No | |
totals | object | No | creators, total_cents, views_low, views_high, unmeasured, cpm_low_cents, cpm_high_cents, tiers, budget_cents, remaining_cents. |
lines | array of object | No | |
payment_options | array of object | No | |
agent_payment | one of "checkout", "team_invoice" | No | |
brand_terms | object | No | |
mandate | object or null | No | |
policy | object | No | allowed: whether this key's mandate lets it sign now; refusal: the reason and numbers when not (over_budget when the plan is over the campaign's budget, which no mandate can approve: remove a creator or have the brand raise the budget). |
blocked_lines | array of string (uuid) | No | |
over_budget | object or null | No | The plan over its campaign's budget: budget_cents, total_cents and over_by_cents, at current prices when a creator's price rose past the budget (the plan then keeps its earlier prices, so total_cents alone reads as within it). Null within the budget, with no budget, or once signed. Approval refuses it until a creator is removed or the budget is raised. |
order | object or null | No | |
valid_while | "terms_fingerprint_unchanged" | No |
{
"plan_id": "<uuid>",
"campaign_id": "<uuid>",
"version": 0,
"status": "awaiting_approval",
"currency": "<string>",
"launch_window_start": "<date>",
"launch_window_end": "<date>",
"terms_fingerprint": "<string>",
"total_cents": 0,
"totals": {},
"lines": [
{
"id": "<uuid>",
"creator": {
"id": "<uuid>",
"name": "<string>",
"handle": "<string>",
"profile_url": "<string>",
"avatar_url": "<uri>",
"followers": 0
},
"creator_id": "<uuid>",
"unit_id": "<uuid>",
"stage_id": "planned",
"stage": "<string>",
"channel": "<string>",
"channel_label": "<string>",
"format": "<string>",
"deliverable": "<string>",
"scheduled_date": "<date>",
"price_cents": 0,
"vetting": "<string>",
"reason": "<string>",
"expected_views_low": 0,
"expected_views_high": 0,
"on_sale": false
}
],
"payment_options": [
{
"rail": "checkout",
"label": "<string>",
"clears": "<string>"
}
],
"agent_payment": "checkout",
"brand_terms": {
"current_version": "<string>",
"current_number": 0,
"url": "<string>",
"accepted_for_this_key": "<string>",
"accepted_number_for_this_key": 0
},
"mandate": {
"key_id": "<uuid>",
"version": 0,
"max_plan_cents": 0,
"monthly_cap_cents": 0,
"channels": [
"<string>"
],
"may_approve": false,
"may_exceed_budget": false,
"expires_at": "<date-time>",
"updated_at": "<date-time>",
"spent_this_month_cents": 0,
"terms_version": "<string>",
"terms_accepted_at": "<date-time>",
"terms_accepted_email": "<string>"
},
"policy": {
"allowed": false,
"refusal": {}
},
"blocked_lines": [
"<uuid>"
],
"over_budget": {
"budget_cents": 0,
"total_cents": 0,
"over_by_cents": 0
},
"order": {},
"valid_while": "terms_fingerprint_unchanged"
}Other tools
inventory: Network coverageresolve_audience: Resolve an audiencecampaign_status: Campaign statusevidence: Proof of deliveryresults: Resultsbrain_get: Company contextcreators_search: Find creatorscreator_get: One creatorcreator_ask_price: Ask for a pricecreate_campaign: Start a campaignplan_add_creator: Add a creatorplan_remove_creator: Remove a creatorplan_move_dates: Move a plan's datesplan_swap_creator: Swap a creatorset_creator_guidelines: Set the creator guidelinesapprove_plan: Approve and get the pay linkarchive_campaign: Archive a campaignrename_campaign: Rename a campaigndelete_campaign: Delete a draft campaignfeedback_send: Send feedbackfeedback_list: Your feedback
Get access
Keys are created in Developers once your brand is approved. Connect an agent to ask for access, then read the agent guide for the full flow.