Discord API
Send messages, embeds, polls, forum posts, and threads to Discord servers with Zernio API - No bot hosting, no gateway, no intents approval
Quick Reference
| Property | Value |
|---|---|
| Content limit | 2,000 characters (message content) |
| Embeds per message | 10 (max 6,000 chars total) |
| Images per message | Up to 10 attachments |
| Image formats | JPEG, PNG, GIF, WebP |
| Image max size | 25 MB (higher on boosted servers) |
| Video formats | MP4, MOV, WebM |
| Video max size | 25 MB (up to 500 MB on boosted servers) |
| Post types | Messages, Embeds, Polls, Forum Posts, Threads |
| Scheduling | Yes |
| Inbox (DMs) | No |
| Inbox (Comments) | No |
| Analytics | No |
Before You Start
Discord integration uses a centralized bot token model. You do NOT need to create a Discord Application, request privileged intents, or host a gateway connection. You add the Zernio bot to your server via OAuth and POST to our REST API.
Key points:
- No bot hosting required - we manage the bot infrastructure
- No intents approval - MESSAGE_CONTENT and other privileged intents are handled at the bot level
- No gateway/sharding - you never connect a WebSocket; everything is REST
- The bot needs: Send Messages, Embed Links, Attach Files, Send Messages in Threads, Create Public Threads permissions (granted at install time)
Quick Start
Send a message to a Discord channel:
const { post } = await zernio.posts.createPost({
content: 'Hello from Zernio API!',
platforms: [
{
platform: 'discord',
accountId: 'YOUR_ACCOUNT_ID',
platformSpecificData: {
channelId: '1234567890'
}
}
],
publishNow: true
});
console.log('Posted to Discord!', post._id);result = client.posts.create_post(
content="Hello from Zernio API!",
platforms=[
{
"platform": "discord",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"channelId": "1234567890"
}
}
],
publish_now=True,
)
print(f"Posted to Discord! {result.post['_id']}")curl -X POST https://zernio.com/api/v1/posts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Hello from Zernio API!",
"platforms": [
{
"platform": "discord",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"channelId": "1234567890"
}
}
],
"publishNow": true
}'Connection
Discord uses OAuth2 with our centralized bot:
- Call
GET /v1/connect/discord?profileId=YOUR_PROFILE_IDto get the bot invite URL - The user authorizes the bot to join their server
- After authorization, the user selects which channel to post to via
/connect/discord/select-channel - The connected account appears in
GET /v1/accounts
Each connected account represents one Discord server. The channelId in platformSpecificData determines which channel receives the message.
Webhook Identity (Bot Customization)
By default, messages are posted as "Zernio" with the bot's avatar. You can customize the display name and avatar at two levels:
Account-level default (applies to every post from this account):
curl -X PATCH https://zernio.com/api/v1/connect/discord \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"accountId": "YOUR_ACCOUNT_ID",
"webhookUsername": "My Brand",
"webhookAvatarUrl": "https://example.com/logo.png"
}'Per-post override (overrides account default for a single post):
{
"platforms": [{
"platform": "discord",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"channelId": "1234567890",
"webhookUsername": "Special Announcement",
"webhookAvatarUrl": "https://example.com/special-logo.png"
}
}],
"publishNow": true
}Webhook usernames must be 1-80 characters and cannot contain "clyde" or "discord". Send an empty string to reset to the default ("Zernio").
Embeds
Send rich embedded content alongside or instead of plain text:
{
"content": "New release shipping today!",
"platforms": [{
"platform": "discord",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"channelId": "1234567890",
"embeds": [{
"title": "v2.3.0 Release Notes",
"description": "Dark mode, new API endpoints, faster uploads.",
"color": 5814783,
"url": "https://example.com/changelog",
"footer": { "text": "Shipped today" },
"fields": [
{ "name": "New Features", "value": "3", "inline": true },
{ "name": "Bug Fixes", "value": "12", "inline": true }
]
}]
}
}],
"publishNow": true
}Each message supports up to 10 embeds with a combined character limit of 6,000 across all embed fields.
Native Polls
Create Discord-native polls (same UX as the Discord client):
{
"platforms": [{
"platform": "discord",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"channelId": "1234567890",
"poll": {
"question": { "text": "Ship it now or wait until Monday?" },
"answers": [
{ "poll_media": { "text": "Ship now" } },
{ "poll_media": { "text": "Wait for Monday" } }
],
"duration": 24,
"allow_multiselect": false
}
}
}],
"publishNow": true
}| Poll Property | Value |
|---|---|
| Max answers | 10 |
| Duration range | 1 - 768 hours (32 days) |
| Default duration | 24 hours |
| Multi-select | Optional (default: false) |
Polls are standalone messages. You cannot combine a poll with media attachments in the same message (Discord API limitation).
Forum Posts
Post starter messages to forum channels (type 15):
{
"content": "Community call notes for January 15",
"platforms": [{
"platform": "discord",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"channelId": "9999999999",
"forumThreadName": "Community Call - Jan 15",
"forumAppliedTags": ["11111111", "22222222"]
}
}],
"publishNow": true
}forumThreadName(required for forum channels) becomes the thread titleforumAppliedTagsare snowflake IDs of existing forum tags (max 5 tags per post)- Use
listForumTags(channelId)to discover available tags
Threads
Create a follow-up thread under any published message:
{
"content": "Main announcement here",
"platforms": [{
"platform": "discord",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"channelId": "1234567890",
"threadFromMessage": {
"name": "Discussion Thread",
"autoArchiveDuration": 1440,
"rateLimitPerUser": 0
}
}
}],
"publishNow": true
}autoArchiveDuration options: 60, 1440 (1 day), 4320 (3 days), or 10080 (7 days) minutes. rateLimitPerUser sets slow-mode in seconds (0-21600).
Announcement Crosspost
Auto-crosspost messages from announcement channels (type 5) so followers in other servers receive them:
{
"platformSpecificData": {
"channelId": "ANNOUNCEMENT_CHANNEL_ID",
"crosspost": true
}
}This is a no-op for regular text channels.
Edit & Delete
- Edit:
PUT /v1/posts/{postId}updates the Discord message content and embeds - Delete:
DELETE /v1/posts/{postId}deletes the Discord message or cancels a scheduled one
Rate Limits
Discord applies per-channel, per-guild, and global rate limits. Zernio handles 429 responses with exponential backoff and respects the X-RateLimit-Reset-After header automatically. You never need to implement retry logic.
platformSpecificData Reference
| Field | Type | Required | Description |
|---|---|---|---|
channelId | string | Yes | Target channel snowflake ID |
embeds | array | No | Up to 10 Discord embed objects (6,000 chars total) |
poll | object | No | Native poll (question, answers, duration). Cannot combine with media |
crosspost | boolean | No | Auto-crosspost in announcement channels |
forumThreadName | string | Forum channels | Thread title for forum starter message |
forumAppliedTags | string[] | No | Tag snowflake IDs for forum posts (max 5) |
threadFromMessage | object | No | Create a thread under the published message |
threadFromMessage.rateLimitPerUser | number | No | Slow-mode seconds for thread (0-21600) |
tts | boolean | No | Text-to-speech message |
webhookUsername | string | No | Override display name for this post (1-80 chars) |
webhookAvatarUrl | string | No | Override avatar URL for this post |
Channel Management
List available channels in the connected guild:
const { channels } = await zernio.discord.getDiscordChannels({
path: { accountId: 'YOUR_ACCOUNT_ID' },
});res = client.discord.get_discord_channels(account_id="YOUR_ACCOUNT_ID")curl https://zernio.com/api/v1/accounts/YOUR_ACCOUNT_ID/discord-channels \
-H "Authorization: Bearer YOUR_API_KEY"Switch the connected channel:
curl -X PATCH https://zernio.com/api/v1/connect/discord \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"accountId": "YOUR_ACCOUNT_ID",
"channelId": "NEW_CHANNEL_ID"
}'Only text (0), announcement (5), and forum (15) channels are supported. A new webhook is automatically created in the target channel.
Related Endpoints
- Connect Discord Account - OAuth flow and bot installation
- Create Post - Post creation and scheduling
- Discord Settings - Update webhook identity and switch channels
- Discord Channels - List guild channels