API referenceAccounts
POST
/accounts/hosted-link

JavaScript SDK: swarmhit.accounts.hostedLinks.create(params)

Mint a one-time URL where a person connects their own LinkedIn account on a page Swarmhit serves, so your product never handles their LinkedIn password. Send them to url; they sign in, clear any verification step LinkedIn raises, and are redirected back to your redirectUrl.

The sender lands in the effective workspace (the one named by the X-Swarmhit-Workspace header, if set) and consumes a seat from its allocation. The seat is checked when the link is created, so a full workspace fails here (400 seat-limit-reached, or no-plan without an active plan) rather than at the end of the person's sign-in. It is checked, not reserved; a workspace whose seats are added on demand is not refused.

The page carries your organization's name and picture by default; both can be overridden, and a default return URL set, in your organization settings — so redirectUrl only has to be sent when a particular link should land somewhere else.

With accountId the link REPAIRS that sender instead of adding one: it keeps its id, its campaigns and its seat, and no seat is consumed. The exception is a change of sign-in method (a browser-session sender signing back in with a password, or the reverse): the sender then comes back under a new id, its campaign pools move to it and the old one is removed, so read the id from account_id on the redirect. An accountId that is not a sender in the workspace is a 400 with code: account-not-found.

A failed sign-in attempt does not end the link: the person can try again until it expires or they cancel, and each attempt LinkedIn refuses fires account.connection_failed.

You learn the outcome three ways, and can use any of them: the redirect back carries ?hosted_link_id=&status=connected|failed|expired|cancelled &account_id=&external_id=; the account.connected / account.connection_failed webhooks carry hostedLinkId and externalId; and GET /accounts/hosted-link/{id} returns the current state.

url is returned once, here — the token inside it is stored only as a hash and cannot be read back.

Authorization

bearerAuth
AuthorizationBearer <token>

An API key created on the Access tokens page.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

curl -X POST "https://example.com/accounts/hosted-link" \  -H "Content-Type: application/json" \  -d '{}'
{  "data": {    "id": "string",    "status": "pending",    "channel": "linkedin",    "provider": "google",    "providers": [      "google"    ],    "orderId": "string",    "purchase": {      "maxMailboxes": 0,      "contactProvided": true    },    "url": "string",    "workspaceId": "string",    "accountId": "string",    "reconnectAccountId": "string",    "externalId": "string",    "redirectUrl": "string",    "hasProxy": true,    "country": "string",    "error": {      "code": "string",      "message": "string"    },    "expiresAt": "2019-08-24T14:15:22Z",    "openedAt": "2019-08-24T14:15:22Z",    "completedAt": "2019-08-24T14:15:22Z",    "createdAt": "2019-08-24T14:15:22Z"  }}

Open a live view of the sign-in browser POST

**JavaScript SDK:** [`swarmhit.accounts.createLiveView(accountId)`](/smart-api/sdk/methods#accounts) For a pending CAPTCHA (or a LinkedIn page with nothing to type) on a sender our own LinkedIn gateway runs, i.e. when `checkpoint.liveView` is true. Returns a single-use websocket URL, valid about ten minutes, streaming the sign-in browser: the server sends JSON text frames `{"type":"frame","data":"<base64 JPEG>","meta":{"deviceWidth":…}}` and `{"type":"state","state":"live|finishing|ended","result":…}`; the client sends `{"type":"mouse","action":"mousePressed|mouseReleased|mouseMoved","x":…,"y":…}`, `{"type":"wheel","x":…,"y":…,"dx":…,"dy":…}`, `{"type":"key","key":…,"code":…,"keyCode":…}` or `{"type":"text","text":…}`. Coordinates are in the page's pixels (scale by `meta.deviceWidth`). When LinkedIn accepts the step the sender connects as usual (`account.connected`). Most integrators send their user to the hosted connect page instead, which shows this view itself. 409 with `live_view_unavailable` when there is no browser step to show, `live_view_not_ready` while the sign-in is still running (retry in a minute), and `live_view_expired` once it is no longer waiting.

Disconnect a sender DELETE

**JavaScript SDK:** [`swarmhit.accounts.disconnect(accountId, params?)`](/smart-api/sdk/methods#accounts) Disconnect a LinkedIn sender account: revoke its session, remove it from the workspace and free its seat. The inverse of connecting a sender (POST /accounts). From then on GET /accounts/{id} answers 404 and GET /accounts no longer lists it; no webhook is sent, unless an endpoint subscribes to `account.archived`. The account is archived: its conversations, settings (limits, warm-up) and history stay, listed by GET /accounts?archived=true, and POST /accounts/{id}/restore brings it back under the same id. Its login secrets (session cookie, password, 2FA key) are not kept: a restored account is reconnected like any other. Archived accounts are kept for 90 days, then deleted permanently; pass `permanent=true` to delete right away. With `permanent=true` the account is deleted for good, live or archived: its conversations and settings are erased (`account.deleted`). What it did in campaigns stays with the campaigns. Only a key created by an owner or admin of the workspace can do this (403 `not-allowed` otherwise).