# OmniSocials Discord API

> Post to your Discord channel with one REST call, through the channel’s own webhook: text, images and videos, polls, link buttons and forum posts. No bot to add or host. Schedule posts, then read the reactions per emoji and the poll votes.

This is the machine-readable version of [omnisocials.com/discord-api](https://omnisocials.com/discord-api), maintained for AI agents. Facts checked against the OmniSocials app and API on October 22, 2026. Platform reference: [docs.omnisocials.com/platforms/discord](https://docs.omnisocials.com/platforms/discord). API reference: [docs.omnisocials.com/api](https://docs.omnisocials.com/api).

## Basics

- Base URL: `https://api.omnisocials.com/v1`
- Auth: `Authorization: Bearer omsk_live_...`. One key belongs to one workspace. Keys are created in the app under Settings, API.
- Channel id in `channels` (the same field as `accounts`): `discord`. The account connects inside the OmniSocials app, not through the API.
- Rate limit: 100 requests per minute per key. A 429 carries `Retry-After`.
- Responses use a `{ "data": ... }` envelope. Create returns `201`.
- Webhooks: `post.scheduled`, `post.published`, `post.failed`, `post.approved`, `post.rejected`, signed with HMAC-SHA256 in `X-OmniSocials-Signature`.

## Skip the work around a webhook

A Discord webhook already posts for free: one POST to its URL. Everything around that call is yours to build: a scheduler and a queue, uploads under Discord’s 20 MB file limit, the poll, button and forum fields, retries when Discord answers 429, reading reactions back and noticing when someone deletes the webhook. OmniSocials does that part.

- On your own: Webhook, Scheduler, Uploads, Big files, Payload, Reactions, Reconnects, Retries, then the first post.
- Fields of Discord’s webhook call your own code builds: `payload_json`, `files[n]`, `attachments`, `flags`, `allowed_mentions`, `components`, `poll`, `thread_name`.
- On OmniSocials: sign in, create an API key, POST. Continue with Discord makes the webhook for you.

## Schedule a post

```bash
curl -X POST https://api.omnisocials.com/v1/posts/create \
  -H "Authorization: Bearer $OMNISOCIALS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "content": "New: Best times to post",
  "channels": ["discord"],
  "media_urls": ["https://cdn.example.com/best-times.png"],
  "discord": {
    "buttons": [
      { "text": "Read the docs",
        "url": "https://docs.omnisocials.com/api/analytics" }
    ]
  },
  "schedule_at": "2026-10-22T18:00:00Z"
}'
```

The answer (`201`, shortened):

```json
{
  "data": {
    "id": "1024",
    "status": "scheduled",
    "app_url": "https://app.omnisocials.com/create-post/1024"
  }
}
```

## Every Discord format, one request

Text, images and videos, polls, link buttons and forum posts share one request shape. OmniSocials checks the post against Discord’s limits before anything is sent, so a post that breaks one fails in your request with the reason.

- **Text and links.** Up to 2,000 characters with Discord’s own Markdown: bold, italic, lists and masked links. Link previews show unless you turn them off. (`content`, `discord.link_preview`)
- **Images and videos.** Up to 10 images, GIFs and videos in one message, mixed as you like. Blur them as a spoiler, or send the message silently. (`media_urls`, `discord.spoiler`, `discord.silent`)
- **Polls, buttons, forum posts.** A native poll whose question is the post text, up to 5 link buttons under the message, or a new forum post with its own title. (`discord.poll`, `discord.buttons`, `discord.thread_name`)

### Text

```json
{
  "content": "What's new: https://omnisocials.com/changelog",
  "channels": ["discord"],
  "discord": { "link_preview": true },
  "schedule_at": "2026-10-23T12:00:00Z"
}
```

### Media

```json
{
  "content": "Sidebar update: new Home and Drafts tabs",
  "channels": ["discord"],
  "media_urls": [
    "https://cdn.example.com/sidebar-1.png",
    "https://cdn.example.com/sidebar-2.png"
  ],
  "discord": { "silent": true },
  "schedule_at": "2026-10-25T10:00:00Z"
}
```

### Poll

```json
{
  "content": "Which channel should we add next?",
  "channels": ["discord"],
  "discord": {
    "poll": {
      "options": ["Tumblr", "WordPress", "Slack"],
      "duration_hours": 48
    }
  },
  "schedule_at": "2026-10-24T11:00:00Z"
}
```

### Buttons

```json
{
  "content": "New: OmniSocials SDKs in 8 languages",
  "channels": ["discord"],
  "discord": {
    "buttons": [
      { "text": "Pick your SDK",
        "url": "https://omnisocials.com/sdk" },
      { "text": "Read the docs",
        "url": "https://docs.omnisocials.com" }
    ]
  },
  "schedule_at": "2026-10-24T15:00:00Z"
}
```

### Forum

```json
{
  "content": "New in OmniSocials: Notable Days",
  "channels": ["discord"],
  "media_urls": [
    "https://cdn.example.com/notable-days.png"
  ],
  "discord": {
    "thread_name": "Release notes: Notable Days"
  },
  "schedule_at": "2026-10-23T16:00:00Z"
}
```

## Every Discord option in one object

Send it silently, keep @everyone from pinging, blur the media, turn off link previews, add link buttons, a poll or a forum post title. The discord object holds them all, and the app shows the same switches.

`POST /v1/posts/create`:

```json
{
  "content": "New: Bluesky threads",
  "channels": ["discord"],
  "media_urls": ["https://cdn.example.com/bluesky-threads.png"],
  "discord": {
    "silent": true,
    "link_preview": true,
    "allow_mentions": false,
    "spoiler": false,
    "buttons": [
      { "text": "Read the docs",
        "url": "https://docs.omnisocials.com/platforms/bluesky" }
    ]
  },
  "schedule_at": "2026-10-22T11:00:00Z"
}
```

- **Mentions stay quiet.** @everyone, @here, roles and users in the text notify nobody unless allow_mentions is true, so a scheduled post never pings a whole server by accident. (`discord.allow_mentions`)
- **Polls and buttons.** A poll takes 2 to 10 answers of up to 55 characters and runs 1 to 768 hours. Up to 5 buttons, labels of up to 80. A poll with buttons fails in your request with 400 validation_error. (`discord.poll`, `discord.buttons`)
- **Forum posts.** In a forum or media channel, thread_name (up to 100 characters) opens a new post with that title. A text channel gets the post without it, and result.warnings says thread_name_ignored. (`discord.thread_name`, `result.thread_id`)

## Big videos, sent as links

A webhook attaches files of up to 20 MB. Send a bigger video, up to 1 GB, and OmniSocials puts a link to it in the message, and Discord shows a player for it. The post then says what went as a link.

`POST /v1/posts/create-and-publish`:

```json
{
  "content": "New: 1GB video uploads\nUpload videos up to 1GB.",
  "channels": ["discord"],
  "media_urls": ["https://cdn.example.com/1gb-uploads.mp4"]
}
```

`GET /v1/posts/1019`:

```json
{
  "data": {
    "id": "1019",
    "status": "published",
    "discord": {
      "result": {
        "message_id": "1562397541700472323",
        "sent_at": "2026-10-21T09:30:02.000Z",
        "video_links": [
          "https://cdn.omnisocials.com/workspace-4127/1gb-uploads.mp4"
        ],
        "link_message_id": null,
        "warnings": ["media_sent_as_links"]
      }
    }
  }
}
```

- **Attached up to 20 MB.** Images, GIFs and videos of up to 20 MB are attached to the message, up to 10 files in one. An image over 20 MB is re-encoded to a JPEG that fits. (`media_urls`)
- **Bigger videos as a link.** A video or GIF over 20 MB, up to 1 GB, goes as a link in the message, and Discord shows a player for it. Links that do not fit in 2,000 characters follow in a second message. (`result.video_links`, `result.link_message_id`)
- **Where it landed.** discord.result holds the message id, when it went out and what was sent differently, such as media_sent_as_links. published_urls.discord links the message for members of the server. (`discord.result`, `published_urls.discord`)

## No bot, one webhook

Continue with Discord and pick the channel on Discord’s own screen, or paste a webhook URL from your server settings. No bot joins your server and no token expires. Then create an API key, and your code posts there.

- **Two ways to connect.** Continue with Discord makes the webhook for you; you need the Manage Server permission. Or paste a webhook URL from Server Settings, Integrations, Webhooks. (`connect_method`)
- **Knows when the webhook is gone.** If someone deletes the webhook or resets its URL, the account reads needs_reconnect with the reason, and you get an email. Reconnect with a new webhook. (`needs_reconnect`, `reauth_reason`)
- **Which server and channel.** The accounts call returns the server and channel ids, the webhook name every post shows as its sender and, with Continue with Discord, the server name. Each workspace connects one channel. (`GET /v1/accounts`, `platform_details`)

`GET /v1/accounts?platform=discord` answers:

```json
{
  "data": [{
    "id": "4127_discord",
    "needs_reconnect": false,
    "platform_details": {
      "guild_id": "1085140816021856279",
      "guild_name": "OmniSocials",
      "channel_id": "1085141723757277195",
      "webhook_name": "OmniSocials Updates",
      "connect_method": "oauth"
    }
  }]
}
```

## Read what Discord gives a webhook

Reactions per emoji and poll votes, read back from your own messages. Discord gives a webhook no views, reach or member counts, so those read N/A in the app and the API leaves them out.

- **Reactions per emoji.** likes is the total of every reaction, reactions the count per emoji, your server’s custom emoji included. (`/analytics/posts/:id`, `reactions`)
- **Poll votes.** The votes per answer and the total, the same numbers the app shows next to the post. (`metrics.poll`)
- **N/A, not zero.** Discord reports no views, reach, replies or members to a webhook, so the app shows N/A there instead of a number it cannot know.

`GET /v1/analytics/posts/1016` answers:

```json
{
  "data": {
    "post_id": "1016",
    "platforms": {
      "discord": {
        "metrics": {
          "likes": 31,
          "reactions": { "👍": 19, "🔥": 12 },
          "poll": {
            "votes_count": 286,
            "options": [
              { "title": "Dark",
                "votes_count": 148 },
              { "title": "System",
                "votes_count": 97 },
              { "title": "Light",
                "votes_count": 41 }
            ]
          }
        }
      }
    }
  }
}
```

## Discord’s rules, in one place

OmniSocials checks every post against them before it reaches Discord, so a post that breaks one fails in your request with the reason, not at publish time.

| Limit | Value |
| --- | --- |
| Text | 2,000 characters, most emoji count 2 |
| Files | Up to 10 per message, mixed |
| Images | Up to 40 MB, re-encoded above 20 MB |
| Videos | MP4, MOV or WebM up to 1 GB |
| Attached | Up to 20 MB, larger goes as a link |
| Poll | 2 to 10 answers of up to 55 characters |
| Poll question | 300 characters, open 1 hour to 32 days |
| Buttons | Up to 5, labels of 1 to 80 characters |
| Forum post title | Up to 100 characters |
| Channels | One channel per workspace |
| Removal | From Discord at any time, in the app |
| Rate limit | 100 requests a minute per API key |

## Your first Discord post in three steps

About five minutes from sign-up to a scheduled post in your channel. Then hand the key to your coding agent.

1. **Create an API key** (`Settings › API`). Start your trial, open Settings, API and create a key. It is shown once.
2. **Connect your channel** (`GET /v1/accounts`). Open Channels, add Discord and press Continue with Discord, or paste a webhook URL. Then list it from your code.
3. **Send your first post** (`POST /v1/posts/create`). Post now with create-and-publish, or add schedule_at to plan it. Add the discord object for buttons, a poll or a forum post title.

## FAQ

### Do I need a Discord bot?

No. OmniSocials posts through the channel’s incoming webhook, so no bot joins your server, there is nothing to host and no token expires. In OmniSocials you open Channels, add Discord and press Continue with Discord, or paste a webhook URL. Your code calls the OmniSocials API with an API key.

### How do I get a Discord webhook URL?

In Discord, open Server Settings, then Integrations, then Webhooks. Press New Webhook, pick the channel and press Copy Webhook URL, then paste it in OmniSocials. With Continue with Discord you skip this: you pick the server and the channel on Discord’s own screen and Discord makes the webhook. You need the Manage Server permission in that server.

### Can I schedule Discord messages through the API?

Yes. Add schedule_at to POST /v1/posts/create and OmniSocials sends the message at that time, or use POST /v1/posts/create-and-publish to send it now. A webhook on its own posts right away and has no schedule. OmniSocials’ own events, post.scheduled and post.published, tell your app when a post is planned and when it is out.

### Whose name and picture do the posts show?

The webhook’s. Discord shows every message under the webhook’s name and picture, and a post from OmniSocials can’t set its own. Change them in Discord, in the webhook’s settings under Server Settings, Integrations, Webhooks. GET /v1/accounts returns the name as platform_details.webhook_name.

### Can I edit a message after it is sent?

No. A sent post can’t be edited through OmniSocials; the API changes draft and scheduled posts only. You can take it down at any time: Delete from Discord on the post in OmniSocials removes the message, and the message with the video links if there is one. Only the webhook that sent a message can remove it, so after a reconnect with a new webhook, remove older posts in Discord yourself. DELETE /posts/{id} removes the post from OmniSocials only.

### Does OmniSocials read my server?

No. A webhook can only post to its one channel and read back the messages it sent itself. OmniSocials reads those for their reactions and poll votes, and never sees the server’s other channels, its members or anyone’s messages, which is also why Discord is not in the Social Inbox. Continue with Discord reads the server’s name and icon once, when you connect.

### What happens when someone deletes the webhook?

Posts to the channel stop, each with a message that says why, and GET /v1/accounts shows needs_reconnect: true with the reason “The webhook was deleted in Discord”. Resetting the webhook’s URL in Discord does the same. You get an email. Reconnect the channel in OmniSocials: Continue with Discord makes a new webhook, or paste the URL of a new one.

### Can my AI agent post to Discord?

Yes, through the hosted MCP server. create_post, create_and_publish_post and update_post take the same discord options, get_post shows where the message landed and get_post_analytics returns the reaction total.

### Is the Discord API free?

Yes. Discord charges nothing for its API, and a webhook needs no bot and no sign-in to post to its channel. What it leaves to you is everything around the post: a scheduler, file uploads, the poll and button fields, retries and reading reactions back. With OmniSocials, Discord is part of the plan, $10 per seat per month billed annually, and posting to it uses no credits.

### How much does OmniSocials cost?

One plan with every feature included: $10 per seat per month billed annually, or $12 billed monthly. Team members and client seats cost the same. Every account starts with a 14-day free trial.

The REST API, the SDKs, the CLI, webhooks and the MCP server are part of that one plan.

## Pricing

From $10 per seat a month, API included. 14-day free trial.

## Related

- [Discord scheduler](https://omnisocials.com/discord.md)
- [Discord MCP server](https://omnisocials.com/discord-mcp.md)
- [All channels](https://omnisocials.com/channels.md)
- [Discord character limits](https://omnisocials.com/discord-character-limits)
- [Discord video lengths](https://omnisocials.com/discord-video-lengths)

## Links

- Page: https://omnisocials.com/discord-api
- Discord platform docs: https://docs.omnisocials.com/platforms/discord
- API reference: https://docs.omnisocials.com/api
- REST API overview: https://omnisocials.com/api.md
- MCP server: https://omnisocials.com/mcp.md
- Sign up: https://app.omnisocials.com/signup
