[Migration map](../reference/tool-name-migration.md).
# design_custom_code_apply — save advanced code
Save the requested CSS, head/body JavaScript and head HTML together as one workflow. First read [design_custom_code_get](publ_design_custom_code_get.md) and use its channel and revision. Each supplied code field replaces that entire area; it is not an append or text patch.
## Input
| Field | Type | Required | Constraint |
| --- | --- | --- | --- |
| `requestId` | string | Yes | 8–80 ASCII letters, digits, underscores or hyphens; preserve it for this operation. |
| `channelCode` | string | Yes | Nonempty code of the channel just read. |
| `expectedRevision` | string | Yes | Lowercase 64-character hexadecimal revision from that read. |
| `css` | string | Conditional | Complete CSS source. Omit to preserve; empty string clears. |
| `headJavaScript` | string | Conditional | Complete raw head JavaScript, without manual storage escaping. |
| `bodyJavaScript` | string | Conditional | Complete raw body JavaScript, without manual storage escaping. |
| `headHtml` | string | Conditional | Complete raw head HTML. |
| `dryRun` | boolean | No | Defaults to `false`; `true` inspects a plan. |
Supply at least one code field. The object is strict: extra fields and `null` are invalid. All four code fields preserve omitted values and clear on an explicit empty string. Source is not trimmed, syntax-checked or normalized by this schema; whitespace is retained. No code-length maximum is declared.
```json
{
"requestId":"example-custom-code-001",
"channelCode":"selected-channel-code",
"expectedRevision":"0000000000000000000000000000000000000000000000000000000000000000",
"css":".site-title { letter-spacing: 0.02em; }",
"headJavaScript":"window.siteLabel = `Example ${document.title}`;",
"bodyJavaScript":"",
"headHtml":"<meta name=\"application-name\" content=\"Example\">",
"dryRun":true
}
```
Replace the placeholder channel/revision and use the intended complete source. This illustrative example clears body JavaScript and replaces the other three areas. It is not a live transcript. Inspect the plan, then retain the ID and all business inputs and change only `dryRun` to `false` to execute.
## Access and storage rules
The get tool's connection, target, role and origin guards apply. **Any supplied JavaScript or HTML field invokes the scripts/HTML gate**, including an empty string or a value identical to existing code. An unavailable gate rejects a mixed CSS/script request with `CUSTOM_CODE_UNAVAILABLE` before its first write. For an independent CSS edit, omit all three JavaScript/HTML fields.
Before initialization and each remaining write, the workflow rereads channel context and availability and checks the entire original input again. A gate change after the CSS step can stop the later script/HTML step, leaving CSS saved. A skipped step already matching its expected state needs no new write; completed replays do not freshly check availability.
The bridge stores JavaScript by prefixing each backtick and dollar sign with a backslash and reverses that storage escaping on get. Pass raw JavaScript using ordinary JSON escaping only. CSS and HTML are stored without this transformation.
The read field is `customCSS`; its CSS write patch is `customCss`. Script/HTML patches use `customJs`, `customJsBody`, and `customHeadTags`. These are internal API field names, not additional tool inputs.
## Plan and execution
For a new request, the tool compares the current full-code revision with `expectedRevision` and checks availability. Real execution saves a job, initializes missing shared settings with `POST /seller/api/v1/channel-management/custom` and `{}`, then applies a necessary CSS patch before one combined JavaScript/HTML patch. Initialization supplies the settings used to derive the real patches; this workflow does not explicitly change theme tone or palette.
Updates use `PUT /seller/api/v1/channel-management/custom/experimentals` at CHANNEL_ENV with the selected-channel bearer and channel-ID header. The workflow reads after each write and checks all four expected code fields again at completion. It performs no separate publication or credential refresh. Saved code can affect the channel immediately; the bridge does not execute it or verify its rendered behavior.
These sequential steps are not atomic. Revision comparisons cannot prevent every external change between a read and a write. Earlier successful changes can remain after a later failure; no automatic rollback is provided.
| Path | Result |
| --- | --- |
| New dry run | `success/PLAN_READY`, environment, channel, availability, `initializeRequired`, and `requested` containing the parsed input. For initialized settings, `steps` contains `{kind,patch}` entries; otherwise it is omitted until initialization supplies the actual starting state. No job or task identity is created. |
| Existing job dry run | `PLAN_READY`, `taskType:custom-code`, task ID, `existingPhase`, and stored steps when present. Each stored step includes kind, patch, before/after code and state. Channel context is checked; code and availability are not freshly read. New-plan fields are omitted. |
| Completion | `success/CUSTOM_CODE_APPLIED`, task ID/type, environment, channel, the get tool's code-view fields, `changed`, and `verification:{confirmed:true,method:custom_code_read}`. Availability and the get result's effect text are not included. |
`changed` means the saved plan has at least one code step, not necessarily a write sent by this call. **`changed:false` can still follow initialization**. Matching readback establishes observed stored state, not which actor changed it or whether it works in a browser. A completed replay returns its historical saved result, after checking current channel context. Use get for current code.
Non-demo get/completion results can link to the advanced CSS console. In this revision, a new dry-run result lacks the task type used by that route selector and can receive the account directory link; an existing-job dry run lacks channel metadata and receives no such link. Do not infer a successful editor visit from any returned URL.
## Recovery and failures
Preserve the exact parsed business inputs, request ID, connection, channel and job storage. Fingerprinting ignores the dry-run flag, but includes the exact source strings and original revision. Use [task_status](publ_task_status.md) and [task_resume](publ_task_resume.md) with the original task ID and `taskType:custom-code`. A new dry run has no saved task.
| Saved state | Continuation |
| --- | --- |
| `prepared` before initialization | Verify the initial state and access. Definite rejected/not-sent initialization failures restore this phase. |
| `initializing` | Read first. If settings remain absent, return unknown without resending initialization. If present, derive steps from the observed settings; this is not proof this task created them. |
| Code step `prepared` | If all code matches its after state, mark it done without writing. Otherwise require the matching before state and fresh access before a write. |
| Code step `sending` | Accept matching after-state readback; otherwise return unknown without replaying that write. |
| Code step `done` | Skip it, then still verify the final full code state. |
| Job `done` | Return the stored historical result. |
Definite rejected/not-sent update failures restore that step to `prepared`; uncertain failures retain `sending`. Status returns job phase, step kinds/states and the last result. `pending` is saved progress, not a running background worker. Internal failures can include `phase` and `completedSteps`; the count covers completed code groups, not initialization. Outer failures can omit those fields.
| Code | Meaning |
| --- | --- |
| `INVALID_INPUT` | A field or required code option is invalid; SDK validation can reject earlier. |
| `CUSTOM_CODE_UNAVAILABLE` | The original request includes JavaScript/HTML that current availability does not allow. |
| `DESIGN_CONFLICT` | The initial revision or an intermediate before state changed. Read current code and inspect saved progress. |
| `TASK_CONTEXT_CHANGED`, `CONNECTION_CHANGED` | The original input/account/channel binding no longer matches. |
| `DESIGN_INITIALIZATION_UNVERIFIED` | Initialization was acknowledged but its settings could not be read. |
| `DESIGN_OUTCOME_UNKNOWN` | Uncertain initialization or saving remains unverified and will not be automatically resent. |
| `DESIGN_VERIFICATION_MISMATCH` | Intermediate/final code differs from the expected full state. Do not report completion. |
Other authentication, target, origin and read failures follow the get tool's rules. An error outcome describes the failed request and does not imply earlier steps made no changes. Do not create a new request ID to force an uncertain change to repeat. Apply and shared resume are mutation-capable and carry destructive hints because existing code can be replaced or cleared.
## Saved plan replay
For an existing matching task, `dryRun` returns historical saved plan/progress,
with `historical:true`, `replayed:true` and false current verification. It performs
no fresh business-state or eligibility check, no business effect and no journal
change. Current console/action links are omitted. Follow `nextStep` for the same
target's current state; keep the original task ID for uncertain-outcome recovery.
Context and saved-input checks still apply. A new task follows normal fresh-plan
validation; another request ID must not bypass an uncertain effect.
`nextStep` uses design_custom_code_get with the original channelCode; existingPhase and per-step code/state remain saved data. Reading history does not execute stored code.
## Saved record identity
For this workflow, existing apply/dry-run calls and task status/resume require
both the saved task ID and saved input requestId to match the requested ID.
A mismatching or malformed saved identity returns `TASK_STATE_UNVERIFIED` before
workflow context or business-state reads. Preserve the original record for
inspection; do not rename/edit it, try its embedded ID or create a replacement
request to bypass the error. No stored record is repaired or resent. Valid
matching records retain the recovery behavior described above.
## Inputs
| Field | Required here | Contract |
| --- | --- | --- |
| `css` | No | string |
| `headJavaScript` | No | string |
| `bodyJavaScript` | No | string |
| `headHtml` | No | string |
| `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. |