> ## Documentation Index
> Fetch the complete documentation index at: https://www.adspirer.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Analyze Meta Audiences

> 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



## OpenAPI

````yaml /api-reference/openapi.json post /api/v1/tools/analyze_meta_audiences/execute
openapi: 3.1.0
info:
  contact:
    email: support@adspirer.com
    name: Adspirer Support
  description: >-
    REST endpoints for every Adspirer 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://adspirer.ai/keys.


    ## 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` — Adspirer 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: Adspirer REST API
  version: 1.0.0
servers:
  - description: Production
    url: https://api.adspirer.ai
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 Adspirer account first
                  at https://adspirer.ai
                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://adspirer.ai to keep building.
                is_error: true
                quota:
                  limit: 150
                  period_end: '2026-05-01'
                  tier: plus
                  upgrade_url: https://adspirer.ai
                  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 Adspirer'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 support@adspirer.com 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://adspirer.ai/keys. Prefix `sk_live_`. Treat as a
        secret — never commit.
      scheme: bearer
      type: http

````