---
title: "Create post"
description: "Create a post to one or more connected accounts. Returns 202 with the post id."
section: "API reference"
url: https://dravo.dev/docs/api/posts/create
---
# Create post

Send the target accounts and the content. Returns `202` with the post `id`; the
post is delivered in the background. Tune each network with `platform_options`;
the accepted keys and per-platform fields are listed below.

#### `POST /v1/posts`

Create a unified post to one or more connected accounts. Returns immediately (202) and delivers asynchronously.

**Auth:** API key (`dra_…`) or dashboard JWT

| Field | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `account_ids` | body | string[] | yes | 1 to 100 connected account IDs to publish to. |
| `text` | body | string | yes | Post body, 1 to 5000 chars. |
| `media_urls` | body | string[] | no | Public URLs of images/videos, ideally ingested first via POST /v1/media. |
| `platform_options` | body | object | no | Typed per-platform overrides keyed by platform name. Accepted root keys: facebook, instagram, tiktok, linkedin, x. Unknown platform keys and unknown option names are rejected before queueing. |
| `scheduled_at` | body | string (ISO 8601) | no | If set, schedule the job. Must be timezone-aware and at least 60 seconds in the future. |

Request:

```json
{
  "account_ids": [
    "acc_8f2c1d",
    "acc_4b9e07"
  ],
  "text": "Shipping Dravo: one API for every social network.",
  "media_urls": [
    "https://cdn.dravo.dev/u/abc/cover.jpg"
  ],
  "platform_options": {
    "facebook": {
      "as_reel": true
    },
    "tiktok": {
      "privacy_level": "SELF_ONLY"
    }
  }
}
```

Response `202`: Post accepted and queued (or scheduled).

```json
{
  "id": "post_2a7f93",
  "status": "queued",
  "scheduled_at": null
}
```

Errors:

- `400`: Validation error (empty text, no account_ids, scheduled_at in the past).
- `401`: Missing or invalid API key / JWT.


## Per-platform options

Use `platform_options` when one platform needs behavior that does not exist on
the others: TikTok privacy, Facebook Reel mode, Instagram Stories, LinkedIn link
previews, X polls, and similar platform-specific controls. The object is keyed by
platform and validated before Dravo creates the publish job.

**Request validation.** `platform_options` is strict. The accepted root keys are `facebook`, `instagram`, `tiktok`, `linkedin` and `x`. Unknown roots like `threads`, legacy `meta`, and typos like `firstComent` are rejected before the post is queued.

### Facebook

Root key: `platform_options.facebook`

Use these when publishing to Facebook Pages, especially video posts that should become Reels.

| Field | Type | Behavior |
| --- | --- | --- |
| `as_reel` | boolean | Publishes an eligible video as a Facebook Reel instead of a normal feed video. |
| `first_comment` | string | Posts a first comment after the post is created. If the comment fails, the post can still publish and the result includes a warning. |

Example:

```json
{
  "platform_options": {
    "facebook": {
      "as_reel": true,
      "first_comment": "Full details in the first comment."
    }
  }
}
```

### Instagram

Root key: `platform_options.instagram`

Use these for feed, Reel and Story-specific behavior, plus Instagram tagging metadata.

| Field | Type | Behavior |
| --- | --- | --- |
| `story` | boolean | Publishes the media as an Instagram Story instead of a feed post or Reel. |
| `first_comment` | string | Posts a first comment after publishing. Commonly used for hashtags; reported as a warning if it cannot be created. |
| `share_to_feed` | boolean | Shows a Reel in the main feed when the platform supports it. |
| `location_id` | string | Attaches an Instagram location id to the container. |
| `user_tags` | object \| object[] \| string | Tags Instagram accounts in the media. Each tag includes username plus x and y coordinates from 0 to 1. |
| `collaborators` | string \| string[] | Requests collaborator accounts for eligible Instagram posts. |
| `alt_text` | string | Sets accessibility text for supported Instagram media. |
| `cover_url` | string | Uses a public image URL as the Reel cover. |
| `thumb_offset` | integer | Selects a video thumbnail frame by offset in milliseconds. |
| `audio_name` | string | Sets the audio label for eligible Reel publishing flows. |

Example:

```json
{
  "platform_options": {
    "instagram": {
      "story": false,
      "share_to_feed": true,
      "first_comment": "#launch #socialapi",
      "location_id": "17841400000000000",
      "user_tags": [
        {
          "username": "dravo",
          "x": 0.5,
          "y": 0.5
        }
      ],
      "collaborators": [
        "17841411111111111"
      ],
      "alt_text": "Short product demo video",
      "cover_url": "https://cdn.acme.com/cover.jpg",
      "thumb_offset": 1200,
      "audio_name": "Original audio"
    }
  }
}
```

For user_tags, username is the Instagram account to tag. x is the horizontal position and y is the vertical position inside the media: x = 0 is left, x = 1 is right, y = 0 is top, and y = 1 is bottom. The example x: 0.5, y: 0.5 tags @dravo in the center.

