# Create a Connect Link

> Get a one-time link that lets someone connect a social account to your workspace without logging in to Orshot

- **URL**: https://orshot.com/docs/api-reference/social-connect-session-create

---

Create a connect session: a one-time link for one platform and one account. Hand the link to the person who owns the social account (a client, a franchisee, a team member in your own app). They approve the platform login in their browser, and the account lands in your workspace, ready for the [publish](https://orshot.com/docs/api-reference/social-publish) endpoints. They never need an Orshot login.

The link works once and for five minutes. The first click binds it to that browser, so a forwarded link is dead. Read the outcome with [Get a Connect Session](https://orshot.com/docs/api-reference/social-connect-session-get), or let the person come back to your `return_url`.

See the [Connect accounts from your app](https://orshot.com/docs/publish/connect-from-your-app) guide for the full flow.

A link made for someone else (`external_id` or `return_url` set) is enabled
per workspace on the Enterprise plan; contact hi@orshot.com to turn it on.
The endpoints accept the workspace's API keys and first party clients like
the [Orshot MCP server](https://orshot.com/agents); third-party OAuth apps
are refused. A workspace connecting its own account from the MCP (no
`external_id`, no `return_url`) works on every paid plan, as the dashboard
does.

What the link opens, left to right: the connect page naming your workspace and the platform, the account picker (LinkedIn and Facebook), and the connected result.

![The connect page, the account picker and the connected result page](https://orshot.com/docs/publish/connect-link-flow.webp)

## Endpoint

### POST /social/connect-sessions

```markdown tab="Endpoint"
https://api.orshot.com/v1/social/connect-sessions
```

## Request Example

```js
await fetch("https://api.orshot.com/v1/social/connect-sessions", {
  method: "POST",
  headers: {
    Authorization: "Bearer <ORSHOT_API_KEY>",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    platform: "instagram",
    return_url: "https://crm.example.com/socials/done",
    external_id: "office_142",
  }),
});
```

## Request Parameters

| Parameter              | Type    | Required | Description |
| ---------------------- | ------- | -------- | ----------- |
| `platform`             | String  | Yes      | One of `twitter`, `instagram`, `facebook`, `linkedin`, `tiktok`, `youtube`, `pinterest`, `reddit`, `threads`. Other platforms are connected from the dashboard. |
| `return_url`           | String  | No       | Where the person's browser goes once the connection has an outcome. `https` only, up to 512 characters, no credentials or fragment. The host must be one of your workspace's allowed domains (Embed settings) or `orshot.com`. Without it the person sees Orshot's own result page. |
| `external_id`          | String  | No       | Your reference for the person or account, up to 128 characters of letters, digits, `_`, `.`, `:` or `-`. Stored on the connected account and returned by [List Social Accounts](https://orshot.com/docs/api-reference/social-accounts-list). Do not put emails or other personal data in it. |
| `reconnect_account_id` | Integer | No       | An existing account of this workspace and platform. The login is pinned to that account's identity; signing in as anyone else fails with `account_mismatch`. |
| `expected_username`    | String  | No       | The handle the person must sign in with. Any other identity fails with `account_mismatch`. |
| `post_id`              | Integer | No       | A waiting post of this workspace. Echoed back on the session; waiting posts for the platform attach to the new account on their own. |

## Response Example

```json
{
  "data": {
    "id": "cs_9kq2N0xYv3b8ZtQ1mL7wPA",
    "object": "social_connect_session",
    "status": "pending",
    "platform": "instagram",
    "external_id": "office_142",
    "post_id": null,
    "reconnect_account_id": null,
    "return_url": "https://crm.example.com/socials/done",
    "created_at": "2026-11-02T10:00:00.000Z",
    "expires_at": "2026-11-02T10:05:00.000Z",
    "opened_at": null,
    "completed_at": null,
    "account": null,
    "attached_posts": 0,
    "error": null,
    "connect_url": "https://orshot.com/connect/social/cst_Vb3…",
    "billing": {
      "amount": 12,
      "currency": "usd",
      "interval": "month",
      "recurring": true,
      "billed_to": "workspace_owner"
    }
  }
}
```

`connect_url` is returned once, here. Treat it as a secret: it is the only credential the person needs. `billing` states what a connected account adds to the workspace owner's subscription, see [Pricing](https://orshot.com/docs/publish/pricing).

## Session Status

| Status      | Meaning |
| ----------- | ------- |
| `pending`   | Created, link not opened yet |
| `opened`    | Continue pressed, platform login in progress |
| `selecting` | The platform returned several identities (LinkedIn organisation, Facebook page) and the person is choosing |
| `connected` | Done. `account` holds the connected account |
| `failed`    | Ended without an account. `error.code` says why |
| `cancelled` | Cancelled with [Cancel a Connect Session](https://orshot.com/docs/api-reference/social-connect-session-cancel) |
| `expired`   | Nobody opened the link within five minutes, or the login was not finished within 15 minutes of Continue. An opened session that expired can still end as `connected` when the platform reports the login late |

## Rate Limits

Besides the 20 requests per minute shared by all social endpoints, a workspace can create **30 connect links per hour** and complete **100 connections per day**.

## Error Responses

| Code | `code`                          | Description |
| ---- | ------------------------------- | ----------- |
| 400  | `invalid_platform`              | Unknown platform, or one that is dashboard-only. `supported` lists the valid values |
| 400  | `invalid_return_url`            | Not `https`, too long, or a host outside your allowed domains |
| 400  | `invalid_external_id`           | Too long or unexpected characters |
| 400  | `invalid_field`                 | `expected_username`, `reconnect_account_id` or `post_id` malformed |
| 403  | `enterprise_required`           | Connect links from a workspace API key need the Enterprise flag on this workspace's plan, and so does any link with `external_id` or `return_url`. Contact hi@orshot.com |
| 403  | `first_party_only`              | The caller is a third-party OAuth app. Use a workspace API key |
| 403  | `social_requires_paid_account`  | The workspace owner has no paid plan. `upgrade_url` is included |
| 403  | `shopify_billed`                | Social accounts are not available on Shopify-billed plans yet |
| 403  | `insufficient_role`             | The OAuth token's person is not an owner or admin of the workspace |
| 404  | `account_not_found`             | `reconnect_account_id` is not an account of this workspace |
| 404  | `post_not_found`                | `post_id` is not a post of this workspace |
| 429  | `rate_limited`                  | Links per hour or connections per day reached. `Retry-After` is set |
| 503  | `connect_unavailable`           | Connect links are briefly unavailable. Retry shortly |