ChatStyle External API

The External API lets third-party tools — chatbots, Twitch extensions, stream management apps — interact with your ChatStyle overlay programmatically. Для доступа к внешнему API нужна активная подписка ChatStyle Premium.

Base URL: https://chatstyle.gg/api/ext

Authentication

All requests require a Bearer token in the Authorization header and must include Accept: application/json — without it, error responses will redirect instead of returning JSON:

Production traffic is filtered by Cloudflare. Some default bot/client user agents are blocked before the request reaches the app, so send a descriptive custom User-Agent header.

HTTP Headers
Authorization: Bearer YOUR_API_KEY
Accept: application/json
User-Agent: YourApp/1.0

Generating an API Key

  1. Go to Dashboard → Settings
  2. Open the API tab and click Create Key
  3. Copy the token immediately — it will not be shown again

Твой API-ключ даёт полный доступ ко всем endpoints, пока Premium активен. You can have one active key at a time — revoke the existing key to create a new one.

Revoking Keys

Go to Dashboard → Settings → API and click Revoke on any key. Revoked keys stop working immediately.

Rate Limiting

  • 30 requests per minute per API key
  • Write request bodies are limited to 64 KiB; larger requests return 413 Payload Too Large
  • Exceeding the limit returns 429 Too Many Requests
  • The response includes Retry-After and X-RateLimit-* headers

Error Responses

All errors follow a consistent format:

JSON
{
    "message": "Human-readable error description."
}

Validation errors (422) include field-level details:

JSON
{
    "message": "The values field is required.",
    "errors": {
        "values": ["The values field is required."]
    }
}

Common Status Codes

Code Meaning
200Success
201Created
401Unauthenticated — invalid or missing token
403Forbidden — access denied
404Resource not found
422Validation error
429Rate limit exceeded

Endpoints

Style Settings

GET /api/ext/template

Read the active template settings for an overlay.

Query parameters:

ParameterTypeRequiredDescription
preset_idintegerNoOverlay ID. Pass as preset_id for API compatibility. Defaults to your default overlay.

Example:

Bash
curl -A "YourApp/1.0" \
     -H "Accept: application/json" \
     -H "Authorization: Bearer YOUR_API_KEY" \
     "https://chatstyle.gg/api/ext/template"

Response:

JSON
{
    "data": {
        "template_id": 1,
        "template_name": "Twitch Basic",
        "template_slug": "twitch-basic",
        "settings_values": {
            "bubble.background-color": "#1a1a2e",
            "bubble.padding": 12,
            "message.font-color": "#ffffff"
        },
        "source_values": {
            "bubble.background-color": "#1a1a2e"
        },
        "override_values": {
            "bubble.padding": 12
        },
        "overridden_keys": ["bubble.padding"],
        "sync_source_preset_id": 1,
        "preset_id": 1,
        "preset_name": "Default"
    }
}
PUT /api/ext/template

Update template settings with an explicit overlay sync scope. Values are merged with the chosen scope (partial updates are supported).

Request body:

FieldTypeRequiredDescription
scopestringYessource updates the selected overlay's sync source, override updates overlay overrides, independent updates an overlay with no sync source.
valuesobjectYesKey-value pairs of settings to update
preset_idintegerNoOverlay ID. Pass as preset_id for API compatibility. Defaults to your default overlay.

Example:

Bash
curl -X PUT \
     -A "YourApp/1.0" \
     -H "Accept: application/json" \
     -H "Authorization: Bearer YOUR_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"scope":"override","values":{"bubble.background-color":"#ff0000"}}' \
     "https://chatstyle.gg/api/ext/template"

Response:

JSON
{
    "message": "Style settings updated.",
    "data": {
        "settings_values": {
            "bubble.background-color": "#ff0000",
            "message.font-color": "#ffffff"
        },
        "source_values": {
            "message.font-color": "#ffffff"
        },
        "override_values": {
            "bubble.background-color": "#ff0000"
        },
        "scope": "override",
        "preset_id": 1
    }
}
Note: Changes are broadcast to the overlay in real-time via WebSocket.

Skins

GET /api/ext/skins

List your custom skins for the active template.

