# Make

Create and schedule posts from a Make scenario with the HTTP module, and trigger scenarios from Pozy webhooks.

Make reaches Pozy with its built-in **HTTP** app for actions and **Webhooks** app for triggers. Everything below uses those two apps, so it works on every Make plan.

You need a Pozy API key (**Developers → API keys** in the dashboard) and at least one connected account.

## Make your first request

### Add an HTTP module

In the scenario editor, add **HTTP → Make a request**.

### Set it up

| Field | Value |
| --- | --- |
| URL | `https://api.pozy.ai/v1/accounts` |
| Method | GET |
| Headers | Name `Authorization`, value `Bearer pz_live_...` |
| Parse response | Yes |

### Run it

Click **Run once**. The output bundle lists your connected accounts. Note the `_id` of each account you will post to.

To avoid pasting the key into every module, store it once in a data store or a scenario variable and map it into the header.

## Create a post

Add another **HTTP → Make a request** module:

| Field | Value |
| --- | --- |
| URL | `https://api.pozy.ai/v1/posts` |
| Method | POST |
| Headers | `Authorization: Bearer pz_live_...`, and `Idempotency-Key` mapped to an id from the trigger, such as `{{1.id}}` |
| Body type | Raw |
| Content type | JSON (application/json) |
| Parse response | Yes |

Request content, with values mapped from earlier modules:

```json
{
  "content": "{{1.text}}",
  "platforms": [
    { "platform": "linkedin", "accountId": "6650f1c2a8b4e3d2c1b0a333" }
  ],
  "mediaItems": [
    { "type": "image", "url": "{{1.imageUrl}}" }
  ],
  "publishNow": true
}
```

Remove `mediaItems` for a text-only post.

> **Quotes in mapped text:**
> 
> A quote or a line break inside `{{1.text}}` breaks hand-written JSON. For anything longer than a short title, build the body with **JSON → Create JSON** and pass its output as the request content. It escapes every value for you.

## Schedule for later

Send a local time plus a timezone instead of `publishNow`:

```json
{
  "content": "{{1.text}}",
  "platforms": [{ "platform": "linkedin", "accountId": "6650f1c2a8b4e3d2c1b0a333" }],
  "scheduledFor": "{{formatDate(addDays(now; 1); "YYYY-MM-DD")}}T09:00:00",
  "timezone": "Europe/Madrid"
}
```

This posts at 9:00 in Madrid tomorrow. Other useful expressions:

| Expression | Gives |
| --- | --- |
| `{{formatDate(addHours(now; 3); "YYYY-MM-DDTHH:mm:ss")}}` | Three hours from now, in the scenario's timezone |
| `{{formatDate(1.publishDate; "YYYY-MM-DD")}}T12:00:00` | Noon on a date from an earlier module |

## Different text per platform

Use one request with `customContent` per platform rather than a Router with several modules. It keeps the post as one item in Pozy, with one status to watch:

```json
{
  "content": "{{1.title}}",
  "platforms": [
    { "platform": "linkedin", "accountId": "6650f1c2a8b4e3d2c1b0a333", "customContent": "{{1.longSummary}}" },
    { "platform": "twitter", "accountId": "6650f1c2a8b4e3d2c1b0a444", "customContent": "{{1.shortSummary}} {{1.url}}" }
  ],
  "publishNow": true
}
```

## Trigger a scenario from Pozy

### Add a custom webhook

Start a scenario with **Webhooks → Custom webhook**, click **Add**, name it and copy the URL Make shows.

### Point Pozy at it

Create the endpoint in the dashboard, or with an HTTP module:

```json
{
  "name": "Make: published posts",
  "url": "https://hook.eu1.make.com/abc123",
  "events": ["post.published"],
  "customHeaders": { "X-Hook-Token": "a-long-random-string" }
}
```

### Let Make learn the shape

Back in Make, click **Redetermine data structure**, then send a test event from Pozy with [`POST /v1/webhooks/test`](https://pozy.ai/docs/api/testWebhook) (or the dashboard's test button). Make now knows the fields, and you can map `event`, `post.content`, `post.platforms[].publishedUrl` and the rest.

### Make sure the call came from Pozy

In the webhook's advanced settings, turn on **Get request headers**. Add a filter right after the webhook that only lets bundles through when the `X-Hook-Token` header equals the value you set in `customHeaders`.

For full signature checks, turn on **JSON pass-through** too, so the webhook outputs the body exactly as sent, and compare `X-Pozy-Signature` with `sha256(<raw body>; "hex"; "<endpoint secret>")` in the filter. Make's `sha256` function returns an HMAC when you give it a key.

Respond within 5 seconds. A custom webhook answers immediately by default, which is what you want. Pozy retries a delivery that fails, so the same event can arrive twice; if that matters, keep processed `X-Pozy-Event-Id` values in a data store and skip repeats.

## Scenario ideas

- **Content calendar.** Google Sheets → Watch Rows, then HTTP creates the post from the row, with `Idempotency-Key` set to the row number.
- **Posting from your app.** Your app sends JSON to a Make custom webhook; an HTTP module turns it into a Pozy post.
- **Retry failed posts every hour.** Schedule every hour, `GET /v1/posts?status=failed`, an Iterator over `posts`, then `POST /v1/posts/{postId}/retry` for each.
- **Review alerts.** Custom webhook on `review.new`, a filter on low ratings, then Slack or email.

## When a module fails

| Status | What to do |
| --- | --- |
| `401` | The `Authorization` header is missing, mistyped or the key was revoked |
| `400` | Read `error` and `param` in the response; a field is missing or invalid |
| `429` | You hit the [rate limit](https://pozy.ai/docs/getting-started/rate-limits). Add an error handler with **Break** so Make retries later, and space requests with **Sleep** |
| `5xx` | Retry with the **Break** handler. The idempotency key stops duplicate posts |
