Reference / MCP tool reference
Reference
Save an audience
save_audience: Saves an audience definition under a name, shared across the organisation, or updates a saved one when audience_id is given.
Saves an audience definition under a name, shared across the organisation, or updates a saved one when audience_id is given. Use it when the user wants to keep, share or recount a list later; saving is free and needs audiences:write. Repeating the same call returns the same saved audience. Call list_audiences to find it again, or count_audience with its aud_ id. Lawful basis is UK GDPR Article 6(1)(f) legitimate interests; email audiences include corporate subscribers only by default (PECR), so sole traders and ordinary partnerships are left out unless the toggle is changed.
| Property | Value |
|---|---|
| Tool name | save_audience |
| Position in tools/list | 10 of 22 |
| Cost | Free |
| Scope | audiences:write |
| Annotations | readOnlyHint false, destructiveHint false, idempotentHint true, openWorldHint false |
| Kind | Write; idempotent, not destructive, closed world |
| REST equivalent | POST /v1/audiences; PATCH /v1/audiences/{id} |
Input
The schema sets additionalProperties to false, so a member that is not listed is refused.
| Member | Type | Required | Description |
|---|---|---|---|
audience_id | string | no | A saved audience to update. Leave it out to save a new one. |
name | string | no | |
audience | Audience | no | 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. |
brief | string or null | no |
Example call
The params of a tools/call request:
{
"name": "save_audience",
"arguments": {
"name": "Marketing directors, Leeds",
"audience": {
"schema": "mydatahub.audience/1",
"dataset": "uk_contacts",
"dataset_version": "2026-W39",
"where": {
"all": [
{
"field": "contact.title",
"op": "matches",
"terms": ["marketing manager"],
"mode": "contains",
"expand": ["plural_singular", "department_synonyms", "ampersand_and", "abbreviations"]
},
{
"field": "contact.job_level_rank",
"op": "in",
"values": [1, 2, 3, 4, 5, 6, 8, 9]
},
{
"field": "company.sic_2007",
"op": "in",
"values": ["C"]
},
{
"field": "company.employee_band",
"op": "gte",
"value": "50-99"
},
{
"field": "site.location",
"op": "within_radius",
"centre": {
"place": "Leeds"
},
"radius_miles": 20
},
{
"not": {
"field": "email.address_sha256",
"op": "in_list",
"list_id": "sup_01JB4H7Q2V7XN3M9R6T1Y5W8ZA"
}
}
]
},
"email_policy": {
"min_deliverability_score": 70,
"allow_catch_all": false
},
"dedupe": "none"
}
}
}Output
The result carries structuredContent that matches this schema, and one line of text that leads with the number.
| Member | Type | Always present | Description |
|---|---|---|---|
id | string | yes | Format: an audience id: aud_ followed by a 26 character ULID in upper case Crockford base32, such as aud_01JB4H2K9V6XN3M9R6T1Y5W8ZA. |
name | string | yes | |
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. |
brief | string or null | yes | The brief it was compiled from, if any. |
current_count | AudienceCountSummary or null | yes | |
current_count.count_id | string | yes | Format: a count id: cnt_ followed by 20 base32 characters (A to Z and 2 to 7), such as cnt_7K2PQ4MAXN3R6TBY5WDZ. |
current_count.dataset_version | string | yes | The immutable weekly build a count is bound to, such as 2026-W39. The last 52 stay queryable. |
current_count.contacts | integer (0 or more) | yes | |
current_count.companies | integer (0 or more) | yes | |
current_count.emailable | integer (0 or more) | yes | |
current_count.counted_at | string (date-time) | yes | |
last_refreshed_at | string (date-time) or null | yes | |
created_at | string (date-time) | yes | |
updated_at | string (date-time) | yes | |
created_by | string | yes | Format: a user id: usr_ followed by a 26 character ULID in upper case Crockford base32, such as usr_01JA0Q3V7XN3M9R6T1Y5W8ZAK8. |
url | string (uri) | yes | The audience in the app, mydatahub.emailmovers.com/audiences/{id}. |
Errors
A failed call returns isError true. The text content leads with the sentence a person acts on, then the whole problem as JSON, with code, detail, next_step and did_you_mean. A 401 and a step-up 403 are answered at HTTP level so the client can start authorisation. See Errors.