# Compile a brief

> POST /v1/audiences/compile. Turn a plain English brief into an audience definition with a one-sentence readback, the chips it made and any questions to answer first.

Source: https://emailmovers.com/mydatahub/docs/reference/rest/compile-audience

`POST /v1/audiences/compile`

Turn a plain English brief into an audience definition with a one-sentence readback, the chips it made and any questions to answer first. Words that match no filter are returned, not guessed.

| Property | Value |
| --- | --- |
| Endpoint | `POST https://mydatahub.emailmovers.com/v1/audiences/compile` |
| Operation id | `compileAudience` |
| Cost | Free (0 credits) |
| Access | No account, key or token needed. |
| MCP tool | [`compile_audience`](https://emailmovers.com/mydatahub/docs/reference/mcp/compile_audience.md) |
| Tag | Catalogue |

> **Not yet live.** MyDataHub v2 is built and tested locally and is not yet live. The v2 hosts open at launch, date to confirm. This page describes the contract the API is tested against.

## Request

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `MyDataHub-Version` | header | string | no | The dated API version, pinned per key when left out. Non-breaking changes ship as new dates; the path major changes only for breaking changes, with a 12 month deprecation window. |

### Body

| Member | Type | Required | Description |
| --- | --- | --- | --- |
| `brief` | string | yes | A plain English brief, such as "300 finance directors at law firms in Manchester". |
| `dataset` | enum: `uk_contacts`, `ie_contacts`, `global_contacts` | no | The dataset an audience draws from. uk_contacts is live; ie_contacts and global_contacts are listed but not yet served. |

## Example request

```bash
curl -X POST "https://mydatahub.emailmovers.com/v1/audiences/compile" \
  -H "Content-Type: application/json" \
  --data '{
  "brief": "300 finance directors at law firms in Manchester"
}'
```

## Responses

### 200: The compiled audience.

Headers: `RateLimit`, `RateLimit-Policy`.

| Member | Type | Always present | Description |
| --- | --- | --- | --- |
| `audience` | `Audience` | yes | Who you want, as filters grouped by entity (company., site., contact., email., phone., signal.). The server fills its defaults (active companies, named emails, corporate subscribers, the current dataset_version) and returns the effective definition with every count. See [Audience](https://emailmovers.com/mydatahub/docs/audience.md). |
| `readback` | string | yes | The audience in one sentence, to confirm with the person. |
| `chips` | array of `Chip` | yes |  |
| `chips[].label` | string | yes | What the chip reads, such as Within 20 miles of Leeds. |
| `chips[].pointer` | string | yes | JSON pointer to the filter inside audience. |
| `chips[].from_brief` | string | yes | The words of the brief it came from. |
| `questions` | array of `BriefQuestion` | yes |  |
| `questions[].id` | string | yes |  |
| `questions[].text` | string | yes |  |
| `questions[].options` | array of object | yes |  |
| `unrecognised` | array of string | yes | Words of the brief that matched no filter, shown rather than guessed. |
| `quantity` | integer (0 or more) or null | yes | A quantity named in the brief, such as 300, for quote_order limit. |

#### Example response

```json
{
  "audience": {
    "schema": "mydatahub.audience/1",
    "dataset": "uk_contacts",
    "where": {
      "all": [
        {
          "field": "contact.title",
          "op": "matches",
          "terms": ["finance director"]
        },
        {
          "field": "company.sic_2007",
          "op": "in",
          "values": ["69102"]
        },
        {
          "field": "site.town",
          "op": "in",
          "values": ["manchester"]
        }
      ]
    }
  },
  "readback": "Finance directors at solicitors (SIC 69102) in Manchester.",
  "chips": [
    {
      "label": "Job title: finance director plus expansions",
      "pointer": "/where/all/0",
      "from_brief": "finance directors"
    },
    {
      "label": "Industry: solicitors (SIC 69102)",
      "pointer": "/where/all/1",
      "from_brief": "law firms"
    },
    {
      "label": "Town: Manchester",
      "pointer": "/where/all/2",
      "from_brief": "in Manchester"
    }
  ],
  "questions": [],
  "unrecognised": [],
  "quantity": 300
}
```

## Errors

Every error is a problem object with a `code` and a `next_step`. Every response carries the `RateLimit` and `RateLimit-Policy` headers; see [Rate limits](https://emailmovers.com/mydatahub/docs/rate-limits.md).

| Status | Problem codes | When |
| --- | --- | --- |
| 400 | [`invalid-request`](https://emailmovers.com/mydatahub/docs/errors/invalid-request.md), [`idempotency-key-required`](https://emailmovers.com/mydatahub/docs/errors/idempotency-key-required.md), [`unsupported-version`](https://emailmovers.com/mydatahub/docs/errors/unsupported-version.md) | The request could not be read, or an Idempotency-Key is missing. |
| 422 | [`validation-failed`](https://emailmovers.com/mydatahub/docs/errors/validation-failed.md), [`quote-required`](https://emailmovers.com/mydatahub/docs/errors/quote-required.md), [`dataset-unavailable`](https://emailmovers.com/mydatahub/docs/errors/dataset-unavailable.md) | The request is not valid. errors lists every problem with a JSON pointer and did_you_mean. |
| 429 | [`rate-limited`](https://emailmovers.com/mydatahub/docs/errors/rate-limited.md) | Too many requests. Wait for Retry-After. |
| Any other failure | [`internal-error`](https://emailmovers.com/mydatahub/docs/errors/internal-error.md), [`service-unavailable`](https://emailmovers.com/mydatahub/docs/errors/service-unavailable.md), [`tps-screen-expired`](https://emailmovers.com/mydatahub/docs/errors/tps-screen-expired.md) | Something failed on our side (500 internal-error) or the service is briefly unavailable (503 service-unavailable, with Retry-After). Nothing was charged; retry with the same Idempotency-Key. A count, sample, quote or order with telephone in play is also refused with 503 tps-screen-expired, with no Retry-After, while the dataset version's TPS and CTPS screen is more than 28 days old. |
