# Post to social media from Make

> Index of all OmniSocials docs pages: https://docs.omnisocials.com/llms.txt

Make (make.com) can create OmniSocials posts with the **HTTP** app and its **Make a request** module. The module calls the REST API, so any trigger in Make can schedule or publish a post: a new row in a sheet, a new item in a feed, a form submission.

This guide uses version 4 of the HTTP app, the current one. It keeps the API key in a keychain, outside the module.

## Before you start

- An OmniSocials account with at least one social account connected (**Settings → Organisation → Workspaces**). Accounts cannot be connected through the API.
- An API key from **Settings → API** with the `posts:write` and `accounts:read` scopes. See [Authentication](https://docs.omnisocials.com/authentication.md).
- A Make scenario with a trigger.

## 1. Add the module and the key

1. Add the **HTTP** app to your scenario and choose **Make a request**.
2. In **Authentication type**, select **API key**.
3. In **Credentials**, create a keychain and fill in:

| Field | Value |
|-------|-------|
| **Name** | `OmniSocials API` |
| **Key** | `Bearer omsk_live_<YOUR_KEY>` |
| **API key placement** | In the header |
| **API key parameter name** | `Authorization` |

4. Click **Create**.

The **Key** must include the `Bearer ` prefix, followed by a space. Make stores the keychain under **Keys** in the left sidebar. Change the key there later and every module that uses it picks up the change.

:::caution
Do not put the key in the **Headers** or **Query parameters** fields. Make's own docs say to keep credentials in the **Credentials** field, where they live in the keychain instead of the module settings.
:::

## 2. Configure the request

| Field | Value |
|-------|-------|
| **URL** | `https://api.omnisocials.com/v1/posts/create` |
| **Method** | `POST` |
| **Body content type** | **application/JSON** |
| **Body input method** | **JSON string** to start, **Data structure** once you map values (see below) |
| **Parse response** | **Yes** |

With **JSON string**, paste this into the body:

```json
{
  "content": { "default": "New on the blog: how we plan a month of posts in one hour." },
  "accounts": ["linkedin", "x"],
  "schedule_at": "2026-11-02T09:00:00Z",
  "media_urls": ["https://example.com/cover.jpg"],
  "source": "make"
}
```

Under **Advanced settings**, set **Return error if HTTP request fails** to **Yes**. A rejected post then stops the scenario instead of passing on an error response as if it worked.

Run the module once. A `201` response returns the new post under `data`, with its `id` and a `status` of `scheduled`. Because **Parse response** is on, later modules can map `data.id`.

## 3. Map values from earlier modules

**JSON string** sends your text as it is. A mapped caption with a double quote or a line break makes the JSON invalid, and the API answers `400`.

Switch **Body input method** to **Data structure** for mapped values. Make escapes the values for you. Create the data structure with Make's generator and give it the sample above, then map your fields into it:

- `content` → `default`: the caption from your trigger.
- `accounts`: one item per account, such as `linkedin` and `x`.
- `schedule_at`: a date in the future. Make turns a date into ISO 8601 text, so `{{addHours(now; 1)}}` works.
- `media_urls`: public image or video URLs.

## Body fields

The fields you will use most. The full list, including per-platform options, is in the [API reference](https://docs.omnisocials.com/api) and [Creating posts](https://docs.omnisocials.com/creating-posts.md).

| Field | Type | What it does |
|-------|------|--------------|
| `content` | object | Required. `default` is the text for every account. Add a platform key such as `instagram` or `linkedin` to give that platform its own text. |
| `accounts` | array of strings | Required. Platform names such as `"instagram"`, or account IDs from `GET /v1/accounts` such as `"844008_instagram"`. |
| `schedule_at` | string | ISO 8601 date and time, in the future. The post publishes then. |
| `publish_now` | boolean | `true` publishes right away. It wins over `schedule_at`. |
| `media_urls` | array of URLs | Public image or video URLs. OmniSocials downloads them. Instagram and TikTok posts need at least one. |
| `source` | string | Optional label for where the post came from. |

Leave out both `schedule_at` and `publish_now` to save the post as a draft. Send `publish_now` as a boolean, never as the text `"false"`.

:::tip
To see the account IDs in your workspace, add a second **Make a request** module with the same keychain, method `GET`, and URL `https://api.omnisocials.com/v1/accounts`.
:::

## Troubleshooting

| Response | Cause | Fix |
|----------|-------|-----|
| `401` | The key is wrong or revoked, or the `Bearer ` prefix is missing. | Edit the keychain under **Keys**. |
| `403` | The key misses a scope. | Create a new key with the scope. Scopes cannot be edited. |
| `400` with `validation_error` | A field is missing or invalid, for example an unknown account, a past `schedule_at`, or invalid JSON. | Read `error.message`, it names the problem. |
| `429` | Rate limit. | Wait for `Retry-After` seconds, then retry. |

See [Rate limits and errors](https://docs.omnisocials.com/rate-limits-and-errors.md) for every status code.

## Next steps

- [Creating posts](https://docs.omnisocials.com/creating-posts.md) covers per-platform text, post types, and updates.
- [Media](https://docs.omnisocials.com/media.md) covers uploads, formats, and size limits.
- [Webhooks](https://docs.omnisocials.com/webhooks.md) can start a scenario when a post publishes or fails.