Query parameters:

ParameterTypeRequiredDescription
preset_idintegerNoOverlay ID to filter skins by that overlay's template. Pass as preset_id for API compatibility. Defaults to default overlay.

Example:

Bash
curl -A "YourApp/1.0" \
     -H "Accept: application/json" \
     -H "Authorization: Bearer YOUR_API_KEY" \
     "https://chatstyle.gg/api/ext/skins"

Response:

JSON
{
    "data": [
        {
            "id": 42,
            "name": "Neon Purple",
            "slug": "neon-purple",
            "description": "A vibrant purple skin",
            "availability": "free",
            "settings_values": {
                "bubble.background-color": "#6b21a8",
                "message.font-color": "#e9d5ff"
            },
            "is_active": true
        }
    ]
}
PUT /api/ext/skins/{skin_id}

Update a skin's settings. Only skins owned by your streamer profile can be updated. Values are merged with existing settings; values matching the template or preset base are removed from the stored skin overrides.

Request body:

FieldTypeRequiredDescription
valuesobjectYesKey-value pairs of settings to update

Example:

Bash
curl -X PUT \
     -A "YourApp/1.0" \
     -H "Accept: application/json" \
     -H "Authorization: Bearer YOUR_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"values": {"bubble.background-color": "#00ff00"}}' \
     "https://chatstyle.gg/api/ext/skins/42"

Response:

JSON
{
    "message": "Skin updated.",
    "data": {
        "id": 42,
        "name": "Neon Purple",
        "settings_values": {
            "bubble.background-color": "#00ff00",
            "message.font-color": "#e9d5ff"
        }
    }
}
Note: If the skin is assigned to a role, the overlay is updated in real-time.

Viewer Skin Access

POST /api/ext/viewers/unlock-skin

Grant a viewer access to a specific skin. This creates an entitlement — the viewer can then select the skin via the overlay or streamer shop page.

Request body:

FieldTypeRequiredDescription
twitch_usernamestringOne of username/user_id requiredViewer's Twitch login name
twitch_user_idstringOne of username/user_id requiredViewer's Twitch user ID
skin_idintegerYesThe skin to unlock

Example:

Bash
curl -X POST \
     -A "YourApp/1.0" \
     -H "Accept: application/json" \
     -H "Authorization: Bearer YOUR_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"twitch_username": "someviewer", "skin_id": 42}' \
     "https://chatstyle.gg/api/ext/viewers/unlock-skin"

Response:

JSON
{
    "message": "Skin unlocked for viewer.",
    "data": {
        "twitch_username": "someviewer",
        "skin": {
            "id": 42,
            "name": "Neon Purple"
        }
    }
}
Important notes:
  • The viewer must have a ChatStyle account (they need to have logged in at least once). Returns 404 if the viewer doesn't exist.
  • The skin must belong to your channel (your own custom skin or a global platform skin).
  • Unlocking is idempotent — calling it twice for the same viewer+skin does not create duplicates.
  • Unlocking grants access but does not auto-select the skin. The viewer still needs to select it.
DELETE /api/ext/viewers/unlock-skin

Revoke a viewer's API-granted skin access. Only revokes access that was granted via this API — real purchases are never affected.

Request body: Same as unlock (provide twitch_username or twitch_user_id, plus skin_id).

Example:

Bash
curl -X DELETE \
     -A "YourApp/1.0" \
     -H "Accept: application/json" \
     -H "Authorization: Bearer YOUR_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"twitch_username": "someviewer", "skin_id": 42}' \
     "https://chatstyle.gg/api/ext/viewers/unlock-skin"

Response:

JSON
{
    "message": "Skin access revoked for viewer."
}
Returns 404 if no API-granted access exists for that viewer+skin combination.
GET /api/ext/viewers/{identifier}/skins

List all skins a viewer has been granted access to via this API.

The {identifier} can be either a Twitch username or Twitch user ID.

Example:

Bash
curl -A "YourApp/1.0" \
     -H "Accept: application/json" \
     -H "Authorization: Bearer YOUR_API_KEY" \
     "https://chatstyle.gg/api/ext/viewers/someviewer/skins"

Response:

