publ betaReference (MCP guide)
Open publ console

publ Reference

Migration map.

channel_seo_apply

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

Save selected SEO title/description fields and an optional replacement PNG/JPEG, verify preserved fields, then request the source cache refresh as one recoverable workflow.

Current new text uses the UTF-16 screen bounds and historical recovery rules. Title allows 40 units and description 80; a supplementary emoji counts as two. This supersedes the historical character-count wording below. Older unsent overlong plans remain inspectable but blocked without changing their journals or uploaded objects.

Access and preconditions

Requires OWNER or DELEGATEE with MANAGE_SEO_TOOLS for the selected channel. Discover the channel first. The source-defined hosted selected-channel resource admits this tool only for its exact channelCode; an account resource does not. These rules are implementation scope, not deployed authentication or isolation evidence.

Read channel_seo_get and retain its exact revision. The writer reads both SEO and connected-domain state twice and requires the same verified ACTIVATED domain. After channel/context checks succeed, a domain404 observation returns action_required / SEO_DOMAIN_UNVERIFIED; a non-active domain returns action_required / SEO_DOMAIN_REQUIRED. Both report writesPerformed:false and unverified eligibility while preserving the exact SEO console destination. The human action explains the account-level domain registration/selection, channel connection and ACTIVATED prerequisite. This result does not create/connect a domain or establish that a domain404 means absence.

The host must configure DNS and the recache service, including roboFriendlyApiOrigin or PUBL_ROBO_FRIENDLY_API_ORIGIN in the selected environment. Image replacement additionally needs the resource gateway, upload bucket and region. These requirements apply to dry runs and no-op plans too. Do not pass service URLs, credentials or storage settings as tool inputs. The source hosted JSON request bound is 8 MiB, but client/transport support for that size remains unverified.

A newly prepared plan records the current verified credential context after stable readback. Fresh completion revisions use the current context; historical results retain their saved identity. Verified renewal within the same port does not authorize rebinding an old journal or accepting external credential/permission changes. The channel-seo namespace uses the selected task backend, including the hosted database store when supplied; this source wiring is separate from live hosted durability.

Inputs

Objects are strict, including image. Provide at least one of title, description or image; this refinement is not expressed by the exported JSON Schema. Omitted text/image fields are preserved. There is no clear-image, empty-text, URL-fetch, recache-only or domain-change operation.

Field Required here Contract
title No string; max length 40; Search title, at most 40 UTF-16 code units. An empty string saves the channel name, as the console does.
description No string; min length 1; max length 80; Search description, 1–80 UTF-16 code units.
image No one of: local-file, more-parts, complete, cancel (by kind); Upload the image from this computer: {kind:"local-file", filename, byteLength, sha256} returns one presigned PUT (size, type and SHA-256 signed) and the console link; send the file, then call again with the same input and this field set to {kind:"complete", uploadId, parts:[{partNumber:1, etag}]}. The server never receives the file or downloads a link; download a link to this computer first.
image.filename Yes When image.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.
image.byteLength Yes When image.kind is local-file: integer; greater than 0; The exact file size in bytes (for example from wc -c < FILE or stat).
image.sha256 No When image.kind is local-file: string; pattern ^[0-9a-f]{64}$; The SHA-256 of the file in lowercase hex (shasum -a 256 FILE). Required when the upload answers UPLOAD_CHECKSUM_REQUIRED.
image.uploadId Yes When image.kind is more-parts: string; pattern ^upl_[A-Za-z0-9_-]{22}$
image.fromPart Yes When image.kind is more-parts: integer; minimum 1; maximum 10000
image.uploadId Yes When image.kind is complete: string; pattern ^upl_[A-Za-z0-9_-]{22}$
image.parts Yes When image.kind is complete: array; min items 1; max items 10000
image.parts[].partNumber Yes When image.kind is complete: integer; minimum 1; maximum 10000
image.parts[].etag Yes When image.kind is complete: string; min length 1; max length 200
image.measured No When image.kind is complete: object; What the video measures on this computer, read with measureCommand.
image.measured.durationSeconds Yes When image.kind is complete: number; maximum 1000000; greater than 0; Video duration in seconds (ffprobe format.duration).
image.measured.frameRate Yes When image.kind is complete: number; maximum 1000; greater than 0; Frames per second (ffprobe avg_frame_rate, for example 30000/1001 = 29.97).
image.measured.width Yes When image.kind is complete: integer; maximum 100000; greater than 0
image.measured.height Yes When image.kind is complete: integer; maximum 100000; greater than 0
image.measured.frameRateMode No When image.kind is complete: CFR, VFR; Constant or variable frame rate, when the tool reports it.
image.measured.minFrameRate No When image.kind is complete: number; maximum 1000; greater than 0
image.measured.maxFrameRate No When image.kind is complete: number; maximum 1000; greater than 0
image.uploadId Yes When image.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.

