Developer API
Events reference
Every event, on every transport, arrives in the same envelope. data depends on type and is described below. Fields are only ever added, so ignore any you do not know. test is true for events sent from the dashboard's Send test event button.
{
"id": "01k6a9m3f4q8x2z7c5v0b1n3r6",
"type": "tip.created",
"occurred_at": "2026-09-26T19:04:11Z",
"test": false,
"creator": {
"id": 12,
"slug": "ghostzero"
},
"data": {
"…": "…"
}
}
Wherever a viewer is involved, data.member is {"id", "display_name", "login", "twitch_id"}. login is the Twitch handle for chat mentions; it is null until Gleem has learned it, so fall back to display_name. source says where it happened: extension (the Twitch extension) or web (gleem.gg).
Text a viewer wrote passes the creator's message filter first. Blocked words and links come through as ***, or the whole text is null, depending on the creator's setting. message_filtered and input_filtered are true when that happened, so a tool can skip text-to-speech for it.
tip.created
A viewer sent Gems with an optional message and GIF.
{
"id": 1201,
"member": {
"id": 345,
"display_name": "Viewer",
"login": "viewer",
"twitch_id": "123456"
},
"gems": 250,
"message": "gg!",
"message_filtered": false,
"gif": {
"url": "https://static.klipy.com/example.gif",
"width": 320,
"height": 240,
"title": "Hype"
},
"source": "extension"
}
treat.redeemed
A viewer redeemed a Treat, which put a new entry in the queue.
{
"queue_entry": {
"id": 901,
"session_id": 55,
"position": 3,
"status": "pending",
"refunded": false
},
"redemption_id": "9b3c2c1e-6c4f-4f0e-9f59-2f1b8d0b7a11",
"member": {
"id": 345,
"display_name": "Viewer",
"login": "viewer",
"twitch_id": "123456"
},
"treat": {
"id": 7,
"name": "Ear Cleaning",
"icon": "fa-solid fa-ear"
},
"payment_type": "gems",
"gems": 40,
"input_label": "Which ear?",
"input": "Left, please",
"input_filtered": false,
"source": "web"
}
queue.entry.updated
A queue entry changed status, was refunded, or was deleted.
{
"queue_entry": {
"id": 901,
"session_id": 55,
"position": 3,
"status": "active",
"refunded": false
},
"redemption_id": "9b3c2c1e-6c4f-4f0e-9f59-2f1b8d0b7a11",
"member": {
"id": 345,
"display_name": "Viewer",
"login": "viewer",
"twitch_id": "123456"
},
"treat": {
"id": 7,
"name": "Ear Cleaning",
"icon": "fa-solid fa-ear"
},
"payment_type": "gems",
"gems": 40,
"input_label": "Which ear?",
"input": "Left, please",
"input_filtered": false,
"action": "status_changed",
"previous_status": "pending"
}
queue.opened
The queue opened and accepts Treat redemptions.
{
"session": {
"id": 55,
"status": "open",
"total_slots": 10,
"closes_at": "23:00",
"timezone": "Europe/Berlin"
}
}
queue.closed
The queue closed: by the creator, at its scheduled time, or because a new queue replaced it.
{
"session": {
"id": 55,
"status": "closed",
"total_slots": 10,
"closes_at": "23:00",
"timezone": "Europe/Berlin"
},
"reason": "creator"
}
membership.started
A viewer started, or restarted, a monthly membership.
{
"member": {
"id": 345,
"display_name": "Viewer",
"login": "viewer",
"twitch_id": "123456"
},
"membership": {
"id": 88,
"tier": {
"id": 4,
"name": "Supporter",
"price_gems": 300
},
"pending_tier": null,
"source": "web",
"renews_at": "2026-10-26T19:04:11Z",
"ends_at": null
}
}
membership.renewed
A membership was charged for another month.
{
"member": {
"id": 345,
"display_name": "Viewer",
"login": "viewer",
"twitch_id": "123456"
},
"membership": {
"id": 88,
"tier": {
"id": 4,
"name": "Supporter",
"price_gems": 300
},
"pending_tier": null,
"source": "web",
"renews_at": "2026-10-26T19:04:11Z",
"ends_at": null
},
"gems": 300
}
membership.tier_changed
A membership moved to another tier: at once for an upgrade, at renewal for a downgrade.
{
"member": {
"id": 345,
"display_name": "Viewer",
"login": "viewer",
"twitch_id": "123456"
},
"membership": {
"id": 88,
"tier": {
"id": 4,
"name": "Supporter",
"price_gems": 300
},
"pending_tier": null,
"source": "web",
"renews_at": "2026-10-26T19:04:11Z",
"ends_at": null
},
"previous_tier": {
"id": 3,
"name": "Fan",
"price_gems": 100
},
"gems": 133
}
membership.cancelled
A membership was cancelled by the viewer, or because a renewal failed for want of Gems.
{
"member": {
"id": 345,
"display_name": "Viewer",
"login": "viewer",
"twitch_id": "123456"
},
"membership": {
"id": 88,
"tier": {
"id": 4,
"name": "Supporter",
"price_gems": 300
},
"pending_tier": null,
"source": "web",
"renews_at": "2026-10-26T19:04:11Z",
"ends_at": "2026-10-26T19:04:11Z"
},
"reason": "member"
}
post.unlocked
A viewer bought a for-sale post.
{
"member": {
"id": 345,
"display_name": "Viewer",
"login": "viewer",
"twitch_id": "123456"
},
"post": {
"id": 17,
"title": "Behind the scenes"
},
"gems": 30,
"source": "web"
}
follow.created
A viewer followed the creator on Gleem.
{
"member": {
"id": 345,
"display_name": "Viewer",
"login": "viewer",
"twitch_id": "123456"
}
}
gems.exchanged
A viewer bought Gems with Bits in the Twitch extension.
{
"member": {
"id": 345,
"display_name": "Viewer",
"login": "viewer",
"twitch_id": "123456"
},
"gems": 60,
"sku": "gems_500",
"transaction_id": "b1b2c3d4-0000-0000-0000-000000000000"
}
tickets.granted
A viewer received Trigger Tickets.
{
"member": {
"id": 345,
"display_name": "Viewer",
"login": "viewer",
"twitch_id": "123456"
},
"amount": 1,
"reason": "channel_points",
"balance": 3
}
stream.online
The creator went live on Twitch.
{
"stream": {
"id": "41375541868",
"started_at": "2026-09-26T18:00:02Z"
}
}
stream.offline
The creator's stream ended.
{}