> ## Documentation Index
> Fetch the complete documentation index at: https://docs.madiad.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Channels

> Every channel MADIAD Hub publishes to, how each one connects, and which kinds of post it accepts.

MADIAD Hub publishes to **22 channels**. Not all of them are social networks — the list also covers blogs, team chat, the fediverse, a commerce platform and a mailing list. Each accepts a specific set of post kinds, and connects in one of two ways.

## What each channel accepts

`platforms` is validated against this table before anything is sent. Asking a blog for a video, or YouTube for a text post, returns `400 invalid_request` naming the offending channel — it does not half-publish and then fail.

| Channel                 | `platform`        | Text | Photo | Video | Connects with         |
| ----------------------- | ----------------- | :--: | :---: | :---: | --------------------- |
| TikTok                  | `tiktok`          |   —  |   ✅   |   ✅   | OAuth                 |
| Instagram               | `instagram`       |   —  |   ✅   |   ✅   | OAuth                 |
| YouTube                 | `youtube`         |   —  |   —   |   ✅   | OAuth                 |
| Facebook                | `facebook`        |   ✅  |   ✅   |   ✅   | OAuth                 |
| LinkedIn                | `linkedin`        |   ✅  |   ✅   |   ✅   | OAuth                 |
| X                       | `x`               |   ✅  |   ✅   |   ✅   | OAuth                 |
| Threads                 | `threads`         |   ✅  |   ✅   |   ✅   | OAuth                 |
| Pinterest               | `pinterest`       |   —  |   ✅   |   ✅   | OAuth                 |
| Reddit                  | `reddit`          |   ✅  |   ✅   |   ✅   | OAuth                 |
| Bluesky                 | `bluesky`         |   ✅  |   ✅   |   ✅   | App password          |
| Google Business Profile | `google_business` |   ✅  |   ✅   |   ✅   | OAuth                 |
| Telegram                | `telegram`        |   ✅  |   ✅   |   ✅   | Your bot              |
| Discord                 | `discord`         |   ✅  |   ✅   |   ✅   | Channel webhook       |
| Slack                   | `slack`           |   ✅  |   —   |   —   | Incoming webhook      |
| Mastodon                | `mastodon`        |   ✅  |   ✅   |   ✅   | Access token          |
| Nostr                   | `nostr`           |   ✅  |   —   |   —   | Private key           |
| Lemmy                   | `lemmy`           |   ✅  |   ✅   |   —   | Account login         |
| dev.to                  | `devto`           |   ✅  |   —   |   —   | API key               |
| Hashnode                | `hashnode`        |   ✅  |   —   |   —   | Personal access token |
| WordPress               | `wordpress`       |   ✅  |   ✅   |   ✅   | Application password  |
| Whop                    | `whop`            |   ✅  |   —   |   —   | API key               |
| listmonk                | `listmonk`        |   ✅  |   —   |   —   | API user              |

<Note>
  Use the `platform` value exactly as written — `x` (not `twitter`), `google_business` (with an underscore), `devto` (no dot).
</Note>

<Warning>
  **Threads, Reddit and Bluesky cannot be connected at the moment** (Threads and Reddit checked 12
  September 2026, Bluesky 13 September 2026). These channels are being upgraded, and retrying does
  not help, so their tiles on the connect page are greyed out with a note rather than letting a
  customer walk into a dead end. Starting a connection for any of them returns
  `503 platform_unavailable`. Channels already connected keep
  working and keep publishing, and everything else in the table above is unaffected.
</Warning>

## Two ways to connect

### OAuth channels

Most channels connect by signing in on the connect page: you send the customer a link, they authorise MADIAD Hub on the platform's own screen, and nothing sensitive passes through you. See [Profiles](/concepts/profiles) for the connect-link flow.

### Manual-credential channels

Slack, Mastodon, Nostr, Lemmy, dev.to, Hashnode, WordPress, Whop, listmonk, Telegram and Discord have no OAuth consent screen. Instead, the customer supplies a credential — a webhook URL, an API key, or an application password — which is validated against the platform and stored encrypted.

Link one with `POST /v1/connections/{platform}`. Every request takes `profile_id` and an optional `name`, plus the platform's own fields:

| Channel   | Endpoint                    | Fields                                              |
| --------- | --------------------------- | --------------------------------------------------- |
| Telegram  | `/v1/connections/telegram`  | `bot_token`, `chat_id`                              |
| Discord   | `/v1/connections/discord`   | `webhook_url`                                       |
| Slack     | `/v1/connections/slack`     | `webhook_url`                                       |
| Mastodon  | `/v1/connections/mastodon`  | `instance_url`, `access_token`                      |
| Nostr     | `/v1/connections/nostr`     | `private_key` · `relays` *(optional)*               |
| Lemmy     | `/v1/connections/lemmy`     | `instance_url`, `username`, `password`, `community` |
| dev.to    | `/v1/connections/devto`     | `api_key`                                           |
| Hashnode  | `/v1/connections/hashnode`  | `pat`, `publication_id`                             |
| WordPress | `/v1/connections/wordpress` | `site_url`, `username`, `application_password`      |
| Whop      | `/v1/connections/whop`      | `api_key`, `experience_id`                          |
| listmonk  | `/v1/connections/listmonk`  | `instance_url`, `username`, `password`, `list_id`   |

```bash theme={null}
curl -X POST https://api.madiad.com/v1/connections/wordpress \
  -H "Authorization: Bearer $MADIAD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "profile_id": "'"$PROFILE_ID"'",
    "site_url": "https://blog.example.com",
    "username": "editor",
    "application_password": "xxxx xxxx xxxx xxxx xxxx xxxx",
    "name": "Company blog"
  }'
```

A successful call returns the profile's refreshed connection status. `instance_url` and `site_url` must be `https://` URLs.

Every field is required except where marked optional — omit an optional field and the platform's own default applies (Nostr falls back to a default relay list). Sending it as an empty string is not the same as omitting it.

<Warning>
  **A Nostr private key cannot be rotated or revoked.** Unlike an API key or an application password, whoever holds it controls that identity permanently. Use a Nostr identity created for automated posting — never your personal key.
</Warning>

<Note>
  **WordPress needs an application password, not your login password.** Create one under **Users → Profile → Application Passwords**. The same applies in spirit to Lemmy and listmonk, which do take an account password: give them an account that exists only for publishing.
</Note>

## Choosing an endpoint

The three publish endpoints map onto the columns above:

* [`POST /v1/posts/text`](/concepts/posts) — every channel with a ✅ in **Text**
* [`POST /v1/posts/photos`](/concepts/posts) — every channel with a ✅ in **Photo**
* [`POST /v1/posts/video`](/concepts/posts) — every channel with a ✅ in **Video**

A single call may list any mix of channels that all accept that kind. To reach both a video platform and a blog, send two calls — they are two different kinds of post, and each counts as one upload.

## Analytics coverage

[Analytics](/concepts/analytics) covers ten channels: TikTok, Instagram, YouTube, Facebook, LinkedIn, X, Threads, Pinterest, Reddit and Bluesky.

Google Business Profile and every manual-credential channel report no follower, reach or engagement metrics — a Discord webhook or a mailing list has no follower graph to read. Leave them out of the `platforms` list when requesting analytics.
