---
title: "Replace fields on an HTML surface body"
method: PUT
path: "/api/workspaces/{slug}/html"
tags: ["HTML body"]
---

# Replace fields on an HTML surface body

`PUT /api/workspaces/{slug}/html`

## Request

- Base URL: `https://trydock.ai`
- URL: `https://trydock.ai/api/workspaces/{slug}/html`
- Auth: HTTP bearer

Partial-update friendly. Any of `html` / `css` / `js` can be omitted to leave the column unchanged; pass empty string to clear. HTML is sanitized at write time (see UpdateHtmlSchema). Emits `html.created` on first write to a surface, `html.updated` on subsequent writes — both carry per-field byte counts so webhooks can fan out a meaningful signal. Requires editor role.

## Path parameters

- `slug` string, required

## Request body

- object
  - `surface_slug` string: Optional html surface slug. Omit to write to the primary html surface (lowest position).
  - `html` string: Sanitized at write time. Caps: 50 KB per field. Omit to leave the column unchanged; pass empty string to clear. Sanitizer strips <script>, every on* event handler, javascript:/vbscript:/file:/data:text/html URIs, <iframe>, <object>, <embed>, <foreignobject>, <meta>, <base>, <link>, formaction smuggling. Allows inline <style>, ARIA attrs, form markup (rendered but inert), data:image/* URIs.
  - `css` string: CSS source. Cap: 100 KB. Stored verbatim. Omit to leave unchanged; pass empty string to clear.
  - `js` string: JS source. Cap: 100 KB. Stored but not executed at v1.

## Response `200`

Written.

- object
  - `html` string, required: Sanitized HTML body. Empty string when the surface exists but no body has been written yet.
  - `css` string, required: CSS source. Applied inside the sandboxed iframe.
  - `js` string, required: JS source. Stored but NOT executed at v1 — the sandbox iframe is scripts-off. Interactive mode lands in a later PR.
  - `updatedAt` string, date-time, nullable, required
  - `updatedBy` string, nullable, required
  - `updatedByPrincipalType` string, nullable, required
  - `surfaceSlug` string, nullable, required: Slug of the resolved html surface. Null when the workspace has no html surface yet.

## Other responses

- `400`: Body shape failed validation, OR a field exceeded its byte cap (html 50KB, css 100KB, js 100KB, total envelope 250KB), OR sanitizer rejected the html field entirely.
- `404`: `surface_slug` didn't match any live html surface, or the workspace has no html surface yet.

---

[API](https://skmtc.dev/trydock/apis/dock-rest-api.md) - [All operations](https://skmtc.dev/trydock/apis/dock-rest-api/llms.txt) - [OpenAPI document](https://skmtc.dev/trydock/apis/dock-rest-api/revisions/dd96ae96a412?raw)
