publ betaReference (MCP guide)
Open publ console

publ Reference

Migration map.

marketing_banner_apply

See the current correction and older-server guidance before preparing new inputs; keep existing task inputs unchanged during recovery.

Create a default banner, change visibility, or compose content/image/visibility changes through one tool. The selected object is globalBanner; the other widget and all unrelated custom settings must be preserved.

Access and preparation

Requires OWNER or DELEGATEE with MANAGE_MARKETING_TOOLS for the selected channel. An unrelated permission or CREATOR role is insufficient. The source-defined hosted selected-channel resource admits this tool only for its exact channelCode; the account resource excludes it.

Read marketing_banner_get first and retain its exact revision. New plans independently reread the full custom record and plan, then verify channel/context continuity. The revision includes unrelated settings, timestamps and plan; a change returns MARKETING_CONFLICT before dispatch. Later plan changes return MARKETING_PLAN_CHANGED and pause remaining effects.

The host configures CHANNEL_ENV. Replacement images additionally require a resource gateway, upload bucket and region, including for dry runs. No DNS/recache service is used. A no-op skips mutation-service validation but still performs preparation reads. Service URLs and credentials are not inputs.

Inputs and actions

The outer object, settings, images and each image object are strict. Action-specific combinations are runtime refinements beyond the exported flat object schema.

