- Age group performance breakdown (18-24, 25-34, 35-44, 45-54, 55-64, 65+)
- Gender performance breakdown (male, female, unknown)
- Age + Gender combination analysis
- Segments categorized as SCALE/MAINTAIN/REDUCE/EXCLUDE based on ROAS
- Audience saturation score (0-100) with contributing factors
- Best performing segments to scale
- Underperforming segments to reduce/exclude
- Targeting optimization recommendations
- Quick actionable items
- “Which age groups perform best for my Meta ads?”
- “Should I target men or women on Facebook?”
- “Is my Meta audience saturated?”
- “Which demographics should I exclude?”
- “Analyze my Instagram audience performance”
- “Best demographic targeting for my Facebook campaigns”
- “Age and gender breakdown for my Meta ads”
- “Are my lookalike audiences exhausted?”
- “Which audience segments are wasting money?”
- lookback_days: 7, 14, 30 (default), 60, or 90 days
- start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date.
- end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user’s date request is vague or ambiguous (e.g., “March to June” without a year, “last quarter”, “recently”, “a few months ago”), ask the user to specify exact dates before calling this tool. Do not assume or guess dates.
- breakdown_type: ‘age’, ‘gender’, ‘age_gender’, or ‘all’ (default)
- include_saturation: Include saturation analysis (default: True)
- target_roas: Optional override (default: from account goals or 2.0x)
- ad_account_id: Required for multi-account users. Get from list_connected_accounts
- 🚀 SCALE (ROAS ≥ 1.5x target): Increase budget to this segment
- ➖ MAINTAIN (ROAS 0.75x-1.5x target): Keep current allocation
- ⚠️ REDUCE (ROAS 0.5x-0.75x target): Decrease budget
- 🔴 EXCLUDE (ROAS
<0.5x target): Remove from targeting
- Frequency Score (35%): How often users see ads (>3 indicates fatigue)
- CTR Decline Score (30%): Week-over-week CTR changes
- CPA Increase Score (25%): Rising cost per acquisition
- Reach Saturation Score (10%): Audience reach exhaustion
- ✅ HEALTHY (
<40): Audience is fresh, continue scaling - 🟡 AT_RISK (40-69): Monitor frequency, prepare new audiences
- 🔴 SATURATED (≥70): Expand targeting or refresh creatives
- Age 25-44 typically has highest ROAS for e-commerce
- Gender targeting varies significantly by product category
- High frequency (>4) combined with declining CTR indicates saturation
- Lookalike audiences can exhaust within 4-8 weeks at high spend
OpenAPI
/api-reference/openapi.json post /api/v1/tools/analyze_meta_audiences/execute
openapi: 3.1.0
info:
contact:
email: [email protected]
name: ADSMCP Support
description: >-
REST endpoints for every ADSMCP tool. Same surface as the MCP server, over
plain HTTP for consumers that can't speak SSE (n8n, Zapier, Make, curl, any
language's HTTP client).
## Envelope
Every request wraps tool-specific input in an `arguments` object:
```json
{ "arguments": { <tool-specific fields> } }
```
Every response wraps the result in either a success envelope (`success:
true`, `data: {...}`) or an error envelope (`success: false`, `error:
"..."`, `is_error: true`).
## Authentication
Pass your API key as `Authorization: Bearer sk_live_...` on every request.
Generate keys at https://adsmcp.si/dashboard/api-tokens.
## Quota & billing
Every successful billable call decrements your monthly tool-call allowance.
The current counter is attached to every 200 response under `data.quota`:
```json
"quota": { "used": 42, "limit": 150, "tier": "plus", "period_end":
"2026-05-01" }
```
When the limit is hit, the API returns HTTP 402 with a full `quota` block
including `upgrade_url`. Read-only diagnostic tools (`get_usage_status`,
`list_connected_accounts`, `get_connections_status`) are exempt and never
consume quota.
## Idempotency
Write operations accept an `Idempotency-Key: <uuid>` header. A repeated call
with the same key returns the cached result rather than executing twice.
**Strongly recommended for n8n, Zapier, and any retry-prone client** — it
prevents duplicate campaigns when networks misbehave. Generate a fresh UUID
per logical operation (not per retry).
## Multi-account users
Customers with multiple connected accounts on the same platform (e.g. an
agency with 10 Meta ad accounts) must specify which account to use via
`ad_account_id`, `customer_id`, `advertiser_id`, or `account_id` depending
on the platform. Omitting it returns HTTP 400 with a list of valid account
IDs. See `list_connected_accounts` to discover available IDs.
## HTTP status codes
- `200` — success (parse `data`)
- `400` — tool-level error (surface `error` to users)
- `401` — bad/missing API key
- `402` — ADSMCP quota exhausted
- `404` — unknown tool name
- `429` — upstream ad platform rate-limited us (Meta/Google/etc.) — retry
with backoff
- `500` — server error, report to support
## Streaming
This endpoint is plain request-response JSON. There is **no SSE, no chunked
streaming**. Safe to use from n8n Cloud's HTTP Request node, Zapier
Webhooks, Make HTTP module, curl, and every mainstream HTTP library.
title: ADSMCP REST API
version: 1.0.0
servers:
- description: Production
url: https://api.adsmcp.si
security: []
tags:
- description: Audit tools
name: audit
- description: General (Account Management) tools
name: general
- description: Google Ads tools
name: google-ads
- description: LinkedIn Ads tools
name: linkedin-ads
- description: Meta Ads tools
name: meta-ads
- description: Monitoring & Reporting tools
name: monitoring
- description: TikTok Ads tools
name: tiktok-ads
paths:
/api/v1/tools/analyze_meta_audiences/execute:
post:
tags:
- meta-ads
summary: Analyze Meta Audiences
description: >-
User asks about Meta/Facebook/Instagram audience performance by
demographics, age group or gender targeting optimization, audience
saturation, or which demographic segments to target or exclude.
This tool provides deep analysis of audience segment performance and
detects audience saturation to optimize demographic targeting for Meta
Ads.
Returns:
- Age group performance breakdown (18-24, 25-34, 35-44, 45-54, 55-64,
65+)
- Gender performance breakdown (male, female, unknown)
- Age + Gender combination analysis
- Segments categorized as SCALE/MAINTAIN/REDUCE/EXCLUDE based on ROAS
- Audience saturation score (0-100) with contributing factors
- Best performing segments to scale
- Underperforming segments to reduce/exclude
- Targeting optimization recommendations
- Quick actionable items
When to use this tool:
- "Which age groups perform best for my Meta ads?"
- "Should I target men or women on Facebook?"
- "Is my Meta audience saturated?"
- "Which demographics should I exclude?"
- "Analyze my Instagram audience performance"
- "Best demographic targeting for my Facebook campaigns"
- "Age and gender breakdown for my Meta ads"
- "Are my lookalike audiences exhausted?"
- "Which audience segments are wasting money?"
Parameters:
- lookback_days: 7, 14, 30 (default), 60, or 90 days
- start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days
when used with end_date.
- end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when
used with start_date.
⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous
(e.g., "March to June" without a year, "last quarter", "recently", "a
few months ago"), ask the user to specify exact dates before calling
this tool. Do not assume or guess dates.
- breakdown_type: 'age', 'gender', 'age_gender', or 'all' (default)
- include_saturation: Include saturation analysis (default: True)
- target_roas: Optional override (default: from account goals or 2.0x)
- ad_account_id: Required for multi-account users. Get from
list_connected_accounts
Execution time: 2-5 seconds (cached database query with analysis)
Data source: meta_audience_daily_metrics table (demographic-level daily
metrics)
ROAS Thresholds for Segment Recommendations:
- 🚀 SCALE (ROAS ≥ 1.5x target): Increase budget to this segment
- ➖ MAINTAIN (ROAS 0.75x-1.5x target): Keep current allocation
- ⚠️ REDUCE (ROAS 0.5x-0.75x target): Decrease budget
- 🔴 EXCLUDE (ROAS `<` 0.5x target): Remove from targeting
Saturation Score Factors (weighted):
- Frequency Score (35%): How often users see ads (>3 indicates fatigue)
- CTR Decline Score (30%): Week-over-week CTR changes
- CPA Increase Score (25%): Rising cost per acquisition
- Reach Saturation Score (10%): Audience reach exhaustion
Saturation Levels:
- ✅ HEALTHY (`<`40): Audience is fresh, continue scaling
- 🟡 AT_RISK (40-69): Monitor frequency, prepare new audiences
- 🔴 SATURATED (≥70): Expand targeting or refresh creatives
Common Insights:
- Age 25-44 typically has highest ROAS for e-commerce
- Gender targeting varies significantly by product category
- High frequency (>4) combined with declining CTR indicates saturation
- Lookalike audiences can exhaust within 4-8 weeks at high spend
operationId: execute_analyze_meta_audiences
parameters:
- description: >-
Client-generated UUID to make writes idempotent. Strongly
recommended for write tools. A repeat call with the same key returns
the cached result instead of re-executing. Example:
550e8400-e29b-41d4-a716-446655440000
example: 550e8400-e29b-41d4-a716-446655440000
in: header
name: Idempotency-Key
required: false
schema:
format: uuid
type: string
requestBody:
content:
application/json:
example:
arguments:
breakdown_type: all
date_range: string
end_date: string
lookback_days: 30
raw_data: false
start_date: string
schema:
properties:
arguments:
description: Input schema for Meta audience performance analysis
properties:
ad_account_id:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
Meta Ad Account ID. Required for multi-account users.
Get from list_connected_accounts.
title: Ad Account Id
breakdown_type:
default: all
description: >-
Type of audience breakdown: 'age' (age groups),
'gender', 'age_gender' (combined), or 'all' (default).
title: Breakdown Type
type: string
date_range:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
Date range preset: 'last_7_days', 'last_14_days',
'last_30_days', 'last_60_days', 'last_90_days'.
Overrides lookback_days. Ignored if start_date/end_date
are provided.
title: Date Range
end_date:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
End date (YYYY-MM-DD). If provided with start_date,
overrides lookback_days for custom date range queries.
title: End Date
include_saturation:
default: true
description: >-
Include audience saturation analysis for lookalike and
custom audiences (default: True).
title: Include Saturation
type: boolean
lookback_days:
default: 30
description: >-
Number of days to analyze (7, 14, 30, 60, or 90 days).
Default is 30 days.
title: Lookback Days
type: integer
raw_data:
default: false
description: >-
If true, return ONLY raw metrics as a JSON code block
(spend, clicks, impressions, conversions, CPA, CPC, CTR,
CVR, ROAS by campaign/ad/date). Strips severity labels,
suggested bids/budgets, industry benchmarks, and
optimization recommendations. Use when you run your own
attribution model or want to minimize token usage.
title: Raw Data
type: boolean
start_date:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
Start date (YYYY-MM-DD). If provided with end_date,
overrides lookback_days for custom date range queries.
title: Start Date
target_roas:
anyOf:
- type: number
- type: 'null'
default: null
description: >-
Optional target ROAS override (e.g., 3.0 for 3.0x ROAS).
If not provided, will use account goals or historical
average.
title: Target Roas
type: object
required:
- arguments
type: object
description: >-
All tool arguments are wrapped in an `arguments` object. The fields
accepted inside `arguments` are listed below — required fields are
marked with a red asterisk.
required: true
responses:
'200':
content:
application/json:
example:
data:
quota:
limit: 150
period_end: '2026-05-01'
tier: plus
used: 42
text: (tool-specific textual output for analyze_meta_audiences)
success: true
tool: analyze_meta_audiences
schema:
$ref: '#/components/schemas/SuccessResponse'
description: >-
Tool executed successfully. `data.text` carries the human-readable
result (markdown-friendly). `data.quota` shows your current usage
against the plan limit. `data.structured` appears when the tool
emits machine-parseable structured content. `data.content` appears
for tools that return non-text blocks (images, resources).
'400':
content:
application/json:
example:
error: >-
You have 25 meta_ads accounts connected. Please specify which
account to use by passing the ad_account_id parameter:
- Acme Holdings (ad_account_id="act_123456789")
- Acme EU (ad_account_id="act_987654321")
is_error: true
success: false
tool: analyze_meta_audiences
schema:
$ref: '#/components/schemas/ErrorResponse'
description: >-
Tool-level error. The `error` string is safe to surface to end
users. Common causes: missing required argument, multi-account user
didn't specify which account, upstream platform validation failure.
'401':
content:
application/json:
example:
error: >-
Not authenticated. Please connect your ADSMCP account first
at https://adsmcp.si
is_error: true
success: false
tool: analyze_meta_audiences
schema:
$ref: '#/components/schemas/ErrorResponse'
description: Invalid, expired, or revoked API key.
'402':
content:
application/json:
example:
error: |-
🚨 Monthly limit reached (150/150 tool calls on Plus tier).
Upgrade to Pro at https://adsmcp.si to keep building.
is_error: true
quota:
limit: 150
period_end: '2026-05-01'
tier: plus
upgrade_url: https://adsmcp.si
used: 150
success: false
tool: analyze_meta_audiences
schema:
$ref: '#/components/schemas/QuotaErrorResponse'
description: >-
Quota exhausted for the current billing period. The response
includes a `quota` block with the current used/limit/tier values and
an `upgrade_url` to move up a tier.
'404':
content:
application/json:
example:
error: 'Tool not found: analyze_meta_audiences'
is_error: true
success: false
tool: analyze_meta_audiences
schema:
$ref: '#/components/schemas/ErrorResponse'
description: Unknown tool_name. Check /openapi.json for the full catalog.
'429':
content:
application/json:
example:
error: >-
Upstream platform rate limit hit (Meta Business Use Case
throttle at 95%). Retry after 60 seconds.
is_error: true
success: false
tool: analyze_meta_audiences
schema:
$ref: '#/components/schemas/ErrorResponse'
description: >-
Rate-limited by the upstream ad platform (Meta, Google, LinkedIn,
TikTok). Retry with exponential backoff. Not the same as ADSMCP's
own quota — that returns 402.
'500':
content:
application/json:
example:
error: 'Internal error: RuntimeError'
is_error: true
success: false
tool: analyze_meta_audiences
schema:
$ref: '#/components/schemas/ErrorResponse'
description: >-
Unexpected server error. Report to [email protected] with
request_id.
security:
- ApiKeyAuth: []
components:
schemas:
SuccessResponse:
description: >-
Returned on HTTP 200. `data.text` is the primary human-readable output.
`data.quota` is always present for billable calls. `data.structured` is
set only when the tool emits machine-parseable structured content.
`data.content` is set only when the tool emits non-text content blocks.
properties:
data:
properties:
content:
description: Non-text content blocks (images, resources).
items:
$ref: '#/components/schemas/ContentBlock'
type: array
quota:
$ref: '#/components/schemas/QuotaBlock'
structured:
additionalProperties: true
description: >-
Machine-parseable structured content when the tool provides it
(e.g. account selection prompts, widget payloads).
type: object
text:
description: >-
Human-readable output. Markdown-friendly for tools that emit
formatted lists, tables, or recommendations.
type: string
required:
- text
type: object
success:
const: true
type: boolean
tool:
description: Echoed tool_name from the request URL.
type: string
required:
- success
- data
- tool
type: object
ErrorResponse:
description: >-
Returned on HTTP 4xx / 5xx (except 402 which uses `QuotaErrorResponse`).
`error` is always a human-readable string safe to surface to end users.
properties:
error:
description: Human-readable error message.
type: string
is_error:
const: true
type: boolean
structured_content:
additionalProperties: true
description: >-
Present when the underlying tool attached structured metadata to the
error (e.g. account-selection lists).
type: object
success:
const: false
type: boolean
tool:
type: string
required:
- success
- error
- tool
type: object
QuotaErrorResponse:
description: >-
Returned on HTTP 402 when the monthly quota is exhausted. Identical to
`ErrorResponse` but with an additional `quota` block.
properties:
error:
type: string
is_error:
const: true
type: boolean
quota:
$ref: '#/components/schemas/QuotaBlock'
success:
const: false
type: boolean
tool:
type: string
required:
- success
- error
- tool
- quota
type: object
ContentBlock:
additionalProperties: true
description: >-
A non-text content block. Rare today; tools that attach images,
resources, or widget payloads populate `data.content` with blocks of
this shape.
properties:
type:
example: image
type: string
required:
- type
type: object
QuotaBlock:
description: >-
Current quota state for the API key owner. Attached to every successful
billable response under `data.quota`, and to 402 errors under `quota`
(plus `upgrade_url`).
properties:
limit:
description: Tool call allowance for the current tier.
example: 150
type: integer
period_end:
description: When the monthly counter resets (ISO date).
example: '2026-05-01'
format: date
type: string
tier:
description: Subscription tier of the account that owns the API key.
enum:
- free
- plus
- pro
- max
example: plus
type: string
upgrade_url:
description: Upgrade link (present only on 402 quota errors).
format: uri
type: string
used:
description: Tool calls consumed this billing period.
example: 42
type: integer
required:
- used
- limit
- tier
- period_end
type: object
securitySchemes:
ApiKeyAuth:
bearerFormat: API Key (sk_live_...)
description: >-
API key from https://adsmcp.si/dashboard/api-tokens. Prefix `sk_live_`. Treat as a
secret — never commit.
scheme: bearer
type: http