JSON
{
    "data": [
        {
            "id": 42,
            "name": "Neon Purple",
            "slug": "neon-purple"
        }
    ]
}

Settings Keys Reference

Style and skin settings use dotted keys in the format element.property. The available keys depend on the active style's settings schema — not every style uses every key. Use GET /api/ext/template to see the current settings_values and discover which keys are in use.

Note: Color values accept 3-, 4-, 6-, or 8-digit hex strings such as #fff, #fffc, or #1a1a2e. Short hex values are expanded in responses. Fully transparent colors are represented by the literal transparent in both requests and responses. Numeric values must be JSON numbers inside the documented range. Most numeric settings accept 0 through 10000; box shadow offset and spread settings accept -10000 through 10000. Select values must be one of the listed options. Toggle values must be JSON true or false.
Advanced toggle behavior: When a *-advanced toggle is true, the matching per-side or per-corner keys control rendering. The uniform key is still stored, but it does not affect output until the advanced toggle is turned off again.

Chat

Spacing

KeyTypeDefaultDescription
chat.paddinginteger0Uniform inner spacing around the whole chat container in px (0–10000). Designer label: Space Inside Chat Area
chat.padding-advancedtogglefalseEnable per-side chat inner spacing controls
chat.padding-topinteger0Top inner spacing for the chat container in px (0–10000)
chat.padding-rightinteger0Right inner spacing for the chat container in px (0–10000)
chat.padding-bottominteger0Bottom inner spacing for the chat container in px (0–10000)
chat.padding-leftinteger0Left inner spacing for the chat container in px (0–10000)

Bubble

Designer note: Chat Flow Direction, Alignment, and Text Direction now appear in the Chat tab in the designer, but their stored keys stay bubble.message-direction, bubble.alignment, and bubble.direction.

Structural

KeyTypeDefaultDescription
bubble.directionselectltrText direction. Options: ltr, rtl
bubble.message-directionselectbottom-upMessage flow direction. Options: bottom-up, top-down, left-to-right, right-to-left
bubble.full-widthtogglefalseWhether bubbles stretch to full container width
bubble.alignmentselectleftBubble alignment. Options: left, center, right

Background

KeyTypeDefaultDescription
bubble.background-colorcolortransparentBackground color
bubble.background-gradientgradient""Complete normalized CSS gradient string

Border

KeyTypeDefaultDescription
bubble.border-widthinteger0Border width in px (0–10000)
bubble.border-colorcolortransparentBorder color
bubble.border-styleselectsolidOptions: none, solid, dashed, dotted, double
bubble.border-radiusinteger0Uniform border radius in px (0–10000)
bubble.border-radius-advancedtogglefalseEnable per-corner radius
bubble.border-radius-top-leftinteger0Top-left corner radius (0–10000)
bubble.border-radius-top-rightinteger0Top-right corner radius (0–10000)
bubble.border-radius-bottom-rightinteger0Bottom-right corner radius (0–10000)
bubble.border-radius-bottom-leftinteger0Bottom-left corner radius (0–10000)

Shadow

KeyTypeDefaultDescription
bubble.box-shadow-offset-xinteger0Horizontal shadow offset (-10000 to 10000)
bubble.box-shadow-offset-yinteger0Vertical shadow offset (-10000 to 10000)
bubble.box-shadow-blur-radiusinteger0Shadow blur radius (0–10000)
bubble.box-shadow-spread-radiusinteger0Shadow spread radius (-10000 to 10000)
bubble.box-shadow-colorcolor#000000Shadow color
bubble.box-shadow-insettogglefalseUse inset shadow

Animation

KeyTypeDefaultDescription
bubble.animation-entranceselectslide-in-upEntrance animation. Options: none, fade-in, fade-in-up, fade-in-down, fade-in-left, fade-in-right, slide-in-up, slide-in-down, slide-in-left, slide-in-right, bounce-in, bounce-in-up, bounce-in-down, zoom-in, zoom-in-up, flip-in-x, flip-in-y, rotate-in, jack-in-the-box, roll-in, light-speed-in-right
bubble.animation-durationinteger750Animation duration in ms (0–10000)
bubble.animation-delayinteger0Animation delay in ms (0–10000)
bubble.animation-easingselectease-outOptions: ease-out, ease-in, ease-in-out, linear, ease

