Bot-API-Referenz
Öffentliche Bot-API · Version 1.0 · Basis-URL https://api.speakspeak.net
Überblick
SpeakSpeak bietet eine öffentliche, Discord-kompatible Bot-API: REST-Endpunkte und ein Echtzeit-Gateway. Diese Seite ist die vollständige Referenz — maschinell erzeugt aus derselben API-Beschreibung (OpenAPI 3.1), gegen die auch der Server geprüft wird.
Die technischen Beschreibungen von Endpunkten, Feldern und Fehlercodes sind auf Englisch, der Sprache der API. Den Einstieg auf Deutsch gibt die Entwickler-Seite.
A Discord-compatible REST + gateway dialect for bots on SpeakSpeak. Object shapes, error bodies, rate-limit headers, opcodes and intents follow Discord's wire format closely enough that a ported client library works with a changed base URL — with documented divergences:
- IDs are UUIDv7 strings, not snowflakes. UUIDv7 is time-ordered, so an id remains a valid time cursor for
before pagination.
- Avatars/icons are relative proxy paths (e.g.
/api/v1/avatars/{id}), not Discord CDN hashes.
- Attachment
url/proxy_url are null — SpeakSpeak attachment bytes are only reachable through its own permission-checked presign flow, which the facade does not expose.
- Permission bit positions are SpeakSpeak's own (stringified u64, Discord's wire convention, but the bits mean SpeakSpeak permissions).
- Fields marked "accepted, ignored" below are consumed for library compatibility and have no effect.
Authentifizierung
REST: Authorization: Bot <token> — exactly this scheme, case-sensitive, single space. Bearer, lowercase bot, or a bare token are rejected with 401 {"message":"401: Unauthorized","code":40001}. Gateway: authentication is in-band via the IDENTIFY payload, not a header.
Fehler
Every error body is Discord-shaped: {"message": "...", "code": <int>} (the 429 body is {"message","retry_after","global"} instead, as on Discord). A resource that exists but is not visible to the bot returns the same 404 "Unknown X" as a truly absent one — existence never leaks.
Wiederkehrende Fehlerantworten, auf die die Endpunkte unten verweisen:
List endpoints paginate with before=<UUIDv7 id> + limit. after / around are accepted for library compatibility but not implemented (ignored, logged server-side).
Rate-Limits
Every authenticated REST response carries X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (unix epoch seconds, 3 decimals), X-RateLimit-Reset-After (seconds, 3 decimals) and X-RateLimit-Bucket. A 429 additionally carries Retry-After and — only when the global bucket tripped — X-RateLimit-Global: true.
Buckets (fixed windows, budgets from the facade source):
- global, per bot: 50 requests / 1 s (bucket id
global)
- per bot + route bucket: 50 / 10 s — bucket id is the route class (
messages.write, messages.read, guild.read, reactions, typing, default), suffixed :{channel_id|guild_id} when the route carries that major parameter
- per bot + guild: 20 / 10 s
- destructive extra-throttle (message delete, kick): 5 / 10 s per bot + guild
- attachment upload: 10 / 60 s per bot (bucket id
attachments.upload)
- webhook execute: 30 / 60 s per webhook, plus 120 / 60 s per source IP
- interaction callback / follow-up: 120 / 60 s per source IP
Die Rate-Limit-Header im Einzelnen:
Gateway-Protokoll
wss://api.speakspeak.net/api/v1/gateway. Discord opcode dialect: 0 DISPATCH, 1 HEARTBEAT, 2 IDENTIFY, 3 PRESENCE_UPDATE, 4 VOICE_STATE_UPDATE, 6 RESUME, 7 RECONNECT, 9 INVALID_SESSION, 10 HELLO, 11 HEARTBEAT_ACK. Close codes: 4004 authentication failed/token revoked, 4008 rate limited (identify rate / concurrent session cap — at most 2 concurrent sessions per application), 4009 session timeout (missed heartbeats).
RESUME (opcode 6 with session_id + seq) is implemented: a dropped session is parked for 90 seconds and a resume within that window replays buffered dispatches from seq. Outside the window (or on a bad token) the server sends opcode 9 INVALID_SESSION and the bot must re-IDENTIFY. READY includes resume_gateway_url.
Intents are declared in IDENTIFY and gate event classes — see the GatewayIntents schema. intents: 0 receives no dispatches at all; a typical message bot wants GUILDS | GUILD_MESSAGES | MESSAGE_CONTENT = 33281.
Intents
IDENTIFY intents bitfield. A dispatch is delivered only when the session's intents include its event class — intents: 0 receives nothing. Bits the facade honours:
A typical message bot: GUILDS | GUILD_MESSAGES | MESSAGE_CONTENT = 33281.
Allgemein
Liveness probe
GET/api/v1/healthohne Authentifizierung
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/health
Antworten
Nutzer
Get the bot's own user
GET/api/v1/users/@me
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/users/@me \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
# Antwort 200
{
"id": "019e8232-90d4-70aa-8f3c-2d94bb1e6620",
"username": "diceroller#4102",
"discriminator": "0",
"global_name": "diceroller#4102",
"avatar": null,
"bot": true
}
Get a user
GET/api/v1/users/{user_id}
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/users/{user_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
# Antwort 200
{
"id": "019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"username": "alice#2044",
"discriminator": "0",
"global_name": "alice#2044",
"avatar": "/api/v1/avatars/019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"bot": false
}
Server (Guilds)
Get a guild
GET/api/v1/guilds/{guild_id}
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/guilds/{guild_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
# Antwort 200
{
"id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"name": "Speedrun Lounge",
"icon": "/api/v1/server-icons/019cebae-61c0-72d0-9be5-566cc17d0442",
"owner_id": "019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"description": "EU speedrunning community."
}
Kanäle
List guild channels
GET/api/v1/guilds/{guild_id}/channels
Includes categories as type-4 channels (Discord's model); SpeakSpeak stores them separately, the facade bridges the shape. Note the category object carries no topic/nsfw keys, as in the example.
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/guilds/{guild_id}/channels \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
# Antwort 200
[
{
"id": "019cebaf-7330-71f7-a8c3-344dd2e19a0b",
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"type": 4,
"name": "Text Channels",
"position": 0,
"parent_id": null
},
{
"id": "019cebb0-9828-74b0-a9d7-788aa3f24c5d",
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"type": 0,
"name": "general",
"topic": "Daily chatter",
"position": 0,
"parent_id": "019cebaf-7330-71f7-a8c3-344dd2e19a0b",
"nsfw": false
},
{
"id": "019cf0f0-40b8-76c1-b8ab-155ee4a35d6e",
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"type": 2,
"name": "Voice Lounge",
"topic": null,
"position": 1,
"parent_id": null,
"nsfw": false
}
]
Create a channel
POST/api/v1/guilds/{guild_id}/channels
Parameter
Request-Body
CreateChannelBody
Beispiel-Aufruf
curl -X POST https://api.speakspeak.net/api/v1/guilds/{guild_id}/channels \
-H "Authorization: Bot ssbot_<app>.<secret>" \
-H "Content-Type: application/json" \
-d '{
"name": "help-desk",
"type": 0,
"parent_id": "019cebaf-7330-71f7-a8c3-344dd2e19a0b"
}'
Antworten
# Antwort 201
{
"id": "01a01952-a228-70d2-b9ac-266ff5b46e7f",
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"type": 0,
"name": "help-desk",
"topic": null,
"position": 2,
"parent_id": "019cebaf-7330-71f7-a8c3-344dd2e19a0b",
"nsfw": false
}
Bulk-reorder channels
PATCH/api/v1/guilds/{guild_id}/channels
Parameter
Request-Body
array of ChannelPositionEntry
Beispiel-Aufruf
curl -X PATCH https://api.speakspeak.net/api/v1/guilds/{guild_id}/channels \
-H "Authorization: Bot ssbot_<app>.<secret>" \
-H "Content-Type: application/json" \
-d '[
{
"id": "019cebb0-9828-74b0-a9d7-788aa3f24c5d",
"position": 0,
"parent_id": "019cebaf-7330-71f7-a8c3-344dd2e19a0b"
},
{
"id": "01a01952-a228-70d2-b9ac-266ff5b46e7f",
"position": 1,
"parent_id": "019cebaf-7330-71f7-a8c3-344dd2e19a0b"
}
]'
Antworten
Get a channel
GET/api/v1/channels/{channel_id}
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/channels/{channel_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Update a channel
PATCH/api/v1/channels/{channel_id}
Parameter
Request-Body
UpdateChannelBody
Beispiel-Aufruf
curl -X PATCH https://api.speakspeak.net/api/v1/channels/{channel_id} \
-H "Authorization: Bot ssbot_<app>.<secret>" \
-H "Content-Type: application/json" \
-d '{"name": "help-desk", "topic": "Questions and support"}'
Antworten
# Antwort 200
{
"id": "01a01952-a228-70d2-b9ac-266ff5b46e7f",
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"type": 0,
"name": "help-desk",
"topic": "Questions and support",
"position": 2,
"parent_id": "019cebaf-7330-71f7-a8c3-344dd2e19a0b",
"nsfw": false
}
Delete a channel
DELETE/api/v1/channels/{channel_id}
Parameter
Beispiel-Aufruf
curl -X DELETE https://api.speakspeak.net/api/v1/channels/{channel_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Nachrichten
List messages
GET/api/v1/channels/{channel_id}/messages
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/channels/{channel_id}/messages \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
# Antwort 200
[
{
"id": "01a01949-a701-745b-83ef-599cd8e7910b",
"channel_id": "019cebb0-9828-74b0-a9d7-788aa3f24c5d",
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"author": {
"id": "019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"username": "alice#2044",
"discriminator": "0",
"global_name": "alice#2044",
"avatar": "/api/v1/avatars/019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"bot": false
},
"content": "Anyone else seeing lag on the EU voice nodes? Log attached.",
"timestamp": "2026-08-19T09:10:52.417306Z",
"edited_timestamp": null,
"attachments": [
{
"id": "01a01949-a178-767d-a501-7bbefa09b324",
"filename": "voice-debug.log",
"content_type": "text/plain",
"size": 48213,
"url": null,
"proxy_url": null
}
],
"embeds": [],
"mentions": [],
"mention_roles": [],
"mention_everyone": false,
"pinned": false,
"type": 0,
"flags": 0
},
{
"id": "01a01944-8c6d-71b2-9c3d-4e5f60718293",
"channel_id": "019cebb0-9828-74b0-a9d7-788aa3f24c5d",
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"author": {
"id": "019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"username": "alice#2044",
"discriminator": "0",
"global_name": "alice#2044",
"avatar": "/api/v1/avatars/019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"bot": false
},
"content": "gg everyone, that was a clean run",
"timestamp": "2026-08-19T09:05:17.933481Z",
"edited_timestamp": null,
"attachments": [],
"embeds": [],
"mentions": [],
"mention_roles": [],
"mention_everyone": false,
"pinned": false,
"type": 0,
"flags": 0
}
]
Send a message
POST/api/v1/channels/{channel_id}/messages
Two request forms:
application/json — content and/or embeds.
multipart/form-data — Discord's one-request file send: a payload_json part (the same JSON message object; optional — files only is a valid message) plus files[0]…files[n] parts. Caps are server-configured (defaults: 8 MiB per file, 10 files per message); exceeding them is a 400 code 40005. Uploads count against the attachments.upload bucket (10 / 60 s per bot).
Embed limits: at most 10 embeds; title ≤ 256, description ≤ 4096, field name ≤ 256, field value ≤ 1024, footer text ≤ 2048, author name ≤ 256 characters.
Parameter
Request-Body
CreateMessageBody
object (multipart/form-data)
Beispiel-Aufruf
curl -X POST https://api.speakspeak.net/api/v1/channels/{channel_id}/messages \
-H "Authorization: Bot ssbot_<app>.<secret>" \
-H "Content-Type: application/json" \
-d '{
"content": "Build 2103 is live. Changelog below.",
"message_reference": {
"message_id": "01a01949-a701-745b-83ef-599cd8e7910b"
},
"embeds": [
{
"title": "Build 2103",
"description": "Desktop build 2103 is rolling out now.",
"color": 3066993,
"footer": {
"text": "CI run 88"
},
"fields": [
{
"name": "Platform",
"value": "Linux x64",
"inline": true
},
{
"name": "Duration",
"value": "4m12s",
"inline": true
}
]
}
]
}'
Antworten
# Antwort 201
{
"id": "01a0194d-0fa4-756c-94f0-6aade9f8a213",
"channel_id": "019cebb0-9828-74b0-a9d7-788aa3f24c5d",
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"author": {
"id": "019e8232-90d4-70aa-8f3c-2d94bb1e6620",
"username": "diceroller#4102",
"discriminator": "0",
"global_name": "diceroller#4102",
"avatar": null,
"bot": true
},
"content": "Build 2103 is live. Changelog below.",
"timestamp": "2026-08-19T09:14:35.812416Z",
"edited_timestamp": null,
"attachments": [],
"embeds": [
{
"type": "rich",
"title": "Build 2103",
"description": "Desktop build 2103 is rolling out now.",
"color": 3066993,
"footer": {
"text": "CI run 88"
},
"fields": [
{
"name": "Platform",
"value": "Linux x64",
"inline": true
},
{
"name": "Duration",
"value": "4m12s",
"inline": true
}
]
}
],
"mentions": [],
"mention_roles": [],
"mention_everyone": false,
"pinned": false,
"type": 0,
"flags": 0
}
Get a message
GET/api/v1/channels/{channel_id}/messages/{message_id}
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/channels/{channel_id}/messages/{message_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Edit a message
PATCH/api/v1/channels/{channel_id}/messages/{message_id}
Parameter
Request-Body
UpdateMessageBody
Beispiel-Aufruf
curl -X PATCH https://api.speakspeak.net/api/v1/channels/{channel_id}/messages/{message_id} \
-H "Authorization: Bot ssbot_<app>.<secret>" \
-H "Content-Type: application/json" \
-d '{"content": "Build 2103 is live. Changelog pinned."}'
Antworten
# Antwort 200
{
"id": "01a0194d-0fa4-756c-94f0-6aade9f8a213",
"channel_id": "019cebb0-9828-74b0-a9d7-788aa3f24c5d",
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"author": {
"id": "019e8232-90d4-70aa-8f3c-2d94bb1e6620",
"username": "diceroller#4102",
"discriminator": "0",
"global_name": "diceroller#4102",
"avatar": null,
"bot": true
},
"content": "Build 2103 is live. Changelog pinned.",
"timestamp": "2026-08-19T09:14:35.812416Z",
"edited_timestamp": "2026-08-19T09:16:02.145087Z",
"attachments": [],
"embeds": [
{
"type": "rich",
"title": "Build 2103",
"description": "Desktop build 2103 is rolling out now.",
"color": 3066993,
"footer": {
"text": "CI run 88"
},
"fields": [
{
"name": "Platform",
"value": "Linux x64",
"inline": true
},
{
"name": "Duration",
"value": "4m12s",
"inline": true
}
]
}
],
"mentions": [],
"mention_roles": [],
"mention_everyone": false,
"pinned": false,
"type": 0,
"flags": 0
}
Delete a message
DELETE/api/v1/channels/{channel_id}/messages/{message_id}
Counts against the destructive throttle (5 / 10 s per guild).
Parameter
Beispiel-Aufruf
curl -X DELETE https://api.speakspeak.net/api/v1/channels/{channel_id}/messages/{message_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Trigger a typing indicator
POST/api/v1/channels/{channel_id}/typing
Parameter
Beispiel-Aufruf
curl -X POST https://api.speakspeak.net/api/v1/channels/{channel_id}/typing \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Reaktionen
Add a reaction
PUT/api/v1/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me
{emoji} is either a Unicode emoji (URL-encoded) or a custom emoji as name:emoji_id (Discord's convention; the id is a UUID).
Parameter
Beispiel-Aufruf
curl -X PUT https://api.speakspeak.net/api/v1/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Remove own reaction
DELETE/api/v1/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me
Parameter
Beispiel-Aufruf
curl -X DELETE https://api.speakspeak.net/api/v1/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Pins
List pinned messages
GET/api/v1/channels/{channel_id}/pins
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/channels/{channel_id}/pins \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Pin a message
PUT/api/v1/channels/{channel_id}/pins/{message_id}
Parameter
Beispiel-Aufruf
curl -X PUT https://api.speakspeak.net/api/v1/channels/{channel_id}/pins/{message_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Unpin a message
DELETE/api/v1/channels/{channel_id}/pins/{message_id}
Parameter
Beispiel-Aufruf
curl -X DELETE https://api.speakspeak.net/api/v1/channels/{channel_id}/pins/{message_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Mitglieder
List guild members
GET/api/v1/guilds/{guild_id}/members
Returns the member list. No limit/after query parameters in the current phase — the full CS member list is returned.
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/guilds/{guild_id}/members \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
# Antwort 200
[
{
"user": {
"id": "019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"username": "alice#2044",
"discriminator": "0",
"global_name": "alice#2044",
"avatar": "/api/v1/avatars/019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"bot": false
},
"nick": "Ali",
"roles": [
"019d0c59-dc88-723f-a1cd-377ab6c57f80"
],
"joined_at": "2026-03-14T09:30:00.184920Z",
"deaf": false,
"mute": false
},
{
"user": {
"id": "019e8232-90d4-70aa-8f3c-2d94bb1e6620",
"username": "diceroller#4102",
"discriminator": "0",
"global_name": "diceroller#4102",
"avatar": null,
"bot": true
},
"nick": null,
"roles": [],
"joined_at": "2026-06-01T08:00:14.062771Z",
"deaf": false,
"mute": false
}
]
Get a guild member
GET/api/v1/guilds/{guild_id}/members/{user_id}
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/guilds/{guild_id}/members/{user_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Update a member (nick, roles, timeout)
PATCH/api/v1/guilds/{guild_id}/members/{user_id}
communication_disabled_until is echoed back in this PATCH response only (as in the example) — CS's member read carries no timeout column, so the field never appears on GET responses.
Parameter
Request-Body
UpdateMemberBody
Beispiel-Aufruf
curl -X PATCH https://api.speakspeak.net/api/v1/guilds/{guild_id}/members/{user_id} \
-H "Authorization: Bot ssbot_<app>.<secret>" \
-H "Content-Type: application/json" \
-d '{
"nick": "Speedrun Sam",
"roles": [
"019d0c59-dc88-723f-a1cd-377ab6c57f80"
],
"communication_disabled_until": "2026-08-19T21:00:00Z"
}'
Antworten
# Antwort 200
{
"user": {
"id": "019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"username": "alice#2044",
"discriminator": "0",
"global_name": "alice#2044",
"avatar": "/api/v1/avatars/019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"bot": false
},
"nick": "Speedrun Sam",
"roles": [
"019d0c59-dc88-723f-a1cd-377ab6c57f80"
],
"joined_at": "2026-03-14T09:30:00.184920Z",
"deaf": false,
"mute": false,
"communication_disabled_until": "2026-08-19T21:00:00Z"
}
Kick a member
DELETE/api/v1/guilds/{guild_id}/members/{user_id}
Counts against the destructive throttle (5 / 10 s per guild).
Parameter
Beispiel-Aufruf
curl -X DELETE https://api.speakspeak.net/api/v1/guilds/{guild_id}/members/{user_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Add a role to a member
PUT/api/v1/guilds/{guild_id}/members/{user_id}/roles/{role_id}
Parameter
Beispiel-Aufruf
curl -X PUT https://api.speakspeak.net/api/v1/guilds/{guild_id}/members/{user_id}/roles/{role_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Remove a role from a member
DELETE/api/v1/guilds/{guild_id}/members/{user_id}/roles/{role_id}
Parameter
Beispiel-Aufruf
curl -X DELETE https://api.speakspeak.net/api/v1/guilds/{guild_id}/members/{user_id}/roles/{role_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Rollen
List guild roles
GET/api/v1/guilds/{guild_id}/roles
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/guilds/{guild_id}/roles \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
# Antwort 200
[
{
"id": "019cebae-6208-7c4d-8e11-23ab45cd67ef",
"name": "Members",
"color": 0,
"hoist": false,
"position": 0,
"permissions": "3072",
"mentionable": false,
"managed": false
},
{
"id": "019d0c59-dc88-723f-a1cd-377ab6c57f80",
"name": "Moderators",
"color": 15105570,
"hoist": true,
"position": 1,
"permissions": "8522776",
"mentionable": true,
"managed": false
}
]
Create a role
POST/api/v1/guilds/{guild_id}/roles
Parameter
Request-Body
CreateRoleBody
Beispiel-Aufruf
curl -X POST https://api.speakspeak.net/api/v1/guilds/{guild_id}/roles \
-H "Authorization: Bot ssbot_<app>.<secret>" \
-H "Content-Type: application/json" \
-d '{
"name": "Helpers",
"permissions": "134144",
"color": 3447003,
"hoist": true,
"mentionable": false
}'
Antworten
# Antwort 201
{
"id": "01a01956-a198-734a-92de-488bc7d6809a",
"name": "Helpers",
"color": 3447003,
"hoist": true,
"position": 2,
"permissions": "134144",
"mentionable": false,
"managed": false
}
Bulk-reorder roles
PATCH/api/v1/guilds/{guild_id}/roles
Parameter
Request-Body
array of RolePositionEntry
Beispiel-Aufruf
curl -X PATCH https://api.speakspeak.net/api/v1/guilds/{guild_id}/roles \
-H "Authorization: Bot ssbot_<app>.<secret>" \
-H "Content-Type: application/json" \
-d '[
{
"id": "01a01956-a198-734a-92de-488bc7d6809a",
"position": 1
},
{
"id": "019d0c59-dc88-723f-a1cd-377ab6c57f80",
"position": 2
}
]'
Antworten
# Antwort 200
[
{
"id": "019cebae-6208-7c4d-8e11-23ab45cd67ef",
"name": "Members",
"color": 0,
"hoist": false,
"position": 0,
"permissions": "3072",
"mentionable": false,
"managed": false
},
{
"id": "01a01956-a198-734a-92de-488bc7d6809a",
"name": "Helpers",
"color": 3447003,
"hoist": true,
"position": 1,
"permissions": "134144",
"mentionable": false,
"managed": false
},
{
"id": "019d0c59-dc88-723f-a1cd-377ab6c57f80",
"name": "Moderators",
"color": 15105570,
"hoist": true,
"position": 2,
"permissions": "8522776",
"mentionable": true,
"managed": false
}
]
Update a role
PATCH/api/v1/guilds/{guild_id}/roles/{role_id}
Parameter
Request-Body
UpdateRoleBody
Beispiel-Aufruf
curl -X PATCH https://api.speakspeak.net/api/v1/guilds/{guild_id}/roles/{role_id} \
-H "Authorization: Bot ssbot_<app>.<secret>" \
-H "Content-Type: application/json" \
-d '{"permissions": "134152", "mentionable": true}'
Antworten
# Antwort 200
{
"id": "01a01956-a198-734a-92de-488bc7d6809a",
"name": "Helpers",
"color": 3447003,
"hoist": true,
"position": 1,
"permissions": "134152",
"mentionable": true,
"managed": false
}
Delete a role
DELETE/api/v1/guilds/{guild_id}/roles/{role_id}
Parameter
Beispiel-Aufruf
curl -X DELETE https://api.speakspeak.net/api/v1/guilds/{guild_id}/roles/{role_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Bans
List bans
GET/api/v1/guilds/{guild_id}/bans
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/guilds/{guild_id}/bans \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
# Antwort 200
[
{
"reason": "spamming invite links",
"user": {
"id": "019ba915-e91a-751b-8bd0-c44f1a9c2731",
"username": "spamlord#9313",
"discriminator": "0",
"global_name": "spamlord#9313",
"avatar": null,
"bot": false
}
}
]
Get a ban
GET/api/v1/guilds/{guild_id}/bans/{user_id}
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/guilds/{guild_id}/bans/{user_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Ban a user
PUT/api/v1/guilds/{guild_id}/bans/{user_id}
The ban reason is taken from the X-Audit-Log-Reason request header (Discord's convention). delete_message_seconds is not supported.
Parameter
Beispiel-Aufruf
curl -X PUT https://api.speakspeak.net/api/v1/guilds/{guild_id}/bans/{user_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Remove a ban
DELETE/api/v1/guilds/{guild_id}/bans/{user_id}
Parameter
Beispiel-Aufruf
curl -X DELETE https://api.speakspeak.net/api/v1/guilds/{guild_id}/bans/{user_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Emojis
List guild emojis
GET/api/v1/guilds/{guild_id}/emojis
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/guilds/{guild_id}/emojis \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
# Antwort 200
[
{
"id": "019f22bc-5df0-778e-b612-8cc01b1ac435",
"name": "pog",
"roles": [],
"user": null,
"require_colons": true,
"managed": false,
"animated": false,
"available": true
}
]
Get an emoji
GET/api/v1/guilds/{guild_id}/emojis/{emoji_id}
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/guilds/{guild_id}/emojis/{emoji_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Delete an emoji
DELETE/api/v1/guilds/{guild_id}/emojis/{emoji_id}
Emoji creation is not available over the bot API (upload flow).
Parameter
Beispiel-Aufruf
curl -X DELETE https://api.speakspeak.net/api/v1/guilds/{guild_id}/emojis/{emoji_id} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Einladungen
Create an invite
POST/api/v1/channels/{channel_id}/invites
SpeakSpeak invites are server-scoped: the channel resolves to its guild and a guild-wide invite is created (channel_id on the result is always null). Note in the example that the requested max_age comes back as a resolved expires_at timestamp, and max_age on the result is always null.
Parameter
Request-Body
CreateInviteBody
Beispiel-Aufruf
curl -X POST https://api.speakspeak.net/api/v1/channels/{channel_id}/invites \
-H "Authorization: Bot ssbot_<app>.<secret>" \
-H "Content-Type: application/json" \
-d '{"max_uses": 25, "max_age": 86400}'
Antworten
# Antwort 201
{
"code": "Xk3qTz9wLmPa",
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"channel_id": null,
"inviter": null,
"uses": 0,
"max_uses": 25,
"max_age": null,
"temporary": false,
"expires_at": "2026-08-20T09:22:10.317502Z",
"created_at": "2026-08-19T09:22:10.318204Z"
}
Delete an invite
DELETE/api/v1/invites/{code}
Parameter
Beispiel-Aufruf
curl -X DELETE https://api.speakspeak.net/api/v1/invites/{code} \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
Audit-Log
List audit-log entries
GET/api/v1/guilds/{guild_id}/audit-logs
Only actions with an exact Discord equivalent are returned (MEMBER_KICK=20, MEMBER_BAN_ADD=22, MEMBER_BAN_REMOVE=23); SpeakSpeak-only actions are omitted rather than mapped to a wrong Discord action_type. users contains the *acting* users only — targets are referenced by target_id and resolved separately.
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/guilds/{guild_id}/audit-logs \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
# Antwort 200
{
"audit_log_entries": [
{
"id": "019ff577-dc88-7bc2-ba56-2a045f5e0879",
"action_type": 22,
"user_id": "019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"target_id": "019ba915-e91a-751b-8bd0-c44f1a9c2731",
"reason": "spamming invite links",
"changes": [],
"options": null
},
{
"id": "019ff26b-67a8-7ab1-a945-1ff34e4df768",
"action_type": 20,
"user_id": "019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"target_id": "019ba915-e91a-751b-8bd0-c44f1a9c2731",
"reason": "repeated spam after warning",
"changes": [],
"options": null
}
],
"users": [
{
"id": "019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"username": "alice#2044",
"discriminator": "0",
"global_name": "alice#2044",
"avatar": "/api/v1/avatars/019a4a18-bfd9-73c1-9aa4-7b0d24e19af5",
"bot": false
}
]
}
Webhooks
Get webhook info (token-authenticated)
GET/api/v1/webhooks/{webhook_id}/{token}ohne Authentifizierung
Public route — the credential is the token in the URL. Rate-limited per webhook (30 / 60 s) and per source IP (120 / 60 s).
Parameter
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/webhooks/{webhook_id}/{token}
Antworten
# Antwort 200
{
"id": "019fa962-42e8-789f-8723-9dd12c2bd546",
"type": 1,
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"channel_id": "019cebb0-9828-74b0-a9d7-788aa3f24c5d",
"name": "Deploys",
"avatar": null,
"application_id": null
}
Execute an incoming webhook
POST/api/v1/webhooks/{webhook_id}/{token}ohne Authentifizierung
Public route — the credential is the token in the URL. Body limit 8 KiB, JSON only (no multipart). content ≤ 2000 characters, username override ≤ 80. There are no *outgoing* webhooks in SpeakSpeak, so there is no signature scheme to verify.
Parameter
Request-Body
WebhookExecuteBody
Beispiel-Aufruf
curl -X POST https://api.speakspeak.net/api/v1/webhooks/{webhook_id}/{token} \
-H "Content-Type: application/json" \
-d '{
"content": "gip deployed: build 2103, all checks green",
"username": "CI Status"
}'
Antworten
# Antwort 200
{
"id": "01a0195b-5584-70e1-8f20-31425364758a",
"channel_id": "019cebb0-9828-74b0-a9d7-788aa3f24c5d",
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"author": {
"id": "019fa962-42fc-7a1b-9c2d-3e4f50617283",
"username": "CI Status",
"discriminator": "0",
"global_name": "CI Status",
"avatar": null,
"bot": true
},
"content": "gip deployed: build 2103, all checks green",
"timestamp": "2026-08-19T09:30:11.204863Z",
"edited_timestamp": null,
"attachments": [],
"embeds": [],
"mentions": [],
"mention_roles": [],
"mention_everyone": false,
"pinned": false,
"type": 0,
"flags": 0
}
Interaktionen
Respond to an interaction
POST/api/v1/interactions/{interaction_id}/{token}/callbackohne Authentifizierung
Public route — the credential is the single-use ssint_… token in the URL. Body limit 16 KiB. type 4 = immediate channel message (default), 5 = deferred, 9 = modal (data is then {custom_id,title,components}). For type 4, data.flags bit 6 (EPHEMERAL, 64) is honoured. Rate-limited per source IP (120 / 60 s). The interaction token expires after its TTL (at most 15 minutes).
Parameter
Request-Body
InteractionCallbackBody
Beispiel-Aufruf
curl -X POST https://api.speakspeak.net/api/v1/interactions/{interaction_id}/{token}/callback \
-H "Content-Type: application/json" \
-d '{
"type": 4,
"data": {
"content": "You rolled a 17.",
"flags": 64
}
}'
Antworten
Create an interaction follow-up message
POST/api/v1/webhooks/{app_id}/{token}/messagesohne Authentifizierung
Public route — same ssint_… interaction token. Note the explicit /messages tail: this deliberately does not reuse Discord's bare POST /webhooks/{app_id}/{token} shape (which would collide with webhook execute). Body limit 16 KiB. Rate-limited per source IP (120 / 60 s).
Parameter
Request-Body
FollowupBody
Beispiel-Aufruf
curl -X POST https://api.speakspeak.net/api/v1/webhooks/{app_id}/{token}/messages \
-H "Content-Type: application/json" \
-d '{
"content": "Roll breakdown: d20 result 14, modifier 3, total 17."
}'
Antworten
Edit the original interaction response
PATCH/api/v1/webhooks/{app_id}/{token}/messages/@originalohne Authentifizierung
Public route — same ssint_… interaction token. @original does not exist for an ephemeral or not-yet-sent response (404).
Parameter
Request-Body
FollowupBody
Beispiel-Aufruf
curl -X PATCH https://api.speakspeak.net/api/v1/webhooks/{app_id}/{token}/messages/@original \
-H "Content-Type: application/json" \
-d '{"content": "Updated result: natural 20."}'
Antworten
Delete the original interaction response
DELETE/api/v1/webhooks/{app_id}/{token}/messages/@originalohne Authentifizierung
Parameter
Beispiel-Aufruf
curl -X DELETE https://api.speakspeak.net/api/v1/webhooks/{app_id}/{token}/messages/@original
Antworten
Gateway-Verbindung
Gateway WebSocket upgrade
GET/api/v1/gatewayohne Authentifizierung
WebSocket endpoint (documented here as the HTTP upgrade request). No Authorization header — the bot authenticates in-band with IDENTIFY (opcode 2) carrying its token and intents. See the top-level description for opcodes, close codes, RESUME and the 2-concurrent-sessions-per-application cap.
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/gateway
Antworten
Gateway connection info (authenticated)
GET/api/v1/gateway/bot
Beispiel-Aufruf
curl https://api.speakspeak.net/api/v1/gateway/bot \
-H "Authorization: Bot ssbot_<app>.<secret>"
Antworten
# Antwort 200
{
"url": "wss://api.speakspeak.net/api/v1/gateway",
"shards": 1,
"session_start_limit": {
"total": 1000,
"remaining": 1000,
"reset_after": 86400000,
"max_concurrency": 1
}
}
OAuth2 & Installation
Bot-install metadata lookup
GET/api/v1/oauth2/authorizeohne Authentifizierung
Public (no auth) — client_id is a public identifier, as on Discord. Returns what the install UI needs to render the consent screen. The actual install is completed in the SpeakSpeak client via the returned install_endpoint.
Parameter
Beispiel-Aufruf
curl "https://api.speakspeak.net/api/v1/oauth2/authorize?client_id=<client_id>&scope=<scope>"
Antworten
# Antwort 200
{
"application": {
"app_id": "019e8230-9374-777e-9d51-c20aa4b3f9c1",
"name": "Dice Roller",
"icon_url": null
},
"requested_permissions": "3072",
"guild_id": "019cebae-61c0-72d0-9be5-566cc17d0442",
"install_endpoint": "/api/v1/applications/019e8230-9374-777e-9d51-c20aa4b3f9c1/install"
}
Objekte
Error
Discord-shaped error body.
RateLimitError
The 429 body (Discord's shape — no code field).
User
Guild
Channel
GuildMember
Role
Ban
Emoji
Message
Attachment
Embed
Discord-shaped embed. type is rich (bot/webhook-authored) or link (URL unfurl). Image/thumbnail url values are null (same presign gap as attachments).
Invite
AuditLog
AuditLogEntry
Webhook
GatewayBotInfo
ApplicationSummary
AuthorizeResponse
CreateMessageBody
UpdateMessageBody
CreateChannelBody
UpdateChannelBody
Absent fields (and explicit null) mean "unchanged".
ChannelPositionEntry
CreateRoleBody
UpdateRoleBody
RolePositionEntry
UpdateMemberBody
CreateInviteBody
WebhookExecuteBody
InteractionCallbackBody
FollowupBody
Fragen & Feedback
Die Bot-API ist in der öffentlichen Beta und wird erweitert. Fragen, Feedback oder ein Bibliotheks-Wunsch? Schreib an contact@speakspeak.net.