Update a widget

View as Markdown
Changes a widget's settings. Despite the `PUT` verb this is a **partial** update: only the fields you send change, and at least one must be sent. Two exceptions to "merge" semantics: - `branding` replaces the stored branding object as a whole (send every branding field you want to keep; `primary_color` is required inside it). - `allowed_origins` replaces the whole list. Send `greeting_message: null` (or an empty string) to clear the greeting. The widget API key cannot be rotated and the widget cannot be deactivated here; use `DELETE /api/widgets/{id}` to take it down. **Side effects.** Updates the row, clears the cached widget list, the cached authenticated embed script and the runtime configuration cache, and writes an audit entry. **Consistency.** Runtime endpoints (`/widget/*`) keep a per-instance copy of the configuration for up to 30 seconds, so a new `allowed_origins`, `rate_limit_rpm` or `voice_enabled` can take that long to apply everywhere. Browsers may cache the embed script for up to 5 minutes, so launcher colour and position changes can take that long to appear on your site. **Idempotency.** Safe to retry: sending the same body again leaves the same state (only `updated_at` moves). **Webhook events.** `audit.log_recorded` when you subscribe to it. See [Webhooks](/webhooks). **Access** - **Required scope:** `write`. - **Rate limit:** General API — 120 requests/min per workspace (200 on Growth, 300 on Business, 600 on Enterprise). See [Rate limits](/rate-limits). - **Plan:** Available on every plan.

Authentication

AuthorizationBearer
Workspace API key: `jl_` followed by 64 lowercase hex characters, created by the workspace owner in the dashboard (**Settings → API Keys**) and sent as `Authorization: Bearer jl_...`. The plaintext is shown once, at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys. | Scope | GET / HEAD | POST / PUT / PATCH / DELETE | Admin-only routes | | --- | --- | --- | --- | | `read` | Yes | No | No | | `write` | Yes | Yes | No | | `full` | Yes | Yes | Yes | Operations restricted to admins or owners reject keys without the `full` scope with `403`, and say so in their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret — that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds. See [Authentication](/authentication).

Path parameters

idstringRequiredformat: "uuid"

Widget id. A value that is not a UUID returns 400 Invalid widget ID.

Request

At least one field must be present with a defined value.
agent_idstringOptionalformat: "uuid"

Agent that answers visitors from now on. Not looked up; use an agent of your workspace.

namestringOptional1-200 characters

Internal name. Trimmed; an empty or blank string is treated as not sent.

allowed_originslist of stringsOptional

Replaces the whole list. Full origins (scheme, host, optional port); * never matches.

brandingobjectOptional

Widget look and copy. On write, primary_color is required whenever branding is sent, and the object REPLACES the stored branding (it is not merged). Widgets created without branding store {}, which is what POST /widget/init then returns.

voice_enabledbooleanOptional

Whether POST /widget/voice-session may be used for this widget.

greeting_messagestring or nullOptional<=2000 characters

First message the widget shows. Trimmed. null or an empty string clears it.

rate_limit_rpmintegerOptional>=1

Requests per minute allowed per widget credential on the public /widget/* endpoints.

Response

The updated widget.
dataobject

A web-chat widget configuration. Returned by every /api/widgets endpoint. Field names are snake_case.

Errors

400
Bad Request Error
401
Unauthorized Error
403
Forbidden Error
404
Not Found Error
429
Too Many Requests Error