Skip to content

Connections API ​

A connection is one social account linked to a workspace. Posts target connections by slug, such as instagram-mybrand. This page covers listing connections, checking their health, refreshing tokens, getting a reconnect link, and how the connect flows work.

Connection routes live under /api/workspaces/:id/connections and /api/oauth. With an API key the workspace comes from the key. With a dashboard session token send X-Workspace-Id. See the REST API overview.

Which connection endpoints can I call? ​

MethodPathPurposePermissionGuarded API key
GET/workspaces/:id/connectionsList connections with statusplatform.connectYes
POST/workspaces/:id/connections/:connectionId/refreshRefresh tokens (slug or ID)platform.connectNo
POST/oauth/connections/:ref/reconnect-linkGet a re-authorize linkWorkspace ownerNo
POST/oauth/:platform/popup-codeMint a code to open the connect windowWorkspace owner, session tokenNo
GET/oauth/:platform/connect-popup?code=Start the connect flow in a browserSingle-use coden/a
PATCH/workspaces/:id/connections/:connectionId/targetSwitch the page or account a connection posts toplatform.connectNo
POST/workspaces/:id/connections/:connectionId/forkAdd a second page from the same loginplatform.connectNo
DELETE/workspaces/:id/connections/:connectionIdDisconnectplatform.disconnectNo
DELETE/workspaces/:id/connections/:connectionId/revokeRevoke and deleteplatform.disconnectNo

The :connectionId in the last four rows is a connection ID. The refresh route accepts a slug or an ID. The platform.connect permission belongs to the Owner role, so Admin, Editor and Contributor sessions get 403 on list and refresh. An API key acts as the workspace owner.

How do I list connected accounts and their status? ​

bash
curl https://api.socifyr.com/api/workspaces/6a04f0000000000000000001/connections \
  -H "Authorization: Bearer sk_..."
json
{
  "success": true,
  "data": [
    {
      "id": "6a04f715d3d7d93575e65d13",
      "slug": "instagram-mybrand",
      "platform": "instagram",
      "platformUserId": "17841400000000000",
      "platformUsername": "mybrand",
      "profileImageUrl": "https://cdn.example.com/mybrand.jpg",
      "targetId": "17841400000000000",
      "targetName": "@mybrand",
      "targetImageUrl": "https://cdn.example.com/mybrand.jpg",
      "connectedAt": "2026-10-01T10:00:00.000Z",
      "expiresAt": "2026-12-20T10:00:00.000Z",
      "lastRefreshedAt": "2026-11-10T04:00:00.000Z",
      "hasRefreshToken": false,
      "status": "active",
      "canRefresh": true
    }
  ]
}

Other fields: disconnectedAt (set on disconnected accounts), and availableTargets when a login has several pages to choose from.

What do the status values mean? ​

statusMeaningWhat to do
activeNothing to do. This includes tokens near expiry that renew themselves.Post normally.
expiringThe token expires within 7 days and cannot renew itself, or it has already lapsed but can renew.If canRefresh is true, call refresh. Otherwise plan a reconnect.
needs_reconnectThe account is disconnected, or the token lapsed and cannot renew.Get a reconnect link and have the account owner approve it.

canRefresh is true when the platform supports token refresh. The background expiry cron also refreshes tokens before they lapse. Concepts and platform differences are in Connections and slugs.

How do I refresh a connection token? ​

POST /workspaces/:id/connections/:connectionId/refresh, no body. The last path segment can be the slug.

bash
curl -X POST https://api.socifyr.com/api/workspaces/6a04f0000000000000000001/connections/instagram-mybrand/refresh \
  -H "Authorization: Bearer sk_..."
json
{
  "success": true,
  "data": {
    "id": "6a04f715d3d7d93575e65d13",
    "slug": "instagram-mybrand",
    "platform": "instagram",
    "expiresAt": "2027-01-12T10:00:00.000Z",
    "lastRefreshedAt": "2026-11-13T09:00:00.000Z",
    "status": "active",
    "canRefresh": true
  }
}
StatusCauseFix
400Token refresh is not supported for <platform>. Please reconnect instead.Use the reconnect link below.
404Connection not foundCheck the slug and workspace.
403Guarded API keyUse an unrestricted key or a dashboard session.

