Skip to content

Profile Groups API Reference

Profile Groups are organizational containers that group related social media profiles together. For example, you might have separate profile groups for different brands, clients, or projects.

MethodEndpointDescription
GET/api/profile_groupsList all profile groups
GET/api/profile_groups/:idGet a single profile group
POST/api/profile_groupsCreate a new profile group
DELETE/api/profile_groups/:idDelete a profile group
POST/api/profile_groups/:id/initialize_connectionGet OAuth URL to connect a profile

FieldTypeDescription
idstringUnique profile group identifier (id)
namestringDisplay name of the profile group
profiles_countintegerNumber of connected profiles in this group

GET /api/profile_groups

Retrieves all profile groups accessible with your API key.

API Key TypeReturns
Full account accessAll profile groups in the account
Profile group scopedOnly the scoped profile group
Terminal window
curl -X GET "https://api.postproxy.dev/api/profile_groups" \
-H "Authorization: Bearer YOUR_API_KEY"

Response:

{
"data": [
{
"id": "grp123abc",
"name": "Main Brand",
"profiles_count": 5
},
{
"id": "grp456def",
"name": "Client Project",
"profiles_count": 3
},
{
"id": "grp789ghi",
"name": "Personal",
"profiles_count": 2
}
]
}

GET /api/profile_groups/:id

Retrieves a single profile group by its ID.

NameTypeRequiredDescription
idstringYesProfile group id
Terminal window
curl -X GET "https://api.postproxy.dev/api/profile_groups/grp123abc" \
-H "Authorization: Bearer YOUR_API_KEY"

Response:

{
"id": "grp123abc",
"name": "Main Brand",
"profiles_count": 5
}

POST /api/profile_groups

Creates a new profile group.

NameTypeRequiredDescription
profile_group[name]stringYesName for the new profile group
Terminal window
curl -X POST "https://api.postproxy.dev/api/profile_groups" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"profile_group": {
"name": "New Client Project"
}
}'

Response (201 Created):

{
"id": "grp999xyz",
"name": "New Client Project",
"profiles_count": 0
}

Permission denied (scoped API key) (422):

{
"error": "Your API key has no such permission"
}

DELETE /api/profile_groups/:id

Deletes a profile group and all its associated profiles.

NameTypeRequiredDescription
idstringYesProfile group id
Terminal window
curl -X DELETE "https://api.postproxy.dev/api/profile_groups/grp123abc" \
-H "Authorization: Bearer YOUR_API_KEY"

Response:

{
"deleted": true
}

POST /api/profile_groups/:id/initialize_connection

Generates a URL to connect a new social media profile to a profile group. This is used to initiate the OAuth flow for connecting social accounts as if it was inside your service.

NameTypeRequiredDescription
idstringYesProfile group id
NameTypeRequiredDescription
platformstringYesPlatform to connect
redirect_urlstringYes (except bluesky, telegram)URL to redirect to after OAuth completes
identifierstringYes for blueskyBluesky handle (e.g. yourname.bsky.social)
app_passwordstringYes for blueskyBluesky app password (generate at bsky.app/settings/app-passwords)
bot_tokenstringYes for telegramTelegram bot token from @BotFather
PlatformAccount typeAuth type
facebookFacebook PageOAuth
instagramInstagram Business/Creator AccountOAuth
tiktokTikTok AccountOAuth
linkedinLinkedIn ProfileOAuth
youtubeYouTube ChannelOAuth
twitterX (Twitter) AccountOAuth
threadsThreads AccountOAuth
pinterestPinterest AccountOAuth
blueskyBluesky AccountApp password (no OAuth)
telegramTelegram Channels (via bot)Bring-your-own-bot (no OAuth)
Terminal window
curl -X POST "https://api.postproxy.dev/api/profile_groups/grp123abc/initialize_connection" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "instagram",
"redirect_url": "https://myapp.com/oauth/callback"
}'

Response:

{
"url": "https://app.postproxy.dev/partner_connect/inv789xyz",
"success": true
}
FieldTypeDescription
urlstringURL to redirect the user to for OAuth authentication
successbooleanWhether the invitation was created successfully
  1. Call this endpoint to get the connection URL
  2. Redirect the user to the returned url
  3. User authenticates with the social platform
  4. User is redirected to your redirect_url after completion
  5. A new profile is created in the specified profile group

If the user cancels or the OAuth flow fails, the user is redirected to your redirect_url with ?failure=true and an error_code appended as query parameters. Any existing query parameters on your redirect_url are preserved.

Error CodeDescription
user_abandonedThe user cancelled or dismissed the OAuth flow
account_is_already_connectedThe social account is already connected to another profile
update_failedFailed to update a previously disconnected profile during reconnection

Example: If your redirect_url is https://myapp.com/callback?org=123, a cancelled connection redirects to https://myapp.com/callback?org=123&failure=true&error_code=user_abandoned.

Missing redirect_url (422):

{
"error": "Missing redirect_url"
}

Missing platform (422):

{
"error": "Missing platform"
}

Platform already connected (422):

{
"error": "Platform already connected"
}

Bluesky does not support OAuth in the same way other platforms do. Instead of returning a redirect URL, the API authenticates synchronously with the user’s Bluesky handle and an app password, then creates the profile in one call.

POST /api/profile_groups/:id/initialize_connection

NameTypeRequiredDescription
platformstringYesMust be "bluesky"
identifierstringYesBluesky handle. The .bsky.social suffix is added automatically if missing. Custom domains (e.g. you.example.com) are accepted as-is.
app_passwordstringYesBluesky app password, not the account password. Users generate one at https://bsky.app/settings/app-passwords
Terminal window
curl -X POST "https://api.postproxy.dev/api/profile_groups/grp123abc/initialize_connection" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"platform": "bluesky",
"identifier": "yourname.bsky.social",
"app_password": "xxxx-xxxx-xxxx-xxxx"
}'

Response:

{
"success": true,
"profile": {
"id": "prof321zyx",
"network": "bluesky",
"name": "Your Display Name",
"external_username": "yourname.bsky.social"
}
}

Missing credentials (422):

{
"error": "Bluesky requires `identifier` (handle) and `app_password` in the payload. Generate an app password at https://bsky.app/settings/app-passwords",
"error_code": "missing_credentials"
}

Invalid credentials / 2FA required (401):

{
"error": "This account requires 2FA. Generate an app password at bsky.app/settings/app-passwords and use that instead of your main password.",
"error_code": "bluesky_login_failed"
}

Account already connected to another profile group (422):

{
"error": "This Bluesky profile is already connected to Postproxy.",
"error_code": "account_is_already_connected"
}

Telegram does not expose consumer OAuth for posting. Instead, the user creates their own bot via @BotFather and adds it as administrator to the channel(s) they want to publish to. Postproxy uses that bot’s token to publish.

A single Telegram Profile represents one bot. The channels it can publish to are exposed via the placements endpoint, and the destination channel for each post is selected per-post via the chat_id parameter — see platform parameters.

For a step-by-step walkthrough (creating the bot, adding it to channels, publishing the first post), see the Connect Telegram with your own bot guide.

  1. Submit the bot token with this endpoint to create a Profile. Postproxy validates the token and registers a webhook with Telegram.
  2. User adds the bot as administrator to each Telegram channel they want to publish to. As Telegram notifies us via the webhook, channels appear in the Profile’s placements.
  3. Poll GET /api/profiles/:id/placements to list discovered channels. Use chat_id (the placement’s id) when creating posts.

POST /api/profile_groups/:id/initialize_connection

NameTypeRequiredDescription
platformstringYesMust be "telegram"
bot_tokenstringYesToken issued by @BotFather. Get one with /newbot, then choose a name and username and copy the token.
Terminal window
curl -X POST "https://api.postproxy.dev/api/profile_groups/grp123abc/initialize_connection" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"platform": "telegram",
"bot_token": "123456789:ABCdef-GhIJklMnOpQrStUvWxYz"
}'

Response:

{
"success": true,
"profile": {
"id": "prof321zyx",
"network": "telegram",
"name": "My Bot",
"external_username": "my_bot"
},
"next_step": "Add @my_bot as administrator to the Telegram channel(s) you want to publish to. Channels will appear in GET /api/profiles/prof321zyx/placements once Telegram notifies us."
}

After the bot has been added as administrator to one or more channels, list them via:

Terminal window
curl "https://api.postproxy.dev/api/profiles/prof321zyx/placements" \
-H "Authorization: Bearer your_api_key"
{
"data": [
{ "id": "-1001234567890", "name": "My Channel (@mychannel)" },
{ "id": "-1009876543210", "name": "Private Channel" }
]
}

The list is empty until the user adds the bot to a channel. We recommend polling every few seconds while the user completes that step. If a channel never appears, ask the user to remove and re-add the bot — that re-fires the discovery event.

Missing bot token (422):

{
"error": "Telegram requires `bot_token` in the payload. Create a bot via @BotFather (https://t.me/BotFather) and pass the token."
}

Invalid bot token (401):

{
"error": "Telegram bot token is invalid or revoked — please reconnect the profile.",
"error_code": "telegram_connect_failed"
}

Bot already connected to another profile group (422):

{
"error": "This Telegram bot is already connected to Postproxy.",
"error_code": "account_is_already_connected"
}

Create separate profile groups for different brands:

Terminal window
# Create brand profile groups
curl -X POST "https://api.postproxy.dev/api/profile_groups" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"profile_group": {"name": "Brand A"}}'
curl -X POST "https://api.postproxy.dev/api/profile_groups" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"profile_group": {"name": "Brand B"}}'

Generate connection URLs for clients to connect their accounts:

Terminal window
# Get OAuth URL for client to connect Instagram
curl -X POST "https://api.postproxy.dev/api/profile_groups/grp_client123/initialize_connection" \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"network": "instagram",
"redirect_url": "https://yourplatform.com/client/connected"
}'

Issue profile-group-scoped API keys to partners, allowing them access only to their designated profile group while protecting other data.