URL: /code/apps/social/schedule · Id: `page:/code/apps/social/schedule`

# Post.schedule

> Queue a Post for a set minute, such as a Product Hunt launch one minute after midnight Pacific.

`POST https://api.sb/{your-domain}/posts/schedule`

Queue a [Post](https://startupbuilder.dev/business/nouns/post) for a set minute, such as a Product Hunt launch one minute after midnight Pacific.

- **Action class:** None
- **Approval:** Runs on its own
- **Emits:** `Post.scheduled`
- **Sites:** [5 sites](#on-each-venue)
- **Price:** Free

```text title="Run it · Ask"
Queue the Product Hunt launch for 12:01 a.m. Pacific on Wednesday, November 4.
```

```ts title="Run it · SDK"
import { $ } from 'startup-builder'

const result = await $.try.Post.schedule({ post: 'post_Ph7nW3cZ9a', at: '2026-11-04T08:01:00Z' })
```

```json title="Run it · Response"
{
  "api": "https://api.sb/leaseline.app",
  "post": {
    "$id": "https://api.sb/leaseline.app/posts/post_Ph7nW3cZ9a",
    "$type": "Post",
    "handle": "https://api.sb/leaseline.app/handles/handle_Ph2dK8mV4c",
    "format": "launch",
    "status": "scheduled",
    "publishAt": "2026-11-04T08:01:00Z"
  },
  "action": {
    "operation": "Post.schedule",
    "mode": "try",
    "status": "done"
  }
}
```

Puts a drafted Post on your account’s calendar for a set minute, such as 12:01 a.m. Pacific on launch day. [The hub’s definition of `Post.schedule`](https://startupbuilder.dev/business/nouns/post/schedule).</HubDefinition>

## Inputs
| Name | Type | Default | Meaning |
| --- | --- | --- | --- |
| `post` | `Post` | Required | The drafted Post. |
| `at` | `datetime` | Required | When it goes out. |

## Outputs
| Field | Type | What `null` means |
| --- | --- | --- |
| `post` | `Post` | Never null. |
| `post.status` | `string` | Never null: `scheduled` until `publishAt`, then `published`. |
| `post.publishAt` | `datetime` | Never null: the `at` sent, in UTC. |
| `post.handle` | `Handle` | Never null: the account it goes out from. |
| `post.format` | `string` | Never null: the network’s format, such as a launch or a thread. |

## Effects
**Action class**

None: no approval rule names it, so it runs within its seat’s Permissions and Limits

**Modes**

- `try`: Checks your account can post at `at` and returns the Post as it would sit on the calendar; nothing is queued.
- `send`: Returns the scheduled Post at once: the call settles before anything reaches the network.
- `do`: Returns the scheduled Post at once.

**Idempotency**

Only with a key: the same `Idempotency-Key` and input return the first Action, and the same key with other input returns `409`. Scheduling a scheduled Post again moves it to the new `at`; it never queues twice.

**Saved or shared**

The Post’s `publishAt` is set and its status reads `scheduled`. At `publishAt` it goes out and `Post.published` fires; `Post.withdraw` before then takes it off the calendar.

**Emits**

`Post.scheduled` with `{ post, handle, venue, publishAt }`

**Performed by**

[Content lead](https://startupbuilder.dev/agents/marketing/content-lead)

**Price**

Free on your own account: the platform charges nothing for the call.

## On each Venue
| Site | Fields | Formats |
| --- | --- | --- |
| [Facebook](#facebook) | `body`, `link`, `publishAt` | 1 |
| [Instagram](#instagram) | `body`, `format`, `media`, `publishAt` | 4 |
| [Product Hunt](#product-hunt) | `title`, `body`, `media`, `publishAt` | 1 |
| [TikTok](#tiktok) | `body`, `media` | 2 |
| [YouTube](#youtube) | `title`, `body`, `tags`, `publishAt` | 1 |

### Facebook
Through [Facebook](/code/integrations/facebook).

| Our field | Facebook’s field |
| --- | --- |
| `Post.body` | `message` |
| `Post.link` | `link` |
| `Post.publishAt` | `scheduled_publish_time` (Sent with published false) |

- **Your role on the page.** Posting needs a role that can post; a role removed in Meta’s settings ends the connection with `needs-reauth`.

Feed image ad, 1440 × 1800, 4:5

### Instagram
Through [Instagram](/code/integrations/instagram).

| Our field | Instagram’s field |
| --- | --- |
| `Post.body` | `caption` (2,200 characters, 30 hashtags, 20 mentions) |
| `Post.format` | `media_type` (IMAGE, CAROUSEL, REELS or STORIES) |
| `Post.media` | `image_url or video_url` (A carousel holds up to 20 items, cropped to the first one’s ratio) |
| `Post.publishAt` | `media_publish` (Instagram has no scheduled publish; the platform holds the Post and publishes it then) |

- **A staged post.** Instagram drops a staged post after 24 hours, so the agent stages it in the hour it publishes.
- **Account type.** A professional account; a personal account refuses with `account-not-connected` until it switches.

Feed image, 320 to 1,440 pixels wide, 4:5 to 1.91:1 Carousel Reel, 9:16 Story, 9:16

### Product Hunt
Through [Product Hunt](/code/integrations/product-hunt).

| Our field | Product Hunt’s field |
| --- | --- |
| `Post.title` | `name` |
| `Post.body` | `tagline` (60 characters: what it does and for whom) |
| `Post.media` | `thumbnail and gallery` (A square 240 × 240 thumbnail; the first gallery image is the link preview) |
| `Post.publishAt` | `launch date` (Product Hunt takes a day, and the launch goes live at 12:01 am Pacific that day) |

- **Launch time.** Launches go live at 12:01 am Pacific and the day’s ranking runs to midnight Pacific, so the agent schedules for 12:01 am.
- **Vote asks.** Your agent asks your list for feedback, never for upvotes.
- **Replies.** Every comment gets a drafted answer within 30 minutes for the first 6 hours.

Launch

### TikTok
Through [TikTok](/code/integrations/tiktok).

| Our field | TikTok’s field |
| --- | --- |
| `Post.body` | `post_info.title` (The caption: 2,200 characters, hashtags included) |
| `Post.media` | `source_info.source` (FILE_UPLOAD or PULL_FROM_URL) |

- **Clips waiting in your inbox.** At most 5 in any 24 hours; a sixth waits with `quota-reached` until one is posted.
- **Upload calls.** 6 a minute for your account; the platform queues the rest.

Video Spark Ad

### YouTube
Through [YouTube](/code/integrations/youtube).

| Our field | YouTube’s field |
| --- | --- |
| `Post.title` | `snippet.title` (100 characters, no < or >) |
| `Post.body` | `snippet.description` (5,000 bytes, so accented letters count double) |
| `Post.tags` | `snippet.tags` (500 characters in all, commas included) |
| `Post.publishAt` | `status.publishAt` (Sent with status.privacyStatus private) |

- **A scheduled video.** Uploads private and goes public at its time; YouTube allows a time only on a video never published before.
- **Comments.** Read every 30 minutes, since YouTube sends no webhook for comments.

Video

## What try does
| Account | What try does |
| --- | --- |
| [Facebook](/code/integrations/facebook#try) | Returns the post as your page will show it, with the time it goes live; nothing is posted or scheduled. |
| [Instagram](/code/integrations/instagram#try) | Checks each image and video against Instagram’s specs and returns the post as it will show; no container is staged and nothing publishes. |
| [Product Hunt](/code/integrations/product-hunt#try) | Returns the launch page as Product Hunt will show it, with the time it goes live in your time zone; nothing is scheduled. |
| [TikTok](/code/integrations/tiktok#try) | Checks the clip and caption against what your account reports it allows, and returns the post as it will show; nothing reaches your inbox. |
| [YouTube](/code/integrations/youtube#try) | Checks the file, title, description and tags against YouTube’s limits and returns the video page as it will read; nothing uploads and no quota is spent. |

## Refuses when
This call has no refusals of its own. Every call through an account can also meet [the shared account refusals](/code/refusals#accounts): [`grant-missing`](/code/refusals#grant-missing), [`needs-reauth`](/code/refusals#needs-reauth), [`account-not-connected`](/code/refusals#account-not-connected), [`over-mandate`](/code/refusals#over-mandate), [`quota-reached`](/code/refusals#quota-reached), [`venue-rejected`](/code/refusals#venue-rejected).

## When it waits
Returns in one response; nothing waits.

## Example

**Ask**

```text
Queue the Product Hunt launch for 12:01 a.m. Pacific on Wednesday,
November 4.
```

**API**

```bash
curl -X POST "https://api.sb/leaseline.app/posts/schedule?mode=try" \
  -H "Authorization: Bearer $SB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"post":"post_Ph7nW3cZ9a","at":"2026-11-04T08:01:00Z"}'
```

The response is the one in the Run it window above.

**CLI**

```bash
npx startup-builder do Post.schedule --try --data '{"post":"post_Ph7nW3cZ9a","at":"2026-11-04T08:01:00Z"}'
```

**MCP**

```json
{
  "name": "do",
  "arguments": {
    "mode": "try",
    "code": "return await $.Post.schedule({ post: 'post_Ph7nW3cZ9a', at: '2026-11-04T08:01:00Z' })"
  }
}
```

**SDK**

```ts
import { $ } from 'startup-builder'

const result = await $.try.Post.schedule({
  post: 'post_Ph7nW3cZ9a',
  at: '2026-11-04T08:01:00Z',
})
```

To retry, send the same `Idempotency-Key`: the retry returns the first answer for $0. A new key reads again.

A `sk_test_` key answers these the same way every time, at $0 ([every test value](/code/data#test-values)).

| Test value | Always returns | What it is for |
| --- | --- | --- |
| `post_test_launch` | `{"status":"scheduled","publishAt":"2026-11-04T08:01:00Z"}` | Queues on a test account and never publishes, so a launch-day Workflow runs end to end before the real one. |
| `maxCost: 0.0001` | Refuses with [`max-cost`](/code/refusals#max-cost) | Any priced call with a maxCost of 0.0001 is refused before it spends: the price is above the cap. |
| `rate-limited.test` | Refuses with [`rate-limited`](/code/refusals#rate-limited) | Any call naming this hostname answers 429 with Retry-After, so your retry logic runs. |
| `sources-busy.test` | Refuses with [`sources-busy`](/code/refusals#sources-busy) | Any call naming this hostname answers 503 as if every route were busy, and nothing is spent. |

## Used by
- **Agent tasks:** [Founder posts](/capabilities/publish-and-post/founder-posts)
- **Jobs:** [Publish and post](/capabilities/publish-and-post)
- **Integrations:** [Facebook](/code/integrations/facebook) · [Instagram](/code/integrations/instagram) · [Product Hunt](/code/integrations/product-hunt) · [TikTok](/code/integrations/tiktok) · [YouTube](/code/integrations/youtube)

## Related
[`Post.publish`](/code/apps/social/publish)