Field Required here Contract
action Yes create, visibility, configure; create: source defaults only if absent; visibility: change visible only; configure: merge settings/images with source plan eligibility.
visible No boolean
settings No object
settings.title No string; max length 30; Empty or 2–30 UTF-16 code units, matching the source editor. Emoji may occupy two units. Omit to preserve the saved value.
settings.description No string; max length 40; Empty or 2–40 UTF-16 code units, matching the source editor. Emoji may occupy two units. Omit to preserve the saved value.
settings.title_color No string; min length 1; max length 128
settings.description_color No string; min length 1; max length 128
settings.bg_color No string; min length 1; max length 128
settings.conversion_link_url No string; max length 4096
settings.conversion_link_type No WEB_LINK, INTERNAL_LINK
settings.design_template_code No GLOBAL_BANNER_TYPE_A, GLOBAL_BANNER_TYPE_B, GLOBAL_BANNER_TYPE_C
images No object
images.desktop_bg_image_src No one of: local-file, more-parts, complete, cancel (by kind) or null
images.desktop_bg_image_src.filename Yes When images.desktop_bg_image_src.kind is local-file: string; min length 1; max length 240; pattern ^[^/\\:\x00-\x1f\x7f]+$; The name of the file on this computer, with its extension.
images.desktop_bg_image_src.byteLength Yes When images.desktop_bg_image_src.kind is local-file: integer; greater than 0; The exact file size in bytes (for example from wc -c < FILE or stat).
images.desktop_bg_image_src.sha256 No When images.desktop_bg_image_src.kind is local-file: string; pattern ^[0-9a-f]{64}$
images.desktop_bg_image_src.uploadId Yes When images.desktop_bg_image_src.kind is more-parts: string; pattern ^upl_[A-Za-z0-9_-]{22}$
images.desktop_bg_image_src.fromPart Yes When images.desktop_bg_image_src.kind is more-parts: integer; minimum 1; maximum 10000
images.desktop_bg_image_src.uploadId Yes When images.desktop_bg_image_src.kind is complete: string; pattern ^upl_[A-Za-z0-9_-]{22}$
images.desktop_bg_image_src.parts Yes When images.desktop_bg_image_src.kind is complete: array; min items 1; max items 10000
images.desktop_bg_image_src.parts[].partNumber Yes When images.desktop_bg_image_src.kind is complete: integer; minimum 1; maximum 10000
images.desktop_bg_image_src.parts[].etag Yes When images.desktop_bg_image_src.kind is complete: string; min length 1; max length 200
images.desktop_bg_image_src.measured No When images.desktop_bg_image_src.kind is complete: object; What the video measures on this computer, read with measureCommand.
images.desktop_bg_image_src.measured.durationSeconds Yes When images.desktop_bg_image_src.kind is complete: number; maximum 1000000; greater than 0; Video duration in seconds (ffprobe format.duration).
images.desktop_bg_image_src.measured.frameRate Yes When images.desktop_bg_image_src.kind is complete: number; maximum 1000; greater than 0; Frames per second (ffprobe avg_frame_rate, for example 30000/1001 = 29.97).
images.desktop_bg_image_src.measured.width Yes When images.desktop_bg_image_src.kind is complete: integer; maximum 100000; greater than 0
images.desktop_bg_image_src.measured.height Yes When images.desktop_bg_image_src.kind is complete: integer; maximum 100000; greater than 0
images.desktop_bg_image_src.measured.frameRateMode No When images.desktop_bg_image_src.kind is complete: CFR, VFR
images.desktop_bg_image_src.measured.minFrameRate No When images.desktop_bg_image_src.kind is complete: number; maximum 1000; greater than 0
images.desktop_bg_image_src.measured.maxFrameRate No When images.desktop_bg_image_src.kind is complete: number; maximum 1000; greater than 0
images.desktop_bg_image_src.uploadId Yes When images.desktop_bg_image_src.kind is cancel: string; pattern ^upl_[A-Za-z0-9_-]{22}$
images.mobile_bg_image_src No one of: local-file, more-parts, complete, cancel (by kind) or null
images.mobile_bg_image_src.filename Yes When images.mobile_bg_image_src.kind is local-file: string; min length 1; max length 240; pattern ^[^/\\:\x00-\x1f\x7f]+$; The name of the file on this computer, with its extension.
images.mobile_bg_image_src.byteLength Yes When images.mobile_bg_image_src.kind is local-file: integer; greater than 0; The exact file size in bytes (for example from wc -c < FILE or stat).
images.mobile_bg_image_src.sha256 No When images.mobile_bg_image_src.kind is local-file: string; pattern ^[0-9a-f]{64}$
images.mobile_bg_image_src.uploadId Yes When images.mobile_bg_image_src.kind is more-parts: string; pattern ^upl_[A-Za-z0-9_-]{22}$
images.mobile_bg_image_src.fromPart Yes When images.mobile_bg_image_src.kind is more-parts: integer; minimum 1; maximum 10000
images.mobile_bg_image_src.uploadId Yes When images.mobile_bg_image_src.kind is complete: string; pattern ^upl_[A-Za-z0-9_-]{22}$
images.mobile_bg_image_src.parts Yes When images.mobile_bg_image_src.kind is complete: array; min items 1; max items 10000
images.mobile_bg_image_src.parts[].partNumber Yes When images.mobile_bg_image_src.kind is complete: integer; minimum 1; maximum 10000
images.mobile_bg_image_src.parts[].etag Yes When images.mobile_bg_image_src.kind is complete: string; min length 1; max length 200
images.mobile_bg_image_src.measured No When images.mobile_bg_image_src.kind is complete: object; What the video measures on this computer, read with measureCommand.
images.mobile_bg_image_src.measured.durationSeconds Yes When images.mobile_bg_image_src.kind is complete: number; maximum 1000000; greater than 0; Video duration in seconds (ffprobe format.duration).
images.mobile_bg_image_src.measured.frameRate Yes When images.mobile_bg_image_src.kind is complete: number; maximum 1000; greater than 0; Frames per second (ffprobe avg_frame_rate, for example 30000/1001 = 29.97).
images.mobile_bg_image_src.measured.width Yes When images.mobile_bg_image_src.kind is complete: integer; maximum 100000; greater than 0
images.mobile_bg_image_src.measured.height Yes When images.mobile_bg_image_src.kind is complete: integer; maximum 100000; greater than 0
images.mobile_bg_image_src.measured.frameRateMode No When images.mobile_bg_image_src.kind is complete: CFR, VFR
images.mobile_bg_image_src.measured.minFrameRate No When images.mobile_bg_image_src.kind is complete: number; maximum 1000; greater than 0
images.mobile_bg_image_src.measured.maxFrameRate No When images.mobile_bg_image_src.kind is complete: number; maximum 1000; greater than 0
images.mobile_bg_image_src.uploadId Yes When images.mobile_bg_image_src.kind is cancel: string; pattern ^upl_[A-Za-z0-9_-]{22}$
confirmToken No string; pattern ^ct[a-f\d]{32}$; The confirmToken from this tool's preview result. Omit it to preview; repeat the same input with it to execute.
irreversibleConfirmed No true; true only after the person confirmed again, when the preview has requiresReconfirmation: the action cannot be undone.

