Skip to main content

Connecting Social Accounts

Manual Credential Connections

Most platforms are connected through the JWT connection page (OAuth). A few platforms use a manual credential model instead: you submit the credentials to a dedicated endpoint, Upload-Post validates them with the platform, encrypts the secret at rest, and links it to the profile — no OAuth and no browser redirect. These credentials do not expire.

Connecting Discord (manual credentials)

Discord is connected with a channel incoming webhook URL, not OAuth.

  1. In Discord, open Server Settings → Integrations → Webhooks → New Webhook.
  2. Choose the channel the posts should land in and click Copy Webhook URL.
  3. Send the webhook URL to Upload-Post:
curl -X POST https://api.upload-post.com/api/uploadposts/users/discord/credentials \
-H "Authorization: Apikey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"profile_username": "your_user_id_123",
"webhook_url": "https://discord.com/api/webhooks/123456789/abcdef...",
"name": "My Server #announcements"
}'

Upload-Post validates the webhook (GET on the URL), encrypts and stores it, and sets social_accounts.discord on the profile. After connecting, post with platform[]=discord on the text, photo, and video endpoints. Discord supports text (max 2000 chars), up to 10 images per message, and video. Analytics are not available for Discord.

➡️ See details: Connect Discord API Reference

Connecting Telegram (manual credentials)

Telegram is connected with your own bot plus a target chat, not OAuth.

  1. In Telegram, message @BotFather, send /newbot, and follow the prompts to obtain a bot token.
  2. Add the bot to the target channel or group as an administrator (it must be an admin to post).
  3. Determine the chat_id: a public channel can use its @username; private chats use the numeric id (e.g. -100123456789).
  4. Send the credentials to Upload-Post:
curl -X POST https://api.upload-post.com/api/uploadposts/users/telegram/credentials \
-H "Authorization: Apikey YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"profile_username": "your_user_id_123",
"bot_token": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11",
"chat_id": "@my_channel",
"name": "My Channel"
}'

Upload-Post validates the token (getMe) and chat (getChat), encrypts and stores the bot token, and sets social_accounts.telegram on the profile. After connecting, post with platform[]=telegram on the text, photo, and video endpoints. Telegram supports text (max 4096 chars), single or multiple photos (album), and video (caption max 1024 chars). Analytics are not available for Telegram.

➡️ See details: Connect Telegram API Reference

Connecting Slack (manual credentials)

Slack is connected with a channel Incoming Webhook URL (no OAuth). In Slack, create an app, enable Incoming Webhooks, and add one to the target channel to obtain a URL like https://hooks.slack.com/services/T.../B.../xxxx.

curl -X POST https://api.upload-post.com/api/uploadposts/users/slack/credentials \
-H "Authorization: Apikey YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{ "profile_username": "your_user_id_123", "webhook_url": "https://hooks.slack.com/services/T00/B00/xxxx", "name": "Team Channel" }'

After connecting, post with platform[]=slack on the text endpoint (text only; a Slack Incoming Webhook cannot upload media). Use slack_title to override the shared caption. No analytics.

Connecting Mastodon (manual credentials)

Mastodon uses a per-instance access token. In your Mastodon instance go to Preferences → Development → New application, then copy the access token.

curl -X POST https://api.upload-post.com/api/uploadposts/users/mastodon/credentials \
-H "Authorization: Apikey YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{ "profile_username": "your_user_id_123", "instance_url": "https://mastodon.social", "access_token": "YOUR_TOKEN", "name": "@[email protected]" }'

Supports platform[]=mastodon on text, photo (up to 4 images), and video endpoints. Use mastodon_title to override. No analytics.

Connecting Nostr (manual credentials)

Nostr signs notes with your private key (nsec or hex) and broadcasts to relays. No server account is required.

curl -X POST https://api.upload-post.com/api/uploadposts/users/nostr/credentials \
-H "Authorization: Apikey YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{ "profile_username": "your_user_id_123", "private_key": "nsec1...", "relays": "wss://relay.damus.io,wss://nos.lol", "name": "My Nostr" }'

Text only (platform[]=nostr); relays is optional (sensible defaults are used). Use nostr_title to override. No analytics.

Connecting Lemmy (manual credentials)

Lemmy uses your instance URL, username, password, and a target community. Posts require a community.

curl -X POST https://api.upload-post.com/api/uploadposts/users/lemmy/credentials \
-H "Authorization: Apikey YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{ "profile_username": "your_user_id_123", "instance_url": "https://lemmy.world", "username": "you", "password": "YOUR_PASSWORD", "community": "technology", "name": "Lemmy" }'

Supports platform[]=lemmy on the text and photo endpoints (video is not natively hosted). A title is required per post (lemmy_title or derived from the first line). No analytics.

Connecting Dev.to (manual credentials)

Dev.to publishes Markdown articles with a single API key (Settings → Extensions → DEV API Keys).

curl -X POST https://api.upload-post.com/api/uploadposts/users/devto/credentials \
-H "Authorization: Apikey YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{ "profile_username": "your_user_id_123", "api_key": "YOUR_DEV_API_KEY", "name": "Dev.to" }'

Text/article only (platform[]=devto). devto_title sets the article title (or it is derived from the first line); the shared caption becomes the Markdown body. No analytics.

Connecting Hashnode (manual credentials)

Hashnode uses a Personal Access Token and the target publication ID.

curl -X POST https://api.upload-post.com/api/uploadposts/users/hashnode/credentials \
-H "Authorization: Apikey YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{ "profile_username": "your_user_id_123", "pat": "YOUR_PAT", "publication_id": "PUBLICATION_ID", "name": "My Blog" }'

Text/article only (platform[]=hashnode). hashnode_title sets the post title; the caption becomes the Markdown content. No analytics.

Connecting WordPress (manual credentials)

WordPress (self-hosted) uses your site URL, username, and an Application Password (Users → Profile → Application Passwords).

curl -X POST https://api.upload-post.com/api/uploadposts/users/wordpress/credentials \
-H "Authorization: Apikey YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{ "profile_username": "your_user_id_123", "site_url": "https://myblog.com", "username": "admin", "application_password": "xxxx xxxx xxxx xxxx", "name": "My Blog" }'

Supports platform[]=wordpress on text (posts), photo (featured image), and video endpoints. wordpress_title sets the post title; the caption becomes the post body. No analytics.

Connecting Whop (manual credentials)

Whop posts to a community forum with an API key and the target experience ID.

curl -X POST https://api.upload-post.com/api/uploadposts/users/whop/credentials \
-H "Authorization: Apikey YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{ "profile_username": "your_user_id_123", "api_key": "YOUR_WHOP_API_KEY", "experience_id": "exp_XXXX", "name": "My Community" }'

Text only (platform[]=whop). Posting to a community forum requires an API key with the forum:post:create permission. Use whop_title to set the post title. No analytics.

Connecting Listmonk (manual credentials)

Listmonk (self-hosted newsletter) uses your instance URL, username, password, and a target list ID. Each post creates and sends a campaign.

curl -X POST https://api.upload-post.com/api/uploadposts/users/listmonk/credentials \
-H "Authorization: Apikey YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{ "profile_username": "your_user_id_123", "instance_url": "https://list.myblog.com", "username": "admin", "password": "YOUR_PASSWORD", "list_id": "1", "name": "Newsletter" }'

Text only (platform[]=listmonk). listmonk_title sets the campaign subject; the caption becomes the email body. No analytics.