Webhooks
Embeds
Embeds are the rich cards a webhook can attach to its message, with a color bar, an author, a linked title, Markdown, fields, images and a footer. Same format and limits as Discord’s.
What they look like
An embed is drawn as a card under the message’s text: a color bar on the left, then the
author, the title (a link if it has a url), the description with Markdown, the fields (up to
three in a row when they’re inline), a large image, a thumbnail on the right and, at the
bottom, the footer and the date. Every part is optional; a card shows what it has.
Limits
- Up to 10 embeds per message.
- Up to 6,000 characters between all the embeds of a message, counting titles, descriptions, field names and values, footers and author names.
- The limit of each field is in the tables below. They’re Discord’s, so an embed that works there works here.
The embed object
| Field | Type | Limit and notes |
|---|---|---|
title |
string | Up to 256 characters. |
description |
string | Up to 4,096 characters, with the same Markdown as a message: bold, italics, code, quotes, lists. |
url |
string | Turns the title into a link. |
color |
integer | The bar’s color, as an RGB number: 0x2ECC71 is 3066993. Without it, a neutral bar. |
timestamp |
string | A date in ISO 8601 (2026-11-08T18:30:00.000Z), shown next to the footer. |
author |
object | Above the title. See below. |
footer |
object | At the bottom. See below. |
image |
object | A large image under the fields: { "url": "https://…" }. |
thumbnail |
object | A small image at the top right: { "url": "https://…" }. |
fields |
array | Up to 25. See below. |
author
| Field | Type | Limit and notes |
|---|---|---|
name |
string | Up to 256 characters. |
url |
string | Turns the name into a link. |
icon_url |
string | A small round icon, https only. |
footer
| Field | Type | Limit and notes |
|---|---|---|
text |
string | Up to 2,048 characters. |
icon_url |
string | A small round icon, https only. |
fields
| Field | Type | Limit and notes |
|---|---|---|
name |
string | Up to 256 characters. |
value |
string | Up to 1,024 characters, with Markdown. |
inline |
boolean | true puts it next to the other inline fields, up to three in a row. |
Images and links
- Image and icon URLs must be
https. Any other is left out, and the rest of the embed still shows. - Klang doesn’t copy images: each reader’s app loads them from where they are, as with link previews. They have to be public and stay online.
- Links in an embed open in a new tab, like any link in a message. Masked links
(
[text](https://…)) work in the description and field values. video,providerand embeds whosetypeisn’trichare ignored.
Colors
color is the color as one number. From a hex code like #2ECC71:
const color = parseInt('2ECC71', 16); // 3066993color = int("2ECC71", 16) # 3066993A complete example
The message at the top of this page:
{
"username": "Deploy bot",
"content": "Production is up to date.",
"embeds": [
{
"author": {
"name": "acme/website",
"url": "https://github.com/acme/website",
"icon_url": "https://example.com/acme-icon.png"
},
"title": "Deploy #482 finished",
"url": "https://example.com/deploys/482",
"description": "Shipped **3 commits** to `main` in 1 min 42 s. The new pricing page is live.",
"color": 3066993,
"fields": [
{ "name": "Environment", "value": "production", "inline": true },
{ "name": "Duration", "value": "1 min 42 s", "inline": true },
{ "name": "Triggered by", "value": "ana", "inline": true }
],
"thumbnail": { "url": "https://example.com/acme-logo.png" },
"image": { "url": "https://example.com/deploys/482/preview.png" },
"footer": { "text": "Deploys", "icon_url": "https://example.com/deploys-icon.png" },
"timestamp": "2026-11-08T18:30:00.000Z"
}
]
}Send it like any other message, as in Execute a webhook:
curl -X POST "$KLANG_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d @deploy.json