<!-- https://cutedyno.com/docs/api/publish-post -->

# Publish a post

`POST https://api.cutedyno.com/v1/posts/{id}/publish`

Moves a draft into the publishing queue. When the profile or key requires approval, the post waits for an approver instead.



Required permission: `posts:write`

Accepts `profileId` to target a specific profile. Omit it to use the key’s home profile.

Required permission: `posts:write`

Accepts an `Idempotency-Key` header.

MCP tool: `publish_post`

## Path parameters

- `id` (string, required) — Post id.

## Body

- `profileId` (string) — Profile to act on. Defaults to the profile the API key was created in.
- `scheduledAt` (string) — ISO 8601 datetime, for example 2026-08-01T12:00:00Z.
- `approvers` (string[]) — Emails to request approval from. Defaults to the key owner when approval is required.

## Request

```bash
curl -X POST "https://api.cutedyno.com/v1/posts/POST_ID/publish" \
  -H "Authorization: Bearer $CUTEDYNO_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "profileId": "profile_a1b2c3d4",
  "scheduledAt": "string",
  "approvers": [
    "string"
  ]
}'
```

```typescript
import { CuteDyno } from '@cutedyno/node';

const cutedyno = new CuteDyno();

const result = await cutedyno.posts.publish('POST_ID', {
  profileId: "profile_a1b2c3d4",
  scheduledAt: "string",
  approvers: [
    "string"
  ]
});
console.log(result);
```

```python
import os
import requests

url = "https://api.cutedyno.com/v1/posts/POST_ID/publish"
headers = {"Authorization": f"Bearer {os.environ['CUTEDYNO_API_KEY']}"}

payload = {
    "profileId": "profile_a1b2c3d4",
    "scheduledAt": "string",
    "approvers": [
        "string"
    ]
}

response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
print(response.json())
```

## Response 200

- `post` (object, required)

```json
{
  "post": {
    "id": "a1b2c3d4-0000-4000-8000-000000000000",
    "status": "draft",
    "profileId": "profile_a1b2c3d4"
  }
}
```

## Errors

- `invalid_state_transition` (400) — The post is in a state that does not allow this operation, for example editing a post that already published.
- `key_not_linked_to_user` (400) — Publishing records a human actor. Recreate the key from the dashboard so it carries an owner.
- `invalid_api_key` (401) — The key does not exist, was revoked, or is malformed. Keys start with cdyn_live_.
- `approval_required` (403) — This profile or key forces posts through review, and no approver could be determined. Supply approvers, or recreate the key so it carries an owner.
- `not_found` (404) — The resource does not exist inside the resolved profile.
- `rate_limit_exceeded` (429) — Too many requests for this key. Honour the Retry-After header before retrying.
- `internal_error` (500) — Something failed on our side. Retry with the same Idempotency-Key; report the requestId if it persists.