# Publish Viz

```
POST 
/v1/viz/:viz_id/publish
```

Publish: merge draft → main, tag, trigger build.

V32 — pre-flight checks the iframe bundle health on the viz row. If `bundle_state.status == FAILED` (or STALE) and `force=false`, the helper raises HTTPException 409 with a structured payload so the publish dialog can show the bundle error and offer "publish anyway".

Ticket 1 — callers MAY pass `view_mode` in the request body to set visibility at publish time. The governance gate shared with `PATCH /v1/viz/\{id\}` — `_enforce_public_escalation_gate` — runs when the publish is what puts a public viz live:

* body carries `view_mode="public"` → gate (the request escalates);
* body carries any OTHER `view_mode` → no gate (`protected` / `private` on publish is a de-escalation, whatever is stored);
* body omits `view_mode` → gate iff the STORED viz is public. A viz created public (`POST /v1/viz`, now gated too) and published with `{}` used to sail through because this branch only read the body.

## Request[​](#request "Enlace directo al request")

## Responses[​](#responses "Enlace directo al Responses")

* 200
* 403
* 404
* 422

Successful Response

The publish would put a PUBLIC viz live — viewMode=public in the body, or no viewMode and the stored viz is public — and public sharing is off for the account (PUBLIC\_SHARING\_DISABLED), or the caller is an API key and an admin has not turned on "Allow API keys to publish publicly".

Not found

Validation Error