Spacing

KeyTypeDefaultDescription
bubble.paddinginteger0Inner padding in px (0–10000)
bubble.gapinteger10Gap between bubbles on the .cs-chat container in px (0–10000)
bubble.widthinteger400Bubble width in px (0–10000)

Avatar

Structural

KeyTypeDefaultDescription
avatar.showtoggletrueShow/hide avatar
avatar.positionselectrightOptions: left, center, right
avatar.sizeinteger60Avatar size in px (0–10000)

Background

KeyTypeDefaultDescription
avatar.background-colorcolortransparentBackground color
avatar.background-gradientgradient""Complete normalized CSS gradient string

Border

KeyTypeDefaultDescription
avatar.border-widthinteger0Border width in px (0–10000)
avatar.border-colorcolortransparentBorder color
avatar.border-styleselectsolidOptions: none, solid, dashed, dotted, double
avatar.border-radiusinteger0Uniform border radius in px (0–10000)
avatar.border-radius-advancedtogglefalseEnable per-corner radius
avatar.border-radius-top-leftinteger0Top-left corner radius (0–10000)
avatar.border-radius-top-rightinteger0Top-right corner radius (0–10000)
avatar.border-radius-bottom-rightinteger0Bottom-right corner radius (0–10000)
avatar.border-radius-bottom-leftinteger0Bottom-left corner radius (0–10000)

Shadow

KeyTypeDefaultDescription
avatar.box-shadow-offset-xinteger0Horizontal shadow offset (-10000 to 10000)
avatar.box-shadow-offset-yinteger0Vertical shadow offset (-10000 to 10000)
avatar.box-shadow-blur-radiusinteger0Shadow blur radius (0–10000)
avatar.box-shadow-spread-radiusinteger0Shadow spread radius (-10000 to 10000)
avatar.box-shadow-colorcolor#000000Shadow color
avatar.box-shadow-insettogglefalseUse inset shadow

Animation

KeyTypeDefaultDescription
avatar.animation-entranceselectnoneEntrance animation (same options as bubble)
avatar.animation-durationinteger750Animation duration in ms (0–10000)
avatar.animation-delayinteger0Animation delay in ms (0–10000)
avatar.animation-easingselectease-outOptions: ease-out, ease-in, ease-in-out, linear, ease

Spacing

KeyTypeDefaultDescription
avatar.paddinginteger0Inner padding in px (0–10000)

Username

Structural

KeyTypeDefaultDescription
username.positionselectabove-messageOptions: above-message, inline
username.font-styleselectnormalOptions: normal, italic
username.text-decorationselectnoneOptions: none, underline
username.text-transformselectnoneOptions: none, uppercase, lowercase, capitalize

Typography

KeyTypeDefaultDescription
username.font-sizeinteger14Font size in px (0–10000)
username.font-colorcolor#ffffffText color
username.font-familystringInterFont family (from font catalog)
username.font-weightselect400Options: 300, 400, 500, 600, 700, 800, 900
username.text-shadow-offset-xinteger0Horizontal text shadow offset (0–10000)
username.text-shadow-offset-yinteger0Vertical text shadow offset (0–10000)
username.text-shadow-blur-radiusinteger0Text shadow blur (0–10000)
username.text-shadow-colorcolor#000000Text shadow color
username.text-stroke-widthinteger0Text stroke width in px (0–10000)
username.text-stroke-colorcolor#000000Text stroke color

Background

KeyTypeDefaultDescription
username.background-colorcolortransparentBackground color
username.background-gradientgradient""Complete normalized CSS gradient string

Border

KeyTypeDefaultDescription
username.border-widthinteger0Border width in px (0–10000)
username.border-colorcolortransparentBorder color
username.border-styleselectsolidOptions: none, solid, dashed, dotted, double
username.border-radiusinteger0Uniform border radius in px (0–10000)
username.border-radius-advancedtogglefalseEnable per-corner radius
username.border-radius-top-leftinteger0Top-left corner radius (0–10000)
username.border-radius-top-rightinteger0Top-right corner radius (0–10000)
username.border-radius-bottom-rightinteger0Bottom-right corner radius (0–10000)
username.border-radius-bottom-leftinteger0Bottom-left corner radius (0–10000)

