# Audiences

An **audience** is a saved list of recipients. Each member has an email address and an optional
`payload` of variables that fill `{{placeholders}}` when you send the audience a
[batch](https://docs.marleyfetch.com/guides/batches.md#to-an-audience-personalised).

Audiences are a **Pro** feature. Manage them on the
[Audiences](https://app.marleyfetch.com/audiences) page or through the API.

## Create an audience

```bash
curl https://api.marleyfetch.com/v1/audiences \
  -H "Authorization: Bearer $MARLEYFETCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Beta customers", "description": "Everyone on the beta programme"}'
```

```json
{
  "success": true,
  "audience": { "id": 12, "name": "Beta customers", "description": "Everyone on the beta programme", "...": "..." }
}
```

## Add members

Up to 10,000 members per request. Addresses already in the audience are skipped.

```bash
curl https://api.marleyfetch.com/v1/audiences/12/members \
  -H "Authorization: Bearer $MARLEYFETCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "members": [
      { "email": "alice@example.com", "payload": { "first_name": "Alice", "plan": "Pro" } },
      { "email": "bob@example.com",   "payload": { "first_name": "Bob",   "plan": "Free" } }
    ]
  }'
```

```json
{ "success": true, "inserted": 2, "duplicates": 0, "message": "Added 2 members (0 duplicates skipped)" }
```

In the dashboard, **Add Members** takes one member per line. Add variables after a comma as
`key=value`:

```text
alice@example.com, first_name=Alice, plan=Pro
bob@example.com, first_name=Bob
carol@example.com
```

Values without a key are stored as `attr_1`, `attr_2`, … in order, so prefer `key=value` for
anything you want to use in a template.

## List and remove members

```bash
# 100 per page by default, up to 1,000
curl "https://api.marleyfetch.com/v1/audiences/12/members?limit=100&offset=0" \
  -H "Authorization: Bearer $MARLEYFETCH_API_KEY"

# Remove one member
curl -X DELETE https://api.marleyfetch.com/v1/audiences/12/members/345 \
  -H "Authorization: Bearer $MARLEYFETCH_API_KEY"
```

The list response has a `pagination` object with `total`, `limit`, `offset` and `hasMore`. Keep
increasing `offset` by `limit` while `hasMore` is `true`.

## Other operations

| | |
| --- | --- |
| `GET /v1/audiences` | All your audiences with `member_count`, newest first. |
| `GET /v1/audiences/{id}` | One audience with `member_count`. |
| `PUT /v1/audiences/{id}` | Change `name` or `description`. |
| `DELETE /v1/audiences/{id}` | Delete the audience. |

## Sign-up pages

Each audience can have a hosted sign-up page where people add themselves. Set it up from the
audience's page in the dashboard: choose a URL slug, title, description, button label and
success message, then share the link. It is protected by a Cloudflare Turnstile challenge
against bots. Members who join this way get `{"source": "public_signup_page", "slug": "..."}`
as their payload.

## Send to an audience

```json
{
  "template_id": 3,
  "audience_id": 12
}
```

`POST` that to `/v1/send/batch` — see [Batch sending](https://docs.marleyfetch.com/guides/batches.md).
