# Publish to LinkedIn

> Publish text or one image to a connected LinkedIn profile or organization Page.

Canonical: <https://www.tryadeli.com/docs/api/posts/publish-linkedin>

`POST https://app.tryadeli.com/api/v1/posts`

Authorization: `Bearer <API key>` — see [Authentication](https://www.tryadeli.com/docs/authentication)

LinkedIn publishing is a private preview. Connect a LinkedIn account first: either the member's personal profile or an organization Page they administer. Then publish commentary, one image, or both. The post is public and LinkedIn publishes it synchronously.

> **Warning: Development Tier**
>
> LinkedIn is available only in development and beta while Adeli has Community Management Development Tier access. The shared app is limited to 500 calls per day and each member to 100 calls per day. It is not enabled in production.

**Body**

| Name         | Type         | Required | Description                                                                                                                                                                                         |
| ------------ | ------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `platform`   | `"linkedin"` | Yes      |                                                                                                                                                                                                     |
| `accountId`  | `uuid`       | Yes      | A connected LinkedIn account in your workspace: a personal profile or an organization Page.                                                                                                         |
| `profileId`  | `uuid`       |          | Optional because accountId names its profile. If both are sent, they must agree.                                                                                                                    |
| `commentary` | `string`     | Yes      | The public post text. Send `""` for an image-only post.                                                                                                                                             |
| `image`      | `object`     |          | One `{ content_type, base64, title? }` image. The content type is `image/jpeg`, `image/png`, or `image/gif`; decoded size is at most 20 MB and the image must contain fewer than 40 million pixels. |

For an image post, add:

```json
{
  "image": {
    "content_type": "image/png",
    "base64": "iVBORw0KGgo…",
    "title": "Product update"
  }
}
```

Adeli does not automatically retry post creation: if LinkedIn's answer is ambiguous, retrying could publish a duplicate. An expired connection returns `connection_expired`; reconnect the account before publishing again.

## Request examples

**cURL**

```bash
curl -X POST "https://app.tryadeli.com/api/v1/posts" \
  -H "Authorization: Bearer $ADELI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "platform": "linkedin",
  "accountId": "00000000-0000-0000-0000-000000000000",
  "commentary": "We just shipped a faster publishing workflow."
}'
```

**JavaScript**

```javascript
const response = await fetch("https://app.tryadeli.com/api/v1/posts", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ADELI_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    platform: "linkedin",
    accountId: "00000000-0000-0000-0000-000000000000",
    commentary: "We just shipped a faster publishing workflow.",
  }),
});
console.log(await response.json());
```

**Python**

```python
import os

import requests

response = requests.post(
    "https://app.tryadeli.com/api/v1/posts",
    headers={"Authorization": f"Bearer {os.environ['ADELI_API_KEY']}"},
    json={
        "platform": "linkedin",
        "accountId": "00000000-0000-0000-0000-000000000000",
        "commentary": "We just shipped a faster publishing workflow.",
    },
)
print(response.json())
```

## Responses

### 201

```json
{
  "id": "linkedin_post_00000000-0000-0000-0000-000000000000_dXJuOmxpOnNoYXJlOjEyMw",
  "platform": "linkedin",
  "accountId": "00000000-0000-0000-0000-000000000000",
  "profileId": "00000000-0000-4000-8000-000000000001",
  "status": "published",
  "providerId": "urn:li:share:123",
  "caption": "We just shipped a faster publishing workflow.",
  "media": [],
  "permalink": "https://www.linkedin.com/feed/update/urn:li:share:123/",
  "engagement": { "likes": null, "comments": null, "shares": null, "views": null },
  "publishedAt": "2026-10-23T18:00:00.000Z"
}
```

### 403

```json
{ "error": { "code": "permission_required", "message": "LinkedIn denied the post: the account needs an eligible Page role or an additional permission. Reconnect after restoring access." } }
```

### 429

```json
{ "error": { "code": "rate_limited", "message": "LinkedIn rate limit reached; retry later", "details": { "retryAfterSeconds": 60 } } }
```
