Networks and connections

List networks, connect accounts (yours or your clients'), check and move connections.

View as MarkdownOpenAPIBase URL https://postwire.io

Telegram, Bluesky, Mastodon and Discord connect with credentials (POST /api/connect). TikTok, YouTube, Instagram, Facebook Pages and LinkedIn (personal profile) connect with OAuth: get the authorize URL and open it in a browser. To let a client connect their own account without a PostWire login, send them a connect link.

List supported platforms

GET/api/platforms

No API key needed.

Responses

StatusMeans
200OK
curl
curl "https://postwire.io/api/platforms"
Node
const res = await fetch("https://postwire.io/api/platforms", {
  method: "GET",
});
console.log(res.status, await res.json());
Python
import os, requests

r = requests.get(
    "https://postwire.io/api/platforms",
)
print(r.status_code, r.json())

Connect a credential-based platform (telegram, bluesky, mastodon, discord)

POST/api/connect

Needs an API key: Authorization: Bearer pw_live_….

Body (JSON)

FieldTypeDescription
platform requiredstringOne of: telegram, bluesky, mastodon, discord.
credentials requiredobjecttelegram { bot_token, chat_id } · bluesky { handle, app_password } · mastodon { instance_url, access_token } · discord { webhook_url }. Checked with the network before they are saved.
brand_idstring (uuid)

Responses

StatusMeans
200Connected
curl
curl -X POST "https://postwire.io/api/connect" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "platform": "telegram",
  "credentials": {
    "bot_token": "123456789:AAF…",
    "chat_id": "@bakerynews"
  }
}'
Node
const res = await fetch("https://postwire.io/api/connect", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "platform": "telegram",
    "credentials": {
      "bot_token": "123456789:AAF…",
      "chat_id": "@bakerynews"
    }
  }),
});
console.log(res.status, await res.json());
Python
import os, requests

r = requests.post(
    "https://postwire.io/api/connect",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
    json={
        "platform": "telegram",
        "credentials": {
            "bot_token": "123456789:AAF…",
            "chat_id": "@bakerynews",
        },
    },
)
print(r.status_code, r.json())

Get an OAuth authorize URL for an OAuth platform (tiktok, youtube, linkedin, facebook, instagram)

POST/api/oauth/{platform}/url

Needs an API key: Authorization: Bearer pw_live_….

Parameters

FieldTypeDescription
platform requiredpath, string

Responses

StatusMeans
200{ url }
curl
curl -X POST "https://postwire.io/api/oauth/tiktok/url" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY"
Node
const res = await fetch("https://postwire.io/api/oauth/tiktok/url", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());
Python
import os, requests

r = requests.post(
    "https://postwire.io/api/oauth/tiktok/url",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())

Example response

JSON
{
  "url": "https://www.tiktok.com/v2/auth/authorize/?client_key=…"
}

Generate a hosted connect link for an end-user (multi-tenant)

POST/api/connect-link

A hosted page (valid 1 hour) where your client connects their own account, without a PostWire login: send them the url. The connection lands in brand_id.

Needs an API key: Authorization: Bearer pw_live_….

Body (JSON)

FieldTypeDescription
platformstringOffer only this network; without it the page offers every network. One of: tiktok, instagram, youtube, linkedin, facebook, bluesky, mastodon, telegram, discord.
brand_idstring (uuid)The brand the connection is saved into.
ig_usernamestringInstagram: the @handle to connect, when the person's Pages have several.

Responses

StatusMeans
200{ url, token, expires_in }
curl
curl -X POST "https://postwire.io/api/connect-link" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "platform": "instagram",
  "brand_id": "b3f1c2d4-8a9e-4f6b-a1c2-3d4e5f6a7b8c"
}'
Node
const res = await fetch("https://postwire.io/api/connect-link", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "platform": "instagram",
    "brand_id": "b3f1c2d4-8a9e-4f6b-a1c2-3d4e5f6a7b8c"
  }),
});
console.log(res.status, await res.json());
Python
import os, requests

r = requests.post(
    "https://postwire.io/api/connect-link",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
    json={
        "platform": "instagram",
        "brand_id": "b3f1c2d4-8a9e-4f6b-a1c2-3d4e5f6a7b8c",
    },
)
print(r.status_code, r.json())

Example response

JSON
{
  "url": "https://postwire.io/connect/#eyJ…",
  "token": "eyJ…",
  "expires_in": 3600,
  "platform": "instagram",
  "brand_id": "b3f1c2d4-8a9e-4f6b-a1c2-3d4e5f6a7b8c"
}

The connected accounts, with their brand and the identity each network reports

GET/api/connections

Needs an API key: Authorization: Bearer pw_live_….

Responses

