# LinkedIn accounts

> Connect the LinkedIn accounts of your workspace with a secure link, follow their state and get a webhook when one disconnects.

Source: https://docs.emelia.io/docs/linkedin-accounts

Connect a LinkedIn account without handling its credentials: you create a link, the person opens it and logs in to LinkedIn on an Emelia page. The account then appears in your workspace, ready to send.

## The flow

1. **Create a link** and forward it to the person.
2. **Follow the link** until `status` is `accepted`, and keep `accountId`.
3. **Use the account** as the `linkedin` value of a campaign identity.
4. **Register a webhook** to know when an account must be reconnected.

The routes act on the workspace of the API key. Each new account takes a LinkedIn slot of the subscription: without a free slot the link is refused with `LINKEDIN_ACCOUNT_LIMIT_REACHED`.

## Create a link

[`POST /linkedin/invitations`](https://docs.emelia.io/docs/linkedin-accounts/create-connection-link.md)

```bash
curl -X POST "https://api.emelia.io/linkedin/invitations" \
  -H "Authorization: $EMELIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "claire.fontaine@nexora.io", "sendEmail": false}'
```

```json
{
  "success": true,
  "token": "7b1f0c52-4d7e-4a3a-9a55-0f3ad1c2b8e1",
  "url": "https://app.emelia.io/linkedin-connect/7b1f0c52-4d7e-4a3a-9a55-0f3ad1c2b8e1",
  "expiresAt": "2026-11-11T10:00:00.000Z"
}
```

The link is valid for 7 days. Asking again for the same `email` returns the same link with a new expiry date.

## Follow the link

[`GET /linkedin/invitations/{token}`](https://docs.emelia.io/docs/linkedin-accounts/get-state-of-connection-link.md)

| `status`               | Meaning                                                                     |
| ---------------------- | --------------------------------------------------------------------------- |
| `wait_for_credentials` | The link was not used yet.                                                  |
| `pending`              | LinkedIn is waiting for a verification: a code, or a validation in its app. |
| `accepted`             | The account is connected, `accountId` is its id.                            |
| `failed`               | The connection failed. The link can be used again until it expires.         |
| `expired`              | Create a new link.                                                          |

## List the accounts

[`GET /linkedin/accounts`](https://docs.emelia.io/docs/linkedin-accounts/list-linkedin-accounts.md)

| `status`       | Meaning                                 |
| -------------- | --------------------------------------- |
| `active`       | The account can send.                   |
| `connecting`   | A LinkedIn verification is in progress. |
| `disconnected` | The account must be reconnected.        |
| `disabled`     | No LinkedIn slot for this account.      |

## Use the account in a campaign

Set `id` as the `linkedin` value of an identity, while the campaign is not running:

[`PATCH /advanced/campaigns/{campaignId}/identities`](https://docs.emelia.io/docs/campaigns/set-sender-identities.md)

```bash
curl -X PATCH "https://api.emelia.io/advanced/campaigns/$CAMPAIGN_ID/identities" \
  -H "Authorization: $EMELIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"identities": [{"name": "Claire Fontaine", "linkedin": "6650f1a2b839d80011c5a0bb"}]}'
```

## Know when an account disconnects

[`POST /account-webhooks`](https://docs.emelia.io/docs/linkedin-accounts/register-account-webhook.md)

```bash
curl -X POST "https://api.emelia.io/account-webhooks" \
  -H "Authorization: $EMELIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://hooks.acme.com/emelia/9f2c4e1a7b", "events": ["LINKEDIN_ACCOUNT_DISCONNECTED"]}'
```

Your URL then receives this JSON:

```json
{
  "event": "LINKEDIN_ACCOUNT_DISCONNECTED",
  "account": {
    "id": "6650f1a2b839d80011c5a0bb",
    "name": "Claire Fontaine",
    "handle": "claire-fontaine"
  },
  "date": "2026-11-05T10:05:00.000Z"
}
```

* Emelia checks the accounts every 5 minutes.
* The event is sent once per disconnection. An account already disconnected when you register the URL is reported once.
* There is no retry on HTTP errors, and a single retry on a network error. If you cannot miss an event, also read `GET /linkedin/accounts` regularly.
* `POST /account-webhooks/test` sends an example event, with `test: true`, to a registered URL.

## Reconnect an account

Create a link with `authId`. The link updates this account instead of adding a new one, so its campaigns keep it:

```bash
curl -X POST "https://api.emelia.io/linkedin/invitations" \
  -H "Authorization: $EMELIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "claire.fontaine@nexora.io", "sendEmail": false, "authId": "6650f1a2b839d80011c5a0bb"}'
```
