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

# Make

> Build PostQueen scenarios in Make with the HTTP module, plus webhooks in the other direction

A Make scenario can put posts on your PostQueen calendar today. It calls the same public API as the [CLI](/cli/introduction), [MCP](/mcp/introduction) and the [n8n node](/automation/n8n), so anything a scenario creates lands on the same calendar where you review everything else. She publishes it on time from there.

<Note>
  A native PostQueen app for Make is coming soon. Until it lands, the HTTP module covers the same ground: scheduling, drafts and publishing right away. Scenarios you build now stay valid, because they talk to the public API directly.
</Note>

<Frame>
  <img src="https://mintcdn.com/forceplay/3MbWAJB4xKJ_Rxe0/images/brand/auto-make.svg?fit=max&auto=format&n=3MbWAJB4xKJ_Rxe0&q=85&s=0b55570ae3c11b09611f4106588a250e" alt="A Make scenario whose HTTP module sends a post to PostQueen and schedules it on the calendar" width="410" height="124" data-path="images/brand/auto-make.svg" />
</Frame>

## Before you start

Your Public API key. In [app.postqueen.ai](https://app.postqueen.ai), open **Settings > Developers > Public API** and click **Reveal**.

<Warning>
  The API expects the key raw. The header is `Authorization: YOUR_API_KEY` with no `Bearer` prefix, which trips up people who have wired other APIs into Make before.
</Warning>

## Schedule a post

This all happens in Make's **HTTP** app, and the module you want is **Make a request**.

<Steps>
  <Step title="Add the module">
    In your scenario, add the **HTTP** app and choose the **Make a request** module.
  </Step>

  <Step title="Set the method and URL">
    Method: **POST**. URL: `https://api.postqueen.ai/public/v1/posts`
  </Step>

  <Step title="Add the Authorization header">
    Under **Headers**, click **Add item**. Name: `Authorization`. Value: your API key exactly as the app showed it.
  </Step>

  <Step title="Send the body as JSON">
    Set **Body type** to **Raw**, set **Content type** to **JSON (application/json)**, then paste the payload into **Request content**.
  </Step>

  <Step title="Parse the response">
    Turn on **Parse response** so the created post IDs come back as mappable fields instead of one long string. Run the module once by hand so Make learns the response shape.
  </Step>
</Steps>

The body is the same one the [Create Post](/public-api/posts/create) reference documents:

```json theme={"system"}
{
  "type": "schedule",
  "date": "2026-08-01T10:00:00.000Z",
  "shortLink": false,
  "tags": [],
  "posts": [
    {
      "integration": { "id": "your-integration-id" },
      "value": [
        {
          "content": "Hello world!",
          "image": []
        }
      ],
      "settings": {
        "__type": "bluesky"
      }
    }
  ]
}
```

| Field                     | What it controls                                                                                                                                                          |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`                    | `schedule` for a timed post, `now` to publish immediately, `draft` to park it on the calendar for review.                                                                 |
| `date`                    | ISO 8601 publish time in UTC. Read when `type` is `schedule`. Nothing checks that it is in the future, so a past date is accepted and the post goes out on the next pass. |
| `posts[].integration.id`  | The channel that receives the post. [Find your integration IDs](#find-your-integration-ids).                                                                              |
| `posts[].value[]`         | One entry per post. Adding entries builds a thread on platforms that support threading.                                                                                   |
| `posts[].settings.__type` | The provider key, such as `x`, `linkedin` or `bluesky`. Required fields per provider are listed in [Create Post](/public-api/posts/create).                               |
| `shortLink`               | Shortens links found in the content when set to `true`.                                                                                                                   |

<Tip>
  Mixing mapped values straight into raw JSON is the usual way a scenario breaks: one unescaped quote or line break from an upstream module and the whole body stops being valid JSON. If your content comes from another module, build the payload with the JSON app's **Create JSON** module and map its output into **Request content**.
</Tip>

Media works the same way it does everywhere else. Upload the file first with `POST /public/v1/upload`, then pass the returned `id` and `path` into `value[].image[]`. TikTok, Instagram and YouTube accept media only from trusted domains, so a raw external URL will be rejected.

## Find your integration IDs

Every post needs to name the channel it goes to, and she answers with the whole list. Add a second **Make a request** module, set the method to **GET** and the URL to `https://api.postqueen.ai/public/v1/integrations`, with the same `Authorization` header. Turn on **Parse response** and run it once.

```json theme={"system"}
[
  {
    "id": "cm4ean69r0003w8w1cdomox9n",
    "name": "Jane Doe",
    "identifier": "x",
    "picture": "https://uploads.postqueen.ai/avatar.jpg",
    "disabled": false,
    "profile": "janedoe"
  }
]
```

Map `id` into `posts[].integration.id`. The `identifier` field is the same string you put in `settings.__type`, so `x` maps to `__type: "x"`. Check [Create Post](/public-api/posts/create) for the extra settings each provider needs alongside it.

Two ways to use this in practice: run the module once, copy the IDs you need and paste them into your payload, or keep the GET module in front of the POST and filter for the channel you want by name. The first is simpler, the second survives you reconnecting a channel later.

## Trigger a scenario from PostQueen

The HTTP module drives her. For the other direction, she calls your scenario the moment a post goes out.

<Steps>
  <Step title="Create the webhook in Make">
    Add the **Webhooks** app with the **Custom webhook** module as the first module in your scenario. Click **Add**, name it, save, then **Copy address to clipboard**.
  </Step>

  <Step title="Register it in PostQueen">
    In the app open **Settings**, then the **Webhooks** tab, and click **Add a webhook**. Paste the Make URL, give it a name, and choose whether it fires for all channels or only the ones you pick.
  </Step>

  <Step title="Teach Make the payload">
    With the Make scenario listening, click **Send Test** on the webhook form. Make receives a sample delivery and builds the data structure from it, then click **Save**. To send another sample later, reopen the webhook with **Edit** and press **Send Test** again; in the Make module, click **Re-determine data structure** first.
  </Step>
</Steps>

The delivery is a `POST` with a JSON array of published posts. Each entry carries the post content and its publish time, plus a `releaseURL` pointing at the live post and an `integration` object that names the channel. The moment she publishes, that `releaseURL` is what makes the trigger worth wiring up: log a row in Airtable or drop a Slack message while the post is still warm.

Full payload details and delivery behavior live on the [Webhooks](/automation/webhooks) page.

## Self-hosting

Running her yourself? Everything above still works. Swap the base URL for `https://postqueen.example.com/api/public/v1` and keep the header, the body and the modules as they are.

One thing to watch: the create-post endpoint is rate limited to 30 requests per hour, and you raise that with the `API_LIMIT` env var. A scenario that loops over many rows can hit the ceiling, so batch several posts into one request where you can, or add a **Sleep** module between iterations.

## Next steps

<CardGroup cols={3}>
  <Card title="Public API" icon="code" href="/public-api/introduction">
    Every endpoint the HTTP module can call, with request and response shapes.
  </Card>

  <Card title="Create Post" icon="calendar" href="/public-api/posts/create">
    Provider settings, thread structure and the `__type` table.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/automation/webhooks">
    What she sends the moment a post goes out, field by field.
  </Card>

  <Card title="n8n" icon="https://mintcdn.com/forceplay/3MbWAJB4xKJ_Rxe0/images/brand/icon-n8n.svg?fit=max&auto=format&n=3MbWAJB4xKJ_Rxe0&q=85&s=25d4f09b68dcfa3384c00cdc67569bd5" href="/automation/n8n" width="30" height="30" data-path="images/brand/icon-n8n.svg">
    Ready-made operations instead of hand-built HTTP requests.
  </Card>

  <Card title="Zapier" icon="https://mintcdn.com/forceplay/3MbWAJB4xKJ_Rxe0/images/brand/icon-zapier.svg?fit=max&auto=format&n=3MbWAJB4xKJ_Rxe0&q=85&s=9b00a49e4b41097e9b0c1462c85f0605" href="/automation/zapier" width="30" height="30" data-path="images/brand/icon-zapier.svg">
    The same requests, built with Webhooks by Zapier instead.
  </Card>

  <Card title="CLI" icon="terminal" href="/cli/introduction">
    Test a payload in your terminal before you paste it into Make.
  </Card>
</CardGroup>