StatusMeans
200{ connections: [{ platform, brand_id, brand_name, label?, identity, needs }] }
curl
curl "https://postwire.io/api/connections" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY"
Node
const res = await fetch("https://postwire.io/api/connections", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());
Python
import os, requests

r = requests.get(
    "https://postwire.io/api/connections",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())

Check that a connection still works

GET/api/connect/{platform}/health

Asks the network whether the stored login is still accepted (a revoked token, a Telegram bot removed from its chat, a deleted Discord webhook). healthy null means the network has no check. 240 checks an hour.

Needs an API key: Authorization: Bearer pw_live_….

Parameters

FieldTypeDescription
platform requiredpath, string
brand_idquery, string (uuid)Which brand's connection, when the network is connected in more than one brand.

Responses

StatusMeans
200{ platform, brand_id, connected, healthy: true|false|null, reason, action: null|"reconnect", account, label }
curl
curl "https://postwire.io/api/connect/linkedin/health" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY"
Node
const res = await fetch("https://postwire.io/api/connect/linkedin/health", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());
Python
import os, requests

r = requests.get(
    "https://postwire.io/api/connect/linkedin/health",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())

Disconnect one network of one brand

DELETE/api/connect/{platform}

Needs an API key: Authorization: Bearer pw_live_….

Parameters

FieldTypeDescription
platform requiredpath, string
brand_idquery, string (uuid)Which brand's connection, when the network is connected in more than one brand.

Responses

StatusMeans
200{ ok, platform, brand_id, connected: false }
404not_connected in that brand
409ambiguous_brand: connected in several brands, say which with ?brand_id=
curl
curl -X DELETE "https://postwire.io/api/connect/discord?brand_id=b3f1c2d4-8a9e-4f6b-a1c2-3d4e5f6a7b8c" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY"
Node
const res = await fetch("https://postwire.io/api/connect/discord?brand_id=b3f1c2d4-8a9e-4f6b-a1c2-3d4e5f6a7b8c", {
  method: "DELETE",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());
Python
import os, requests

r = requests.delete(
    "https://postwire.io/api/connect/discord?brand_id=b3f1c2d4-8a9e-4f6b-a1c2-3d4e5f6a7b8c",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())

Move a connected account to another brand of the same PostWire account

POST/api/connect/{platform}/move

Keeps the same login and token; only the brand changes. Without confirm:true nothing moves and the response describes the move (which account, from which brand, to which). Refused with 409 when the target brand already has that network, or when queued posts of the source brand still publish to it (they are listed).

Needs an API key: Authorization: Bearer pw_live_….

Parameters

FieldTypeDescription
platform requiredpath, string

Body (JSON)

FieldTypeDescription
to_brand_id requiredstring
from_brand_idstringNeeded only when the network is connected in more than one brand.
confirmbooleantrue performs the move; otherwise it is a preview.

Responses

StatusMeans
200{ ok, preview?|moved?, platform, account, from: { brand_id, name }, to: { brand_id, name }, message }
409ambiguous_brand | target_has_platform | scheduled_posts_use_it
curl
curl -X POST "https://postwire.io/api/connect/tiktok/move" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "to_brand_id": "b3f1c2d4-8a9e-4f6b-a1c2-3d4e5f6a7b8c",
  "confirm": true
}'
Node
const res = await fetch("https://postwire.io/api/connect/tiktok/move", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "to_brand_id": "b3f1c2d4-8a9e-4f6b-a1c2-3d4e5f6a7b8c",
    "confirm": true
  }),
});
console.log(res.status, await res.json());
Python
import os, requests

r = requests.post(
    "https://postwire.io/api/connect/tiktok/move",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
    json={
        "to_brand_id": "b3f1c2d4-8a9e-4f6b-a1c2-3d4e5f6a7b8c",
        "confirm": True,
    },
)
print(r.status_code, r.json())

The connected TikTok creator and what it may post with

GET/api/tiktok/creator-info

TikTok's own answer for this creator: the privacy levels it allows (use one in options.tiktok.privacy_level), whether comments, duets and stitches are switched off, and the longest video it may post.

Needs an API key: Authorization: Bearer pw_live_….

Parameters

FieldTypeDescription
brand_idquery, string (uuid)Which brand's connection, when the network is connected in more than one brand.

Responses

StatusMeans
200{ ok, brand_id, creator_nickname, creator_username, creator_avatar_url, privacy_level_options[], comment_disabled, duet_disabled, stitch_disabled, max_video_post_duration_sec }
400TikTok not connected
curl
curl "https://postwire.io/api/tiktok/creator-info" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY"
Node
const res = await fetch("https://postwire.io/api/tiktok/creator-info", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());
Python
import os, requests

r = requests.get(
    "https://postwire.io/api/tiktok/creator-info",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())