create accepts no visible/settings/images. It writes source defaults only when this widget is absent; an existing widget is a no-op. Defaults start NOT_ACTIVATED. visibility requires an existing widget and visible; settings/images are forbidden. It changes only is_activated while retaining the complete existing content.

configure merges supplied settings/images and optional visible into one final nested save. It requires at least one supplied setting, image slot or visible, checked by the workflow after schema parsing. Missing widgets start from source defaults. Even a configure containing only visible or unchanged values requires a recognized eligible editor plan. Use visibility for the separate visibility action. Denied or unknown plans return action_required / MARKETING_EDIT_PLAN_REQUIRED with the exact screen's human-console guidance and no writes. No plan upgrade or payment occurs. See the complete eligibility list.

Settings

Field Contract
settings.title Empty or 2–30 characters.
settings.description Empty or 2–40 characters.
settings.title_color Nonempty string, 1–128 characters, no ASCII control or DEL; not a complete CSS color validator.
settings.description_color Same color constraint.
settings.bg_color Same color constraint.
settings.conversion_link_url Empty or a normalized HTTP(S) destination satisfying the source pattern; rules below.
settings.conversion_link_type WEB_LINK or INTERNAL_LINK.
settings.design_template_code GLOBAL_BANNER_TYPE_A, GLOBAL_BANNER_TYPE_B or GLOBAL_BANNER_TYPE_C.

Creation defaults are title TITLE, description DESCRIPTION, title_color and description_color #FFFFFF, bg_color #000000, empty desktop/mobile images, https://publ.co with WEB_LINK, and GLOBAL_BANNER_TYPE_B. They are creation values, never fallbacks for malformed reads. There is no per-slot visibility or widget deletion action.

Text is not trimmed; empty is allowed where listed, and a single character is rejected. Supplied links are limited to 4,096 characters before removing all whitespace and adding https:// when no HTTP(S) prefix exists. Nonempty results require HTTP(S), a hostname, no embedded credentials and the source domain-pattern match. This is validation/normalization, not URL fetching or destination availability verification. WEB_LINK and INTERNAL_LINK retain the source's new-tab/current-tab choice; INTERNAL_LINK does not accept a separate page-ID field.

Images

Field Contract
images.desktop_bg_image_src Omit to preserve; null removes the reference; otherwise an original PNG/JPEG object.
images.desktop_bg_image_src.filename Basename, 1–240 characters, PNG/JPG/JPEG extension; no path, URL, colon or control characters.
images.desktop_bg_image_src.base64 Canonical original-file base64, 4–6,990,508 characters; no data URL or whitespace.
images.mobile_bg_image_src Omit to preserve; null removes the reference; otherwise an original PNG/JPEG object.
images.mobile_bg_image_src.filename Basename, 1–240 characters, PNG/JPG/JPEG extension; no path, URL, colon or control characters.
images.mobile_bg_image_src.base64 Canonical original-file base64, 4–6,990,508 characters; no data URL or whitespace.

All replacement files together may contain at most 5 MiB of original bytes. This aggregate cap is a bridge policy for its 8 MiB request envelope, not a source-widget file-size rule. Extension matching is case-insensitive at runtime but the exported regex omits the flag; use lowercase filenames for both. Parsed bytes must match PNG/JPEG structure and extension. The bridge does not resize or render them. null stores an empty image reference and sends no upload; arbitrary replacement image URLs are not accepted.

Do not retry a pending image with a new request ID.

Input examples

These illustrate dry-run inputs, not observed service results. Replace the channel/revision and choose the user's intended content.

{
  "channelCode": "selected-channel-code",
  "requestId": "banner-create-plan-001",
  "expectedRevision": "0000000000000000000000000000000000000000000000000000000000000000",
  "action": "create",
  "dryRun": true
}
{
  "channelCode": "selected-channel-code",
  "requestId": "banner-visibility-plan-001",
  "expectedRevision": "0000000000000000000000000000000000000000000000000000000000000000",
  "action": "visibility",
  "dryRun": true,
  "visible": false
}
{
  "channelCode": "selected-channel-code",
  "requestId": "banner-configure-plan-001",
  "expectedRevision": "0000000000000000000000000000000000000000000000000000000000000000",
  "action": "configure",
  "dryRun": true,
  "settings": {
    "title": "Welcome",
    "description": "Latest news"
  }
}
{
  "channelCode": "selected-channel-code",
  "requestId": "banner-image-plan-001",
  "expectedRevision": "0000000000000000000000000000000000000000000000000000000000000000",
  "action": "configure",
  "dryRun": true,
  "images": {
    "desktop_bg_image_src": {
      "filename": "banner.png",
      "base64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+aDWQAAAAASUVORK5CYII="
    }
  }
}

