> For the complete documentation index, see [llms.txt](https://docs.kickbot.com/dashboard/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kickbot.com/dashboard/api/reference/widgets.md).

# Custom widgets

KickBot API and MCP reference for Custom widgets. Widget builder presets, the widget library, and installed (saved) widgets.

Widget builder presets, the widget library, and installed (saved) widgets. MCP area name: `widgets`.

| Tool                                                                          | REST                                        | Access |
| ----------------------------------------------------------------------------- | ------------------------------------------- | ------ |
| [`list_widgets`](#list-widgets)                                               | `GET /widgets`                              | Read   |
| [`list_widget_templates`](#list-widget-templates)                             | `GET /widgets/templates`                    | Read   |
| [`get_widget`](#get-widget)                                                   | `GET /widgets/{id}`                         | Read   |
| [`create_widget`](#create-widget)                                             | `POST /widgets`                             | Write  |
| [`update_widget`](#update-widget)                                             | `PATCH /widgets/{id}`                       | Write  |
| [`delete_widget`](#delete-widget)                                             | `DELETE /widgets/{id}`                      | Write  |
| [`create_widget_file_upload`](#create-widget-file-upload)                     | `POST /widgets/{id}/file-uploads`           | Write  |
| [`create_widget_preview_image_uploads`](#create-widget-preview-image-uploads) | `POST /widgets/{id}/preview-image-uploads`  | Write  |
| [`publish_widget`](#publish-widget)                                           | `POST /widgets/{id}/publish`                | Write  |
| [`list_library_widgets`](#list-library-widgets)                               | `GET /widget-library`                       | Read   |
| [`get_library_widget`](#get-library-widget)                                   | `GET /widget-library/{id}`                  | Read   |
| [`install_widget`](#install-widget)                                           | `POST /widget-library/{id}/install`         | Write  |
| [`list_installed_widgets`](#list-installed-widgets)                           | `GET /installed-widgets`                    | Read   |
| [`get_installed_widget`](#get-installed-widget)                               | `GET /installed-widgets/{id}`               | Read   |
| [`update_installed_widget`](#update-installed-widget)                         | `PATCH /installed-widgets/{id}`             | Write  |
| [`create_installed_widget_file_upload`](#create-installed-widget-file-upload) | `POST /installed-widgets/{id}/file-uploads` | Write  |
| [`duplicate_installed_widget`](#duplicate-installed-widget)                   | `POST /installed-widgets/{id}/duplicate`    | Write  |
| [`delete_installed_widget`](#delete-installed-widget)                         | `DELETE /installed-widgets/{id}`            | Write  |

## list\_widgets

**List your custom widgets.** List the widgets this channel built in the widget builder (no code, use get\_widget for that). To show a widget on stream, use its installed copy: see installed\_widget\_ids in get\_widget.

`GET /api/v1/widgets`

| Field            | Type    | Required | Description                              |
| ---------------- | ------- | -------- | ---------------------------------------- |
| `limit` (query)  | integer | No       | Max items to return (1-100, default 50). |
| `offset` (query) | integer | No       | Number of items to skip (default 0).     |

## list\_widget\_templates

**List widget templates.** List the official templates you can start a new widget from (pass the id as template\_id to create\_widget).

`GET /api/v1/widgets/templates`

No input fields.

## get\_widget

**Get a custom widget with its code.** Get one of your widgets with its full HTML, CSS, JavaScript, variables (settings), size, library status (not\_submitted, in\_review, published, rejected), and the ids of its installed copies (use get\_installed\_widget on one to get the OBS overlay URL).

`GET /api/v1/widgets/{id}`

| Field              | Type   | Required | Description                                           |
| ------------------ | ------ | -------- | ----------------------------------------------------- |
| `id` (in the path) | string | Yes      | The widget id (from list\_widgets or create\_widget). |

## create\_widget

**Create a custom widget.** Create a new widget in the widget builder, empty or from a template, and optionally set its code and variables in the same call. KickBot also installs a copy for this channel that always shows the newest code; get\_widget returns its id in installed\_widget\_ids, and get\_installed\_widget gives the OBS overlay URL. Free plans can have 10 widgets. How a widget runs: the overlay page renders `html`, adds `css`, then runs `javascript` in the page. In JavaScript, read the streamer settings with `userVariables.<variable>.value`. Live channel data is in `globalValues` (subCount, followerCount, viewerCount, lastFollower, lastSub, lastGiftedSub, chatMessages, streamerInfo.kick, currentStream). Listen to live Kick events with `document.addEventListener('widgetEvent', (event) => { const { event_name, data } = event.detail; })`. Event names: subEvent, subGiftEvent, kicksEvent, followEvent, unfollowEvent, chatMessageEvent, chatMessageDeletedEvent, chatMessagePinnedEvent, chatMessageUnpinnedEvent, chatClearedEvent, followerCountUpdatedEvent, subCountUpdatedEvent, viewerCountUpdatedEvent, raidEvent, streamOnline, streamOffline. Use `window.kickbotWidget.createTextNode(text)` or `createChatMessageFragment(content, font_size)` to show viewer text safely (never put chat text into innerHTML). Full reference: <https://docs.kickbot.com/dashboard/widgets/widget-builder-docs>.

`POST /api/v1/widgets`

Needs a read and write key or connection.

| Field         | Type    | Required | Description                                                                                                                                     |
| ------------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`        | string  | Yes      | Widget name.                                                                                                                                    |
| `template_id` | string  | No       | Optional template id from list\_widget\_templates. Leave out for an empty widget.                                                               |
| `html`        | string  | No       | Widget HTML (body content, no or ).                                                                                                             |
| `css`         | string  | No       | Widget CSS.                                                                                                                                     |
| `javascript`  | string  | No       | Widget JavaScript. See the create\_widget description for the runtime.                                                                          |
| `width`       | integer | No       | Overlay width in pixels. Default 800 (or the template size).                                                                                    |
| `height`      | integer | No       | Overlay height in pixels. Default 600 (or the template size).                                                                                   |
| `variables`   | object  | No       | All settings of the widget, keyed by variable name (letters, digits, \_). Replaces the full set. JavaScript reads them as userVariables..value. |

## update\_widget

**Update a custom widget.** Change the name, code, size, or variables of one of your widgets. Only the fields you send change; `variables` replaces the full set. Installed copies of your own widget show the new code the next time the overlay loads (refresh the OBS browser source). Published library versions do not change. How a widget runs: the overlay page renders `html`, adds `css`, then runs `javascript` in the page. In JavaScript, read the streamer settings with `userVariables.<variable>.value`. Live channel data is in `globalValues` (subCount, followerCount, viewerCount, lastFollower, lastSub, lastGiftedSub, chatMessages, streamerInfo.kick, currentStream). Listen to live Kick events with `document.addEventListener('widgetEvent', (event) => { const { event_name, data } = event.detail; })`. Event names: subEvent, subGiftEvent, kicksEvent, followEvent, unfollowEvent, chatMessageEvent, chatMessageDeletedEvent, chatMessagePinnedEvent, chatMessageUnpinnedEvent, chatClearedEvent, followerCountUpdatedEvent, subCountUpdatedEvent, viewerCountUpdatedEvent, raidEvent, streamOnline, streamOffline. Use `window.kickbotWidget.createTextNode(text)` or `createChatMessageFragment(content, font_size)` to show viewer text safely (never put chat text into innerHTML). Full reference: <https://docs.kickbot.com/dashboard/widgets/widget-builder-docs>.

`PATCH /api/v1/widgets/{id}`

Needs a read and write key or connection.

| Field              | Type    | Required | Description                                                                                                                                     |
| ------------------ | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` (in the path) | string  | Yes      | The widget id (from list\_widgets or create\_widget).                                                                                           |
| `name`             | string  | No       | Widget name.                                                                                                                                    |
| `html`             | string  | No       | Widget HTML (body content, no or ).                                                                                                             |
| `css`              | string  | No       | Widget CSS.                                                                                                                                     |
| `javascript`       | string  | No       | Widget JavaScript. See the create\_widget description for the runtime.                                                                          |
| `width`            | integer | No       | Overlay width in pixels (the OBS browser source width).                                                                                         |
| `height`           | integer | No       | Overlay height in pixels (the OBS browser source height).                                                                                       |
| `variables`        | object  | No       | All settings of the widget, keyed by variable name (letters, digits, \_). Replaces the full set. JavaScript reads them as userVariables..value. |

## delete\_widget

**Delete a custom widget.** Delete one of your widgets from the widget builder. Its installed copy that shows the in-development code stops working. Copies installed from the public library keep working.

`DELETE /api/v1/widgets/{id}`

Needs a read and write key or connection. This cannot be undone.

| Field              | Type   | Required | Description                                           |
| ------------------ | ------ | -------- | ----------------------------------------------------- |
| `id` (in the path) | string | Yes      | The widget id (from list\_widgets or create\_widget). |

## create\_widget\_file\_upload

**Upload a file for a widget variable.** Step 1 of 2 to use your own image, video, or audio file in a widget variable. Send the file type and size; returns an upload\_url that only accepts that exact type and size. Step 2: send the file with HTTP PUT to upload\_url within 30 minutes: body = the raw file, with the headers in `headers` (Content-Type must be exactly content\_type; the body must be exactly size\_bytes long, or the upload fails). Then set file\_url as the variable default with update\_widget. A new upload for the same variable and target deletes the earlier files. Allowed types: image/png, image/jpeg, image/gif, image/webp, video/mp4, video/webm, video/quicktime, audio/mpeg, audio/mp3, audio/wav, audio/wave, audio/x-wav, audio/vnd.wave, audio/ogg, audio/opus, audio/webm, audio/mp4, audio/x-m4a, audio/m4a, audio/aac, audio/x-aac, audio/flac, audio/x-flac. Max size: 25 MB (25000000 bytes).

`POST /api/v1/widgets/{id}/file-uploads`

Needs a read and write key or connection.

| Field              | Type    | Required | Description                                                                                                                                                                                                                                                                                                                                                  |
| ------------------ | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id` (in the path) | string  | Yes      | The widget id (from list\_widgets or create\_widget).                                                                                                                                                                                                                                                                                                        |
| `variable`         | string  | Yes      | The variable name the file is for.                                                                                                                                                                                                                                                                                                                           |
| `file_name`        | string  | Yes      | File name with extension, for example "background.png".                                                                                                                                                                                                                                                                                                      |
| `content_type`     | string  | Yes      | MIME type of the file, exactly as you will send it in Content-Type: image/png, image/jpeg, image/gif, image/webp, video/mp4, video/webm, video/quicktime, audio/mpeg, audio/mp3, audio/wav, audio/wave, audio/x-wav, audio/vnd.wave, audio/ogg, audio/opus, audio/webm, audio/mp4, audio/x-m4a, audio/m4a, audio/aac, audio/x-aac, audio/flac, audio/x-flac. |
| `size_bytes`       | integer | Yes      | File size in bytes, max 25 MB. The PUT body must be exactly this long.                                                                                                                                                                                                                                                                                       |

## create\_widget\_preview\_image\_uploads

**Upload preview images before publishing.** Step 1 of 3 to publish a widget to the public library. Send the name, type, and size of each image (max 10; the first one is the main preview image). Returns one upload\_url per image; each only accepts that exact type and size. Step 2: send each image with HTTP PUT to its upload\_url within 30 minutes: body = the raw image, with the headers in its `headers` (Content-Type must be exactly content\_type; the body must be exactly size\_bytes long). Step 3: call publish\_widget with the image\_url values. Allowed types: image/png, image/jpeg, image/gif, image/webp. Max size: 10 MiB (10485760 bytes).

`POST /api/v1/widgets/{id}/preview-image-uploads`

Needs a read and write key or connection.

| Field              | Type            | Required | Description                                                                                                                                       |
| ------------------ | --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` (in the path) | string          | Yes      | The widget id (from list\_widgets or create\_widget).                                                                                             |
| `images`           | array of object | Yes      | The images, for example \[{ "file\_name": "main.png", "content\_type": "image/png", "size\_bytes": 48213 }]. The first is the main preview image. |

## publish\_widget

**Submit a widget to the public widget library.** OUTWARD ACTION: submits your widget to the public KickBot widget library. A copy of the current code becomes version 1 and goes to review by KickBot staff; after approval every KickBot streamer can see and install it, with your Kick name as the creator. This can only be done once per widget and cannot be undone through the API. Upload preview images first with create\_widget\_preview\_image\_uploads. Only do this when the channel owner asked to publish.

`POST /api/v1/widgets/{id}/publish`

Needs a read and write key or connection. This cannot be undone. This has an effect outside your settings (for example on your live stream).

| Field                | Type            | Required | Description                                                                                  |
| -------------------- | --------------- | -------- | -------------------------------------------------------------------------------------------- |
| `id` (in the path)   | string          | Yes      | The widget id (from list\_widgets or create\_widget).                                        |
| `description`        | string          | Yes      | Public description shown in the library.                                                     |
| `preview_image_urls` | array of string | Yes      | image\_url values from create\_widget\_preview\_image\_uploads. The first is the main image. |

## list\_library\_widgets

**Browse the widget library.** List the public widgets any streamer can install (official KickBot widgets and community widgets). Install one with install\_widget.

`GET /api/v1/widget-library`

| Field                   | Type                                  | Required | Description                                                    |
| ----------------------- | ------------------------------------- | -------- | -------------------------------------------------------------- |
| `search` (query)        | string                                | No       | Only widgets whose name contains this text (case-insensitive). |
| `official_only` (query) | boolean                               | No       | Only official KickBot widgets.                                 |
| `sort` (query)          | `"name"` or `"popular"` or `"newest"` | No       | name (A-Z, default), popular (most installs), or newest.       |
| `limit` (query)         | integer                               | No       | Max items to return (1-100, default 50).                       |
| `offset` (query)        | integer                               | No       | Number of items to skip (default 0).                           |

## get\_library\_widget

**Get a library widget.** Get the description, images, size, and install count of a public library widget, and whether this channel already installed it.

`GET /api/v1/widget-library/{id}`

| Field              | Type   | Required | Description                                          |
| ------------------ | ------ | -------- | ---------------------------------------------------- |
| `id` (in the path) | string | Yes      | The library widget id (from list\_library\_widgets). |

## install\_widget

**Install a library widget.** Install a public library widget on this channel. Returns the installed widget with its settings and the OBS overlay URL. It always shows the newest published version. Installing again creates a second copy with its own settings.

`POST /api/v1/widget-library/{id}/install`

Needs a read and write key or connection.

| Field              | Type   | Required | Description                                          |
| ------------------ | ------ | -------- | ---------------------------------------------------- |
| `id` (in the path) | string | Yes      | The library widget id (from list\_library\_widgets). |

## list\_installed\_widgets

**List installed widgets.** List the widgets installed on this channel (from the library, and the copies of your own widgets). Use get\_installed\_widget for the settings and the OBS overlay URL.

`GET /api/v1/installed-widgets`

| Field            | Type    | Required | Description                              |
| ---------------- | ------- | -------- | ---------------------------------------- |
| `limit` (query)  | integer | No       | Max items to return (1-100, default 50). |
| `offset` (query) | integer | No       | Number of items to skip (default 0).     |

## get\_installed\_widget

**Get an installed widget and its overlay URL.** Get an installed widget: its settings (each with type, default, and current value), its size, and overlay\_url. To show it on stream, add overlay\_url as a Browser Source in OBS (or another streaming app) with the given width and height. The URL is secret: do not post it in chat or in public.

`GET /api/v1/installed-widgets/{id}`

| Field              | Type   | Required | Description                                                                 |
| ------------------ | ------ | -------- | --------------------------------------------------------------------------- |
| `id` (in the path) | string | Yes      | The installed widget id (from list\_installed\_widgets or install\_widget). |

## update\_installed\_widget

**Change the settings of an installed widget.** Change the name or setting values of an installed widget. Only the settings you send change. Values must match the setting type (see get\_installed\_widget). Set a value to null to use the default. After the save, the live overlay reloads.

`PATCH /api/v1/installed-widgets/{id}`

Needs a read and write key or connection.

| Field              | Type   | Required | Description                                                                                             |
| ------------------ | ------ | -------- | ------------------------------------------------------------------------------------------------------- |
| `id` (in the path) | string | Yes      | The installed widget id (from list\_installed\_widgets or install\_widget).                             |
| `name`             | string | No       | A name for this installed copy.                                                                         |
| `values`           | object | No       | New setting values keyed by setting name, for example {"text\_color": "#ffffff", "show\_avatar": true}. |

## create\_installed\_widget\_file\_upload

**Upload a file for an installed widget setting.** Step 1 of 2 to use your own image, video, or audio file in a setting of an installed widget. Send the file type and size; returns an upload\_url that only accepts that exact type and size. Step 2: send the file with HTTP PUT to upload\_url within 30 minutes: body = the raw file, with the headers in `headers` (Content-Type must be exactly content\_type; the body must be exactly size\_bytes long, or the upload fails). Then set file\_url as the value with update\_installed\_widget. A new upload for the same setting deletes the earlier file. Allowed types: image/png, image/jpeg, image/gif, image/webp, video/mp4, video/webm, video/quicktime, audio/mpeg, audio/mp3, audio/wav, audio/wave, audio/x-wav, audio/vnd.wave, audio/ogg, audio/opus, audio/webm, audio/mp4, audio/x-m4a, audio/m4a, audio/aac, audio/x-aac, audio/flac, audio/x-flac. Max size: 25 MB (25000000 bytes).

`POST /api/v1/installed-widgets/{id}/file-uploads`

Needs a read and write key or connection.

| Field              | Type    | Required | Description                                                                                                                                                                                                                                                                                                                                                  |
| ------------------ | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id` (in the path) | string  | Yes      | The installed widget id (from list\_installed\_widgets or install\_widget).                                                                                                                                                                                                                                                                                  |
| `setting`          | string  | Yes      | The setting name the file is for.                                                                                                                                                                                                                                                                                                                            |
| `file_name`        | string  | Yes      | File name with extension, for example "background.png".                                                                                                                                                                                                                                                                                                      |
| `content_type`     | string  | Yes      | MIME type of the file, exactly as you will send it in Content-Type: image/png, image/jpeg, image/gif, image/webp, video/mp4, video/webm, video/quicktime, audio/mpeg, audio/mp3, audio/wav, audio/wave, audio/x-wav, audio/vnd.wave, audio/ogg, audio/opus, audio/webm, audio/mp4, audio/x-m4a, audio/m4a, audio/aac, audio/x-aac, audio/flac, audio/x-flac. |
| `size_bytes`       | integer | Yes      | File size in bytes, max 25 MB. The PUT body must be exactly this long.                                                                                                                                                                                                                                                                                       |

## duplicate\_installed\_widget

**Duplicate an installed widget.** Make a second copy of an installed widget with the same settings and its own overlay URL, for example to show it twice with different settings.

`POST /api/v1/installed-widgets/{id}/duplicate`

Needs a read and write key or connection.

| Field              | Type   | Required | Description                                                                 |
| ------------------ | ------ | -------- | --------------------------------------------------------------------------- |
| `id` (in the path) | string | Yes      | The installed widget id (from list\_installed\_widgets or install\_widget). |

## delete\_installed\_widget

**Remove an installed widget.** Remove an installed widget from this channel. Its overlay URL stops working. The library widget itself is not changed.

`DELETE /api/v1/installed-widgets/{id}`

Needs a read and write key or connection. This cannot be undone.

| Field              | Type   | Required | Description                                                                 |
| ------------------ | ------ | -------- | --------------------------------------------------------------------------- |
| `id` (in the path) | string | Yes      | The installed widget id (from list\_installed\_widgets or install\_widget). |

## Need help?

Email <support@kickbot.com> or ask in the `#support` channel on [Discord](https://discord.gg/MAg3gBbc89).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.kickbot.com/dashboard/api/reference/widgets.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
