publ betaReference (MCP guide)
Open publ console

publ Reference

Migration map.

marketing_popup_apply

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

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

settings.description permits empty text or 2–100 UTF-16 code units, including editor newlines before storage encoding. Omit it to preserve the current value. One unit and values above 100 are rejected. Popup title remains empty or 2–20; visible button labels remain 2–10. For example, after get returns a revision, configure can supply this description without changing images or visibility:

{
  "settings": {
    "description": "Explore our newest stories, upcoming events, and member benefits in one place."
  }
}

Include this settings fragment with action:"configure", the selected channelCode, the returned expectedRevision and a stable requestId.

Use dryRun:true for a plan without a business write or task JSON. Explicit execution can initialize custom settings after verified404 and upload images before saving. All other custom business fields must match readback. Keep taskType:marketing-widget for status/resume; unknown sent requests are never repeated. An unstarted image after restart requires the original apply bytes. Historical completion is not current verification. Human plan changes use the returned screen; no billing mutation, rollback or orphan deletion occurs.

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_popup_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 20; Empty or 2–20 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 100; Popup editor text: empty or 2–100 UTF-16 code units, including newlines before storage encoding. Omit to preserve the current description.
settings.title_color No string; min length 1; max length 128
settings.description_color No string; min length 1; max length 128
settings.btn_count_option No NOT_USE, USE_ONE, USE_TWO
settings.btn_1_text No string; max length 10; Empty or 2–10 UTF-16 code units, matching the source editor. Emoji may occupy two units. Omit to preserve the saved value.
settings.btn_1_conversion_link_url No string; max length 4096
settings.btn_1_conversion_link_type No WEB_LINK, INTERNAL_LINK
settings.btn_2_text No string; max length 10; Empty or 2–10 UTF-16 code units, matching the source editor. Emoji may occupy two units. Omit to preserve the saved value.
settings.btn_2_conversion_link_url No string; max length 4096
settings.btn_2_conversion_link_type No WEB_LINK, INTERNAL_LINK
images No object
images.bg_image_src No one of: local-file, more-parts, complete, cancel (by kind) or null
images.bg_image_src.filename Yes When images.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.bg_image_src.byteLength Yes When images.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.bg_image_src.sha256 No When images.bg_image_src.kind is local-file: string; pattern ^[0-9a-f]{64}$
images.bg_image_src.uploadId Yes When images.bg_image_src.kind is more-parts: string; pattern ^upl_[A-Za-z0-9_-]{22}$
images.bg_image_src.fromPart Yes When images.bg_image_src.kind is more-parts: integer; minimum 1; maximum 10000
images.bg_image_src.uploadId Yes When images.bg_image_src.kind is complete: string; pattern ^upl_[A-Za-z0-9_-]{22}$
images.bg_image_src.parts Yes When images.bg_image_src.kind is complete: array; min items 1; max items 10000
images.bg_image_src.parts[].partNumber Yes When images.bg_image_src.kind is complete: integer; minimum 1; maximum 10000
images.bg_image_src.parts[].etag Yes When images.bg_image_src.kind is complete: string; min length 1; max length 200
images.bg_image_src.measured No When images.bg_image_src.kind is complete: object; What the video measures on this computer, read with measureCommand.
images.bg_image_src.measured.durationSeconds Yes When images.bg_image_src.kind is complete: number; maximum 1000000; greater than 0; Video duration in seconds (ffprobe format.duration).
images.bg_image_src.measured.frameRate Yes When images.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.bg_image_src.measured.width Yes When images.bg_image_src.kind is complete: integer; maximum 100000; greater than 0
images.bg_image_src.measured.height Yes When images.bg_image_src.kind is complete: integer; maximum 100000; greater than 0
images.bg_image_src.measured.frameRateMode No When images.bg_image_src.kind is complete: CFR, VFR
images.bg_image_src.measured.minFrameRate No When images.bg_image_src.kind is complete: number; maximum 1000; greater than 0
images.bg_image_src.measured.maxFrameRate No When images.bg_image_src.kind is complete: number; maximum 1000; greater than 0
images.bg_image_src.uploadId Yes When images.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–20 characters.
settings.description Empty or 2–100 UTF-16 code units before newline encoding. Omit to preserve; no trimming or truncation.
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.btn_count_option NOT_USE, USE_ONE or USE_TWO.
settings.btn_1_text Empty or 2–10 characters.
settings.btn_1_conversion_link_url Empty or a normalized HTTP(S) destination satisfying the source pattern.
settings.btn_1_conversion_link_type WEB_LINK or INTERNAL_LINK.
settings.btn_2_text Empty or 2–10 characters.
settings.btn_2_conversion_link_url Same destination constraint.
settings.btn_2_conversion_link_type WEB_LINK or INTERNAL_LINK.
settings.design_template_code GLOBAL_POPUP_TYPE_A, GLOBAL_POPUP_TYPE_B or GLOBAL_POPUP_TYPE_C.

For configure, each visible button in the composed result requires text of 2–10 characters and a nonempty destination. Hidden fields are preserved; selecting NOT_USE or USE_ONE does not erase hidden button data. Supplied description newlines are encoded as literal backslash-n before saving. Omitting description preserves its original representation. Reader/completion output decodes it for editor use.

Creation defaults are title TITLE, description DESCRIPTION, title_color and description_color #FFFFFF, the source https://static.publ.site/popup_default_image.png reference, USE_ONE, button text BUTTON/BUTTON2, https://publ.co destinations with WEB_LINK, and GLOBAL_POPUP_TYPE_B. No source-default image is fetched or uploaded by the bridge. These defaults never repair malformed stored data.

Text is not trimmed. For description, empty clears, one UTF-16 code unit is rejected and 2–100 units are accepted. A newline counts before encoding; an astral character such as an emoji occupies two units. The registered parser enforces this bound in addition to the exported maxLength:100; a JSON Schema validator alone can count Unicode differently. Other text fields retain their own bounds. 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.bg_image_src Omit to preserve; null removes the reference; otherwise an original PNG/JPEG object.
images.bg_image_src.filename Basename, 1–240 characters, PNG/JPG/JPEG extension; no path, URL, colon or control characters.
images.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 original 8 MiB request envelope; the later 16 MiB transport ceiling does not enlarge this file limit, 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": "popup-create-plan-001",
  "expectedRevision": "0000000000000000000000000000000000000000000000000000000000000000",
  "action": "create",
  "dryRun": true
}
{
  "channelCode": "selected-channel-code",
  "requestId": "popup-visibility-plan-001",
  "expectedRevision": "0000000000000000000000000000000000000000000000000000000000000000",
  "action": "visibility",
  "dryRun": true,
  "visible": false
}
{
  "channelCode": "selected-channel-code",
  "requestId": "popup-configure-plan-001",
  "expectedRevision": "0000000000000000000000000000000000000000000000000000000000000000",
  "action": "configure",
  "dryRun": true,
  "settings": {
    "title": "Welcome",
    "description": "Latest news"
  }
}
{
  "channelCode": "selected-channel-code",
  "requestId": "popup-image-plan-001",
  "expectedRevision": "0000000000000000000000000000000000000000000000000000000000000000",
  "action": "configure",
  "dryRun": true,
  "images": {
    "bg_image_src": {
      "filename": "popup.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 globalPopup 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.