Effects and results

A new dry run returns MARKETING_WIDGET_PLAN, noop, normalized changes and plannedStages, with no task creation or business writes. Image bytes are replaced with metadata in the planned changes. With an existing matching task, dryRun returns historical saved progress as a plan rather than a fresh business preview.

A real no-op writes a completed journal without business requests. For a change, the workflow can initialize a missing custom record with a bodyless HTTP200 POST to /seller/api/v1/channel-management/custom, retain its observed full baseline, issue/upload each replacement image, then PUT /seller/api/v1/channel-management/custom/experimentals with one nested globalBanner object. That object merges requested values with preserved fields; it is not a replacement of the whole experimentals object. The save expects HTTP200 without a response-body contract. There is no recache step.

The final readback must preserve every unrelated business setting, the other widget, unknown nested JSON, record ID, channel ID and insertedAt. updatedAt may change during the save. Only top-level experimentals.id/exp_id are excluded. The workflow checkpoints before each effect, but does not use a server-side compare-and-swap or transaction. Failed uploads/saves can leave initialized records or orphaned objects; no rollback or automatic deletion occurs.

MARKETING_WIDGET_COMPLETE includes widget, revision, phase done, historical, initializationAcknowledged, settingsSaveAcknowledged and uploads. Fresh completion confirms stored readback only. A no-op has no save acknowledgement; readback-only reconciliation can also complete without a save acknowledgement or proven causality. writesPerformed is false for a no-op or untouched prepared phase, true when an initialization/save or uploaded-object receipt exists, and otherwise null.

MARKETING_WIDGET_PENDING retains phase, uploads, lastResult and inspect_task guidance. journalPersistence.saved:false means the error checkpoint was not saved. Authentication/context errors can suppress channel/navigation metadata. Image receipts contain generated storage coordinates and checksums, not raw bytes or temporary credentials.

Task recovery

Use taskType marketing-widget and the original taskId with status or resume. The task binds widget kind, channel/context, original revision/plan, normalized input fingerprint, record snapshots and image metadata. The same requestId cannot switch between banner and popup or change the input. Unknown or inconsistent journals fail validation; do not edit or rename them to bypass it.

Phase Recovery behavior
prepared Recheck the original snapshot/plan, then start untouched work.
init-sent Read back the custom record only; observed initialization can advance without an acknowledgement. Never resend initialization.
initialized Recheck the full baseline, handle any untouched image stages, then save.
Per-image prepared Recall the original apply with identical bytes if they are no longer in memory; resume alone returns MARKETING_IMAGE_REQUIRED.
Per-image grant-sent / upload-sent Hold with MARKETING_UPLOAD_UNKNOWN for inspection; never reissue the grant or repeat upload.
Per-image uploaded Retain the verified receipt and continue untouched work.
save-sent Reconcile from full readback only. Match can complete with settingsSaveAcknowledged:false; mismatch holds with MARKETING_SAVE_UNKNOWN. Never resend save.
done Return historical:true and verification.confirmed:false after authority checks. Read the screen for current state.

Status never advances effects. Resume may run untouched stages; no sent boundary is automatically reset, even after definite failure. A rejected continuation of a completed task returns its error without writing an error detail into the completed journal.

The marketing-widget namespace uses the selected task store. For a deliberate later restoration, obtain a fresh reader revision and separately authorized input; retain uncertain tasks.

Saved record identity

A missing record differs from an existing malformed record. Stored JSON null, false, zero or an empty string is rejected with TASK_STATE_UNVERIFIED by the existing record validator. Apply/dry-run/status/resume must not overwrite it or treat it as a fresh task. Preserve the file for inspection; do not delete/edit it or replace the request ID to bypass the error. Existing valid task recovery and genuinely missing-record behavior remain unchanged.