# Publish posts

URL: https://docs.hanzo.ai/docs/openapi/social/post-social-posts-by-id-publish

> Publishes the post immediately to the connected accounts on its channel and answers with the updated row, carrying the account and external id it published under.

`POST /v1/social/posts/{id}/publish`

> [Social →](https://docs.hanzo.ai/docs/openapi/social) · [All API references →](https://docs.hanzo.ai/docs/openapi) · [Get started →](https://docs.hanzo.ai/docs/guides)

|               |                                                     |
| ------------- | --------------------------------------------------- |
| **Address**   | `https://api.hanzo.ai/v1/social/posts/{id}/publish` |
| **Method**    | `POST`                                              |
| **Operation** | `post_social_posts_by_id_publish`                   |
| **Auth**      | `Authorization: Bearer $HANZO_API_KEY`              |

Publishes the post immediately to the connected accounts on its channel
and answers with the updated row, carrying the account and external id it
published under.

It is IDEMPOTENT: a post that has already published, or that another caller is
publishing right now, comes back unchanged rather than being posted twice. That
claim is taken before any network call, which is what makes a double submit safe.

The two failure shapes differ on purpose. Having no connected account for the
channel is the caller's to fix, so it is recorded ON the post as failed with the
reason and answers normally. A deployment that lacks the network's own credentials
cannot publish for anyone, so that is a 503 naming exactly what is missing.

## Request

1 field.

| Field | In   | Type   | Required | Description                                               |
| ----- | ---- | ------ | -------- | --------------------------------------------------------- |
| `id`  | path | string | yes      | ID is the account or post to act on, taken from the path. |

## Response

| Status    | Body              | Meaning |
| --------- | ----------------- | ------- |
| `200`     | social.socialPost | ok      |
| `default` | problem-details   | refused |

`200` body — 11 fields.

| Field        | In   | Type            | Always | Description                                                                                                                                                                                                                                                       |
| ------------ | ---- | --------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `accountId`  | body | string          | —      | AccountID / ExternalID / Error are server-managed publish results, set only by the publish path (never by a client update): the account a post was published through, the provider's returned external post id (for reconciliation), and the last failure reason. |
| `channel`    | body | string          | —      | Channel is the network this post targets: x, facebook, instagram, linkedin, tiktok, youtube or threads.                                                                                                                                                           |
| `content`    | body | string          | —      | Content is the post's text, bounded at 8192 characters.                                                                                                                                                                                                           |
| `createdAt`  | body | integer (int64) | —      | CreatedAt is when the post was created, as a unix timestamp in seconds.                                                                                                                                                                                           |
| `error`      | body | string          | —      | Error is why the last publish attempt failed, verbatim and bounded.                                                                                                                                                                                               |
| `externalId` | body | string          | —      | ExternalID is the id the network returned for the published post, which is what reconciles this row against the post on the network.                                                                                                                              |
| `id`         | body | string          | —      | ID is the post's identifier, minted on create and the id every later call addresses it by.                                                                                                                                                                        |
| `media`      | body | string\[]       | —      | Media is the post's attached media as a list of URLs (images today; the composer's URL field now, an S3 picker later, populate it).                                                                                                                               |
| `scheduleAt` | body | integer (int64) | —      | ScheduleAt is when the post is due, as a unix timestamp in SECONDS.                                                                                                                                                                                               |
| `status`     | body | string          | —      | Status is the post's lifecycle state: draft, scheduled, published or failed.                                                                                                                                                                                      |
| `updatedAt`  | body | integer (int64) | —      | UpdatedAt is when the post row last changed, as a unix timestamp in seconds.                                                                                                                                                                                      |

Failure carries the platform error shape — see [Errors](https://docs.hanzo.ai/docs/errors).

## Examples

**CLI**

```bash
hanzo social posts publish <id>
```

**SDK**

**.ts**

```ts
import { Configuration, SocialApi } from 'hanzoai';

const api = new SocialApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postSocialPostsByIdPublish({ id: 'id' });
```

**.py**

```python
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import SocialApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = SocialApi(client).post_social_posts_by_id_publish(id='id')
```

**.go**

```go
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.SocialAPI.PostSocialPostsByIdPublish(context.Background()).Execute()
if err != nil {
	return err
}
```

**.rs**

```rust
use hanzo_client::apis::{configuration::Configuration, social_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = social_api::post_social_posts_by_id_publish(&cfg, Default::default()).await?;
```

**.java**

```java
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.SocialApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new SocialApi(client).postSocialPostsByIdPublish();
```

**HTTP**

```bash
curl -X POST https://api.hanzo.ai/v1/social/posts/<id>/publish \
  -H "Authorization: Bearer $HANZO_API_KEY"
```

**MCP**

MCP reaches **social** through the `social` tool, which names its 13 operations with its own verbs — this one among them, under a name only MCP declares. `describe` explains any of them:

```bash
curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "list_social_accounts"
         }
       }
     }'
```

---

[Social API](https://docs.hanzo.ai/docs/openapi/social) · [All Hanzo APIs](https://docs.hanzo.ai/docs/openapi) · [Interactive reference](https://docs.hanzo.ai/docs/openapi/reference)
