# Publish a Held Post

> Send a draft or scheduled post to its platforms now

- **URL**: https://orshot.com/docs/api-reference/social-post-publish

---

## Overview

Publishes a draft or scheduled post immediately, to the accounts it already targets. This is the step that puts the post in front of an audience, and it cannot be undone through Orshot.

To change what goes out, [edit the post](https://orshot.com/docs/api-reference/social-post-update) first.

```markdown tab="Endpoint"
https://api.orshot.com/v1/social/posts/{postId}/publish
```

## Request

**Request**
```js
await fetch("https://api.orshot.com/v1/social/posts/512/publish", {
  method: "POST",
  headers: {
    Authorization: "Bearer <ORSHOT_API_KEY>",
  },
});
```

**Response**
```json
{
  "data": {
    "post": {
      "id": 512,
      "status": "published",
      "content": "Our new pricing is live.",
      "is_editable": false,
      "published_at": "2026-08-11T18:02:11.412+00:00"
    },
    "status": "published",
    "platforms": [
      {
        "account_id": 15,
        "platform": "linkedin",
        "username": "acme-inc",
        "name": "Acme Inc",
        "status": "published",
        "url": "https://linkedin.com/feed/update/urn:li:share:1234567890"
      },
      {
        "account_id": 22,
        "platform": "twitter",
        "username": "acmehq",
        "name": "Acme",
        "status": "published",
        "url": "https://twitter.com/acmehq/status/1234567890"
      }
    ]
  }
}
```

No request body is needed — the post already carries its caption, media and accounts.

## Response Fields

| Field                | Type   | Description                                                             |
| -------------------- | ------ | ------------------------------------------------------------------------- |
| `post`               | Object | The updated post. See [List Social Posts](https://orshot.com/docs/api-reference/social-posts-list) |
| `status`             | String | Overall outcome: `published`, `processing`, `partial` or `failed`         |
| `platforms`          | Array  | Per-account results                                                       |
| `platforms[].url`    | String | Link to the live post, when the platform returns one immediately          |
| `platforms[].error`  | String | Why an account failed                                                     |
| `platforms[].action` | String | Suggested recovery, e.g. `reconnect` for an expired token                 |

A `processing` status means every targeted platform publishes asynchronously and the post is still in flight. [Sync the post](https://orshot.com/docs/api-reference/social-post-get) to pick up the final URLs.

A `partial` status means some accounts succeeded and others did not — check each entry in `platforms`.

## Error Responses

### Post already sent (400)

```json
{
  "error": "Only draft or scheduled posts can be published"
}
```

### Not found (404)

```json
{
  "error": "Post not found"
}
```

### Publish failed (500)

```json
{
  "error": "Failed to publish post",
  "message": "Account token expired — reconnect required"
}
```

## Rate Limits

- 20 requests per minute per workspace, shared across all social endpoints