Filename extensions are case-insensitive at runtime, but the exported regex omits that flag; use lowercase extensions for compatibility with both. Decoded bytes must match the extension and pass PNG/JPEG structural checks. Arbitrary bytes matching the input string pattern are insufficient. The bridge preserves the original bytes without resizing, rendering or fetching; structural checks do not verify appearance.

Input examples

These are illustrative dry runs, not observed service results. Replace the selected channel and zero-filled revision with values from one fresh read. The small PNG demonstrates a complete file payload; use the user's intended original image for a real requested change.

{
  "channelCode":"selected-channel-code",
  "requestId":"seo-title-plan-001",
  "expectedRevision":"0000000000000000000000000000000000000000000000000000000000000000",
  "title":"Site title",
  "dryRun":true
}
{
  "channelCode":"selected-channel-code",
  "requestId":"seo-text-plan-001",
  "expectedRevision":"0000000000000000000000000000000000000000000000000000000000000000",
  "title":"Site title",
  "description":"A description of this site.",
  "dryRun":true
}
{
  "channelCode":"selected-channel-code",
  "requestId":"seo-image-plan-001",
  "expectedRevision":"0000000000000000000000000000000000000000000000000000000000000000",
  "image":{"filename":"seo.png","base64":"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+aDWQAAAAASUVORK5CYII="},
  "dryRun":true
}

Execution and results

CHANNEL_SEO_PLAN reports the verified domain, planned stages and noop. A no-op requires an identified record, no replacement image and unchanged requested text. It skips upload/save/recache; a real no-op stores a done task. An id:null observation is never treated as a no-op or proof of persistence. A dry run creates no job. Recalling an existing matching task with dryRun:true returns its historical plan/result, not a refreshed preview.

For a changed image, execution obtains upload credentials and uploads the checked original bytes with a checksum before saving metadata. Raw bytes and temporary grant credentials are not stored in the task journal. The metadata POST goes to /seller/api/v2/channel-management/seo-tools/channel-seo-information/save, containing only supplied text and the acknowledged uploaded image reference. The save receipt and independent repeated reads must preserve every omitted field and the existing numeric record identity/insertedAt, or establish a positive ID for a previously unidentified observation.

The following recache POST targets the configured service's /seller/api/v1/recache with channel and connected-domain headers. The save still requires HTTP 200 with its data contract. Recache accepts HTTP 200 or 204 without a response-body contract; 201/202/206 are not accepted. Credential/context drift still overrides an otherwise valid acknowledgement. Recache has no status endpoint. These are separate requests, with no transaction or automatic rollback. Recache failure can leave metadata saved. The bridge never automatically removes an uploaded object, including one left after a failed/conflicting save.

CHANNEL_SEO_COMPLETE includes the final record/revision. Read metadataSaveAcknowledged, cacheRequestAcknowledged, historical and verification together. A no-op has neither acknowledgement. A save recovered solely by matching readback can finish with metadataSaveAcknowledged:false and writesPerformed:null: matching state does not prove this task caused it. Actual acknowledgements never establish cache freshness, rendered preview, public image access or search-engine indexing.

CHANNEL_SEO_PENDING retains phase, lastResult and any acknowledged steps; it is not completion. Authentication/context failures can suppress channel metadata. journalPersistence.saved:false means the error checkpoint could not be saved; preserve the original task and inspect it instead of assuming the stage is durable.

Task recovery

Changed inputs return REQUEST_ID_CONFLICT. Invalid journals return TASK_STATE_UNVERIFIED; do not copy, edit or rename a journal to bypass the checks.

Phase Recovery behavior
prepared Resume may start remaining work after the original state and context checks. For an unstarted image, call the original apply with identical bytes/input/requestId; plain resume has no bytes and returns SEO_IMAGE_REQUIRED in the pending result.
grant-sent / upload-sent Hold with SEO_UPLOAD_OUTCOME_UNKNOWN for inspection; no replacement grant or upload. This boundary is not reset even for a definite transport rejection.
uploaded Preserve the acknowledged object, recheck unchanged SEO/domain and continue the untouched save.
save-sent Read back only. A matching full desired record can advance to saved; mismatch remains SEO_SAVE_OUTCOME_UNKNOWN. Never resend the save.
saved Recheck the saved record and original domain, then perform the untouched recache.
recache-sent Hold with SEO_RECACHE_OUTCOME_UNKNOWN. No automatic resend or reconciliation through an invented status endpoint.
cached Recheck the record and complete without repeating recache. A concurrent change remains paused.
done Return historical completion with verification.confirmed:false; use get for current values.

Status reads historical task state without advancing it. Resume can send untouched stages. Each grant/upload/save/recache boundary is recorded before dispatch and is not automatically reset after an error. Context, domain or record changes pause progress. Never start a second task solely to bypass an uncertain result.

This page documents source behavior and checked inputs.

SEO retains its independent domain prerequisites and unverified positive-write scope.

This corrects the earlier strict-metadata boundary failure shared with widget uploads.

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.