### TikTok

Root key: `platform_options.tiktok`

Use these for direct publish vs upload mode, privacy, interaction controls and branded content flags.

| Field | Type | Behavior |
| --- | --- | --- |
| `post_mode` | "DIRECT_POST" \| "MEDIA_UPLOAD" | Chooses whether Dravo publishes directly or uploads media to the creator inbox/draft-style flow. |
| `privacy_level` | "PUBLIC_TO_EVERYONE" \| "MUTUAL_FOLLOW_FRIENDS" \| "FOLLOWER_OF_CREATOR" \| "SELF_ONLY" | Sets TikTok visibility. The selected value must be allowed for the creator account. |
| `disable_comment` | boolean | Disables comments when TikTok allows that setting. |
| `disable_duet` | boolean | Disables Duet for eligible video posts. |
| `disable_stitch` | boolean | Disables Stitch for eligible video posts. |
| `is_aigc` | boolean | Labels the post as AI-generated content. |
| `brand_content_toggle` | boolean | Marks the post as branded or paid partnership content. |
| `brand_organic_toggle` | boolean | Marks the post as organic content from the creator's own brand. |
| `auto_add_music` | boolean | Lets TikTok add background music to eligible photo posts. |
| `video_cover_timestamp_ms` | integer >= 0 | Selects the cover frame for a video by timestamp in milliseconds. |
| `photo_cover_index` | integer >= 0 | Selects the cover image index for a photo carousel. |
| `first_comment` | string | Accepted in the request shape for consistency, but TikTok does not support creating comments through the publish API; Dravo reports it as a warning. |

Example:

```json
{
  "platform_options": {
    "tiktok": {
      "post_mode": "DIRECT_POST",
      "privacy_level": "SELF_ONLY",
      "disable_comment": false,
      "disable_duet": true,
      "disable_stitch": true,
      "is_aigc": true,
      "brand_content_toggle": false,
      "brand_organic_toggle": true,
      "auto_add_music": true,
      "video_cover_timestamp_ms": 1500,
      "photo_cover_index": 0
    }
  }
}
```

### LinkedIn

Root key: `platform_options.linkedin`

Use these for visibility, reshare behavior, image accessibility and link article previews.

| Field | Type | Behavior |
| --- | --- | --- |
| `visibility` | "PUBLIC" \| "CONNECTIONS" | Controls whether the post is public or limited to connections. |
| `disable_reshare` | boolean | Disables resharing when the LinkedIn API supports it. |
| `alt_texts` | string[] | Sets alt text per image, by media index. |
| `article.source` | string | Required URL when sharing a link preview through the article object. |
| `article.title` | string | Optional article preview title. |
| `article.description` | string | Optional article preview description. |
| `article.thumbnail` | string | Optional public image URL for the article preview thumbnail. |
| `author` | string | Advanced override for the author URN. Most integrations should let Dravo derive this from the connected account. |
| `first_comment` | string | Posts a first comment after publishing. Failures are reported as warnings. |

Example:

```json
{
  "platform_options": {
    "linkedin": {
      "visibility": "PUBLIC",
      "disable_reshare": false,
      "alt_texts": [
        "Dashboard screenshot"
      ],
      "article": {
        "source": "https://dravo.dev/blog/social-media-api-for-ai-agents",
        "title": "Social media APIs for AI agents",
        "description": "A practical guide to publishing from agents.",
        "thumbnail": "https://cdn.acme.com/article-thumb.jpg"
      },
      "author": "urn:li:person:abc123",
      "first_comment": "Extra implementation notes below."
    }
  }
}
```

### X

Root key: `platform_options.x`

Use these for polls, reply controls, quote/thread behavior and X-specific post metadata.

| Field | Type | Behavior |
| --- | --- | --- |
| `poll.options` | string[]; 2 to 4 items | Creates a poll. Poll posts cannot include media in the same X request. |
| `poll.duration_minutes` | integer; 5 to 10080 | Sets how long the poll stays open. |
| `first_comment` | string | Posts a reply to the new post after publishing. Failures are reported as warnings. |
| `reply_settings` | "following" \| "mentionedUsers" \| "subscribers" \| "verified" | Controls who can reply to the post. |
| `reply_to` | string | Publishes the post as a reply to an existing X post id. |
| `place_id` | string | Attaches an X place id when available for the account/app. |
| `for_super_followers_only` | boolean | Restricts the post to subscribers when the account supports it. |
| `made_with_ai` | boolean | Marks the post with X-specific AI-generated metadata when supported. |

Example:

```json
{
  "platform_options": {
    "x": {
      "poll": {
        "options": [
          "Ship now",
          "Schedule it"
        ],
        "duration_minutes": 60
      },
      "reply_settings": "following",
      "reply_to": "1890123456789012345",
      "place_id": "00a0000000000000",
      "first_comment": "Follow-up context.",
      "for_super_followers_only": false,
      "made_with_ai": true
    }
  }
}
```