Shadow

KeyTypeDefaultDescription
username.box-shadow-offset-xinteger0Horizontal shadow offset (-10000 to 10000)
username.box-shadow-offset-yinteger0Vertical shadow offset (-10000 to 10000)
username.box-shadow-blur-radiusinteger0Shadow blur radius (0–10000)
username.box-shadow-spread-radiusinteger0Shadow spread radius (-10000 to 10000)
username.box-shadow-colorcolor#000000Shadow color
username.box-shadow-insettogglefalseUse inset shadow

Animation

KeyTypeDefaultDescription
username.animation-entranceselectnoneEntrance animation (same options as bubble)
username.animation-durationinteger750Animation duration in ms (0–10000)
username.animation-delayinteger0Animation delay in ms (0–10000)
username.animation-easingselectease-outOptions: ease-out, ease-in, ease-in-out, linear, ease

Spacing

KeyTypeDefaultDescription
username.paddinginteger0Inner padding in px (0–10000)

Message

Structural

KeyTypeDefaultDescription
message.font-styleselectnormalOptions: normal, italic
message.text-decorationselectnoneOptions: none, underline
message.text-transformselectnoneOptions: none, uppercase, lowercase, capitalize

Typography

KeyTypeDefaultDescription
message.font-sizeinteger14Font size in px (0–10000)
message.font-colorcolor#ffffffText color
message.font-familystringInterFont family (from font catalog)
message.font-weightselect400Options: 300, 400, 500, 600, 700, 800, 900
message.text-shadow-offset-xinteger0Horizontal text shadow offset (0–10000)
message.text-shadow-offset-yinteger0Vertical text shadow offset (0–10000)
message.text-shadow-blur-radiusinteger0Text shadow blur (0–10000)
message.text-shadow-colorcolor#000000Text shadow color
message.text-stroke-widthinteger0Text stroke width in px (0–10000)
message.text-stroke-colorcolor#000000Text stroke color

Background

KeyTypeDefaultDescription
message.background-colorcolortransparentBackground color
message.background-gradientgradient""Complete normalized CSS gradient string

Border

KeyTypeDefaultDescription
message.border-widthinteger0Border width in px (0–10000)
message.border-colorcolortransparentBorder color
message.border-styleselectsolidOptions: none, solid, dashed, dotted, double
message.border-radiusinteger0Uniform border radius in px (0–10000)
message.border-radius-advancedtogglefalseEnable per-corner radius
message.border-radius-top-leftinteger0Top-left corner radius (0–10000)
message.border-radius-top-rightinteger0Top-right corner radius (0–10000)
message.border-radius-bottom-rightinteger0Bottom-right corner radius (0–10000)
message.border-radius-bottom-leftinteger0Bottom-left corner radius (0–10000)

Shadow

KeyTypeDefaultDescription
message.box-shadow-offset-xinteger0Horizontal shadow offset (-10000 to 10000)
message.box-shadow-offset-yinteger0Vertical shadow offset (-10000 to 10000)
message.box-shadow-blur-radiusinteger0Shadow blur radius (0–10000)
message.box-shadow-spread-radiusinteger0Shadow spread radius (-10000 to 10000)
message.box-shadow-colorcolor#000000Shadow color
message.box-shadow-insettogglefalseUse inset shadow

Animation

KeyTypeDefaultDescription
message.animation-entranceselectnoneEntrance animation (same options as bubble)
message.animation-durationinteger750Animation duration in ms (0–10000)
message.animation-delayinteger0Animation delay in ms (0–10000)
message.animation-easingselectease-outOptions: ease-out, ease-in, ease-in-out, linear, ease

Spacing

KeyTypeDefaultDescription
message.paddinginteger0Inner padding in px (0–10000)

Badges

KeyTypeDefaultDescription
badges.showtoggletrueShow/hide chat badges
badges.positionselectbefore-nameOptions: before-name, after-name