POST /oauth/connections/:ref/reconnect-link, where :ref is the connection slug or ID. No body. Only the workspace owner can use it, which an unrestricted API key does as the owner. Guarded keys are refused.

bash
curl -X POST https://api.socifyr.com/api/oauth/connections/instagram-mybrand/reconnect-link \
  -H "Authorization: Bearer sk_..."
json
{
  "success": true,
  "data": {
    "url": "https://api.socifyr.com/api/oauth/instagram/connect-popup?code=3f9c...",
    "expiresIn": 600,
    "platform": "instagram",
    "slug": "instagram-mybrand"
  }
}

Give url to the account owner. It is single use and valid for expiresIn seconds (600). It carries a one-time code, not an access token. When the owner approves the same account, the existing connection and its slug update in place, so scheduled posts keep working. Approving a different account creates a new connection. After they approve, retry any failed post with POST /content/:id/retry.

StatusCause
403Only the workspace owner can connect accounts
404Connection not found

Reconnect also works for connections that are already disconnected. For the step-by-step recovery flow see Connections and slugs.

Can I connect a new account through the API? ​

Not with an API key alone. A new connection needs a person in a browser.

  1. A signed-in dashboard session calls POST /oauth/:platform/popup-code and receives { "code": "...", "expiresIn": 60 }. Only the workspace owner can mint it.
  2. The browser opens GET /oauth/:platform/connect-popup?code=<code>. The code works once.
  3. For OAuth platforms, the browser is redirected to the platform's consent screen and back to Socifyr's callback.
  4. For credential-entry platforms, Socifyr shows a form instead. The form is submitted with a short-lived, single-use session cookie that only the popup holds, so you cannot script it with curl.

Use the dashboard or a reconnect link for connecting. The CLI, SDK and MCP can list, refresh and reconnect, but not create the first connection.

Which platforms use a credential form? ​

PlatformFields
Blueskyidentifier (handle), appPassword
TelegrambotToken, chatId
DiscordwebhookUrl
MastodoninstanceUrl, accessToken
NostrprivateKey, optional comma-separated relays
SlackwebhookUrl
Dev.toapiKey
Hashnodetoken
TumblrconsumerKey, consumerSecret, oauthToken, oauthTokenSecret

All other supported platforms use OAuth. See each page under Platforms for the exact steps and permissions.

How do I disconnect an account? ​

RouteEffect
DELETE /workspaces/:id/connections/:connectionIdRevokes the platform token where the platform allows it and marks the connection disconnected. The record stays.
DELETE /workspaces/:id/connections/:connectionId/revokeRevokes the token and deletes the record.

Both return 204 and need the connection's ID. Both need platform.disconnect, which Admins do not have by default. Only Owners do. See Workspaces API for roles.

How do I switch the page an account posts to? ​

For Facebook and Instagram logins that manage several pages:

bash
curl -X PATCH https://api.socifyr.com/api/workspaces/6a04f0000000000000000001/connections/6a04f715d3d7d93575e65d13/target \
  -H "Authorization: Bearer <session-token>" \
  -H "X-Workspace-Id: 6a04f0000000000000000001" \
  -H "Content-Type: application/json" \
  -d '{ "targetId": "17841400000000001", "targetName": "@mybrand.shop" }'

POST .../fork with { "targetId", "targetName", "targetImageUrl" } creates a second connection for another page using the same login. The target routes do not validate a body schema beyond these fields, so send exactly these names.

Frequently asked questions ​

Why does a post fail with reconnect_required? The account's token expired and cannot renew. Get a reconnect link, have the owner approve it, then retry.

Do slugs change when I reconnect? Not when you approve the same account. The slug stays the same.

Can a guarded API key list connections? Yes. Listing is allowed, so an agent can find slugs. Refreshing and reconnecting are not.

Next steps ​