publ betaReference (MCP guide)
Open publ console

publ Reference

Migration map.

promotion_handoff

This implementation is a dependency of the documentation branch.

Return an exact human console destination for a campaign, benefit or product change. The tool observes context and targets using GET; it never performs the requested offer or financial action.

Access and input

Requires OWNER or DELEGATEE with MANAGE_PROMOTION. Hosted source scope is the exact selected channel, not account scope. channelCode and opaque pcid/pbid follow the reader's identity rules. Strict inputs do not accept arbitrary URLs, financial payloads, requestId, expectedRevision or dryRun.

Input Contract
channelCode Required selected channel code.
action Required discriminated object.
action.kind One of the eight destinations below.
action.pcid Required except for create-campaign.
action.pbid Required for benefit-edit, benefit-activation, products and product-add only.
{"channelCode":"selected-channel-code","action":{"kind":"create-campaign"}}
{"channelCode":"selected-channel-code","action":{"kind":"campaign-edit","pcid":"observed-campaign"}}
{"channelCode":"selected-channel-code","action":{"kind":"product-add","pcid":"observed-campaign","pbid":"observed-benefit"}}

Creation policy

create-campaign reads an unfiltered page 1 with limit 15 and the selected channel's current plan. It uses pagination.totalEntries, not the current displayed/filtered row count. NORMAL_ESSENTIAL permits creation only when the existing count is zero. NORMAL_BUSINESS, NORMAL_FROM_ENTERPRISE, NORMAL_PRO, ENTERPRISE_TRIAL, ENTERPRISE_ENTERPRISE, PARTNER_TRIAL, PARTNER_PARTNER and INTERNAL_INTERNAL are eligible under the shared higher-plan rule. FREE_TRIAL, NORMAL_STARTER, NORMAL_STARTER_2023_04 and NORMAL_BASIC are denied. Unknown or missing plans remain unverified and cannot create.

creationPolicy contains currentPlan, canCreate, policyVerified, existingCampaignCount, sourceRule, sourceCountObserved:true and reserved:false. sourceRule describes Essential-or-higher with one Essential campaign slot. Using the unfiltered total is a conservative interpretation of the source button's displayed-list check. A count/plan observation is not a slot reservation, subscription change or proof an eligible creation will succeed.

Blocked or unknown creation policy returns PROMOTION_PLAN_ACTION and the exact channel-plan destination. An eligible creation or verified existing target returns PROMOTION_HUMAN_ACTION. No plan is purchased or upgraded.

Destinations and result

All routes below are relative to /channels/{channelCode}/promotion-campaign and encode dynamic identities. Existing campaign/benefit targets receive repeated parent/content, selected-channel, operator and credential checks before navigation.

action.kind Required identity Console suffix
create-campaign None /campaigns/create; blocked policy uses channel-plan instead.
campaign-edit pcid /campaigns/{pcid}/profile/edit
campaign-activation pcid /campaigns/{pcid}/profile
add-benefit pcid /campaigns/{pcid}/benefits/add
benefit-edit pcid, pbid /campaigns/{pcid}/benefits/{pbid}/edit
benefit-activation pcid, pbid /campaigns/{pcid}/benefits/{pbid}
products pcid, pbid /campaigns/{pcid}/benefits/{pbid}/target-product
product-add pcid, pbid /campaigns/{pcid}/benefits/{pbid}/target-product/add

The result is always action_required on a valid handoff, with writesPerformed:false, action, requiredAction.kind open_console and verification {confirmed:false,targetObserved:true,financialActionPerformed:false}. Creation alone includes creationPolicy. Demo omits live consoleUrl. An observed target or returned link is not completed work. When choosing the human console path, product price/disconnection dialogs are opened by the person from the products screen; no modal URL or generic console-home fallback is invented.

Errors use the reader's identity, pagination, stability and permission boundaries. A missing or foreign target does not fall back to a broader route. No task journal is created; task status/resume and mutation retry do not apply. This handoff performs none of the creation, activation, schedule, discount, grant, product attachment or pricing actions; use the separate implemented writers below where their exact scope applies. The separate notification writer supports only the two documented coupon push settings.

Current existing-campaign editing

The earlier mandatory handoff boundary for campaign metadata/schedule/activation is superseded. promotions_get view profile now returns campaignRevision for promotion_campaign_apply, which saves the selected existing campaign profile or activation while preserving benefits and product prices. Existing benefit profile/activation uses promotion_benefit_apply. A handoff remains available for people. promotion_campaign_create supports a new active campaign with one initial ORDER_DISCOUNT benefit. promotion_benefit_create separately adds one ORDER_DISCOUNT or DISCOUNT to an existing campaign with Business-or-higher. Money movement stays human-operated.

For an existing connected relationship, use promotion_benefit_apply product-disconnect with the exact products-page revision and connected row ID. This removes only the relationship, verifies complete bounded absence and preserves the underlying product. Eligible new connections now use the bounded product-connect flow below; restorationSupported remains false, with no automatic relinking or rollback. A handoff is still GET-only/action_required and never claims the change happened. Financial execution remains a human-console action.

To connect eligible existing products to an existing DISCOUNT benefit, read product-options and use product-connect with connectionRevision and explicit values. The active-campaign prerequisite and five supported families apply; category model ambiguity, fixed-price CP conversion and deleted-product reconnection remain gaps. This creates relationships only. Additional DISCOUNT creation uses promotion_benefit_create with its own options/creation revisions and Business-or-higher gate, permitting inactive parents. Neither flow creates underlying products, restores previous identities or executes finance.

Inputs

Field Required here Contract
action Yes one of: create-campaign, campaign-edit, campaign-activation, add-benefit, benefit-edit, benefit-activation, products, product-add (by kind)
action.pcid Yes When action.kind is campaign-edit or campaign-activation or add-benefit: string; pattern ^[A-Za-z0-9_-]{1,128}$
action.pcid Yes When action.kind is benefit-edit or benefit-activation or products or product-add: string; pattern ^[A-Za-z0-9_-]{1,128}$
action.pbid Yes When action.kind is benefit-edit or benefit-activation or products or product-add: string; pattern ^[A-Za-z0-9_-]{1,128}$