# Discord: coming soon

Source: https://postgale.com/docs/discord

Publish messages with attachments and embeds to Discord channels through a channel webhook, and edit or delete them, via the Postgale API and MCP server.

> **Coming soon.** Discord is not available yet: Discord channels cannot be connected in production, so none of the
> endpoints or tools below work against Discord today. This page describes the planned integration and may change before launch.

Postgale publishes to Discord channels through channel webhooks: text messages, up to 10 attachments and up to 10 embeds, with edits
and deletes of what was published. Everything is available over the [REST API](https://postgale.com/docs/api) (paths relative to `https://postgale.com/api/v1`) and the
[MCP server](https://postgale.com/docs/mcp) (`connect_account`, `create_post`, `manage_published_post`). Each connected channel is one account with platform
`discord`; its `platformAccountId` is the Discord webhook id.

## Connect a channel

Connecting uses Discord's own authorization screen (OAuth2 with the `webhook.incoming` scope). No bot joins your server.

1. In Postgale open **Dashboard → Accounts → Discord** (or ask for a link with the API or `connect_account`).
2. On Discord, pick the **server** and the **channel** to post to and authorize. You need the *Manage Webhooks* permission in that server.
3. Discord creates a webhook in that channel and you come back to Postgale, where the channel is listed as a Discord account.

GET /api/v1/connect/discord:
```bash
curl https://postgale.com/api/v1/connect/discord \
  -H 'Authorization: Bearer sk_…'

# {"authUrl":"https://postgale.com/api/oauth/discord/consent?state=…","expiresInSeconds":600}
```

`?externalId=…` (your own reference) is stored on the connected account. The account is named after the webhook and the server, e.g.
`Postgale @ Acme HQ` (Discord does not tell apps the channel's name); the server and channel ids are kept in the account metadata.
Postgale stores only the webhook, with its token encrypted; it does not keep a Discord user token.

If the webhook is deleted in Discord (Server settings → Integrations → Webhooks) or the channel is removed, the next call fails with
*Unknown Webhook*: the account becomes `needs_reconnect` and `account.disconnected` is sent (reason `webhook_deleted`). Connecting the
same channel again reconnects that account. Disconnecting the account in Postgale deletes the webhook in Discord.

## Publish

The post content is the message, up to 2000 characters. A message needs content, an attachment or an embed. Postgale uploads the
attachments to Discord itself (multipart), up to 10 files of up to 10 MB each and 25 MB per message in all; use the `publicUrl` of
[uploaded media](https://postgale.com/docs/api) or any public https URL. Limits are checked when the post is created.

POST /api/v1/posts:
```bash
curl -X POST https://postgale.com/api/v1/posts \
  -H 'Authorization: Bearer sk_…' \
  -H 'Content-Type: application/json' \
  -d '{"content":"Release 2.4 is out 🎉","platforms":[{"accountId":"acc_dc","platformSpecificData":{"mediaUrls":["https://media.postgale.com/…/screenshot.png"],"embeds":[{"title":"Changelog","description":"Faster sync and dark mode.","url":"https://example.com/changelog","color":5793266,"fields":[{"name":"Version","value":"2.4","inline":true}],"image":{"url":"attachment://screenshot.png"}}],"username":"Release notes"}}],"publishNow":true}'
```

| platformSpecificData | What it does |
| --- | --- |
| `mediaUrl` / `mediaUrls` | Up to 10 attachments (public https URLs, any file type) |
| `embeds` | Up to 10 [Discord embed objects](https://discord.com/developers/docs/resources/message#embed-object): `title` (≤256), `description` (≤4096), `url`, `color` (integer `0xRRGGBB`), `timestamp`, `footer {text, icon_url?}`, `image {url}`, `thumbnail {url}`, `author {name, url?, icon_url?}`, `fields [{name, value, inline?}]` (≤25). 6000 characters in all. Image URLs may be `attachment://<file name>` to show an attachment |
| `username` | Post under this name instead of the webhook's (1-80 characters, cannot contain "discord" or "clyde") |
| `avatarUrl` | https URL of the avatar to post with |
| `silent` | No push notification (like `@silent`) |
| `mentionEveryone` | Let `@everyone` and `@here` in the text ping. Off by default; user and role mentions always ping |

The target's `platformPostId` is the Discord message id and `url` the `discord.com/channels/…` link to the message.

## Edit and delete

| Method | Path | What it does |
| --- | --- | --- |
| POST | `/posts/{id}/edit` | `{content}`: new text of the message (≤2000); attachments and embeds stay |
| POST | `/posts/{id}/unpublish` | Delete the message |
| GET | `/accounts/{id}/health` | Whether the webhook still exists |

Both are queued for a person while approval applies to the API key, the organization or the account (202 `pending_approval`; MCP
`manage_published_post` returns the queued action).

## Discord's rules to know

- **Rate limits**: when Discord answers 429, Postgale retries the post after the `retry_after` Discord asks for.
- **Deleted webhooks**: *Unknown Webhook* or an invalid webhook token marks the account `needs_reconnect` (`reconnect_required` on the API) and the post is not retried automatically.
- **Analytics**: webhooks get no views, reactions or member counts, so post and account analytics answer `not_supported`.
- **File size**: 10 MB per file is Discord's default upload limit; boosted servers allow more, but Postgale keeps to the default.
