> ## Documentation Index
> Fetch the complete documentation index at: https://docs.indm.social/llms.txt
> Use this file to discover all available pages before exploring further.

# Line up automations for the posts you've scheduled

> Set up each post's automation before it goes live, and let each one catch its own post.

If you schedule posts ahead, you can set up each one's automation ahead too. Create an automation with `binding: "next"` and a `starts_at` just before the post's publish time, set it live, and it runs on the first post published from that time on. No `media_id`, because the post doesn't exist yet.

You need a `full` key on a Growth workspace, and the account's id from [List accounts](https://docs.indm.social/api-reference/accounts/list-accounts.md) if the workspace has more than one.

**1. Create one automation per scheduled post**

[Create an automation](https://docs.indm.social/api-reference/automations/create-automation.md) with `binding: "next"` and `starts_at` set a few minutes before the post's scheduled time. `starts_at` is RFC 3339 with an offset, so `2026-11-13T17:55:00+05:30` and `2026-11-13T12:25:00Z` are the same moment.

**2. Set each one live**

[Set it live](https://docs.indm.social/api-reference/automations/set-automation-status.md). From then on it waits. Nothing is sent until a post it can catch is published and someone comments.

**3. Check which post each one caught**

While it waits, [Get an automation](https://docs.indm.social/api-reference/automations/get-automation.md) returns `binding: "next"` and its `starts_at`. Once it has caught its post, `binding` is `specific` and `media_id` names the post.

## How posts are shared out

Several automations can wait at once, and each new post goes to exactly one of them:

1. Automations with a `starts_at` go first, earliest `starts_at` first. Each catches the first post published at or after its time.
2. Then automations without one, in the order they went live.
3. A post that already has a live automation of its own is skipped, and the waiting one keeps waiting.

So three automations for posts scheduled on Monday, Wednesday and Friday, each with a `starts_at` just before its post, catch those three posts in order. Five automations with no `starts_at` catch your next five posts.

> [!NOTE]
>
> Start a few minutes early. An automation catches the first post published at or after `starts_at`, so a start slightly before the scheduled time is always safe, and one a minute after it would miss the post and take the next one.

## The whole flow

```javascript Node theme={null}
const API = "https://api.indm.social/v1";
const headers = {
  Authorization: `Bearer ${process.env.INDM_API_KEY}`,
  "Content-Type": "application/json",
};

async function call(method, path, body) {
  const res = await fetch(API + path, {
    method,
    headers,
    body: body ? JSON.stringify(body) : undefined,
  });
  const json = await res.json();
  if (!res.ok) throw new Error(`${json.error.code}: ${json.error.message}`);
  return json;
}

// One entry per post you've scheduled, with a start a few minutes early.
const scheduled = [
  { startsAt: "2026-11-16T17:55:00+05:30", keyword: "GUIDE", dm: "Here's the guide.", link: "https://example.com/guide" },
  { startsAt: "2026-11-18T17:55:00+05:30", keyword: "PRESET", dm: "Here are the presets.", link: "https://example.com/presets" },
];

for (const post of scheduled) {
  const automation = await call("POST", "/automations", {
    binding: "next",
    starts_at: post.startsAt,
    account_id: process.env.INDM_ACCOUNT_ID, // optional with one connected account
    keywords: [post.keyword],
    dm_message: post.dm,
    link_url: post.link,
  });
  await call("POST", `/automations/${automation.id}/status`, { status: "live" });
  console.log(automation.id, "waits from", automation.starts_at);
}
```

```python Python theme={null}
import os
import requests

API = "https://api.indm.social/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['INDM_API_KEY']}"}

def call(method, path, body=None):
    res = requests.request(method, API + path, headers=HEADERS, json=body)
    data = res.json()
    if not res.ok:
        raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
    return data

# One entry per post you've scheduled, with a start a few minutes early.
scheduled = [
    {"starts_at": "2026-11-16T17:55:00+05:30", "keyword": "GUIDE", "dm": "Here's the guide.", "link": "https://example.com/guide"},
    {"starts_at": "2026-11-18T17:55:00+05:30", "keyword": "PRESET", "dm": "Here are the presets.", "link": "https://example.com/presets"},
]

for post in scheduled:
    automation = call("POST", "/automations", {
        "binding": "next",
        "starts_at": post["starts_at"],
        "account_id": os.environ.get("INDM_ACCOUNT_ID"),  # optional with one connected account
        "keywords": [post["keyword"]],
        "dm_message": post["dm"],
        "link_url": post["link"],
    })
    call("POST", f"/automations/{automation['id']}/status", {"status": "live"})
    print(automation["id"], "waits from", automation["starts_at"])
```

## What can go wrong

| Code | Why |
| - | - |
| `next_post_requires_paid_plan` | Automations that wait for your next post are part of Growth. Attach it to a published post with `media_id` instead. |
| `account_id_required` | The workspace has more than one account. Say whose next post it waits for. |
| `starts_at_invalid` | `starts_at` has no offset, or isn't a time. Send it as RFC 3339, like `2026-11-13T17:55:00+05:30`. |
| `media_id_with_next_binding` | You sent both. A `next` binding has no post yet. |

The response's `caveats` include `starts_at_passed` when the time you sent has already gone by. The automation is saved and catches the first post published after it's set live.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.