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

# Broadcast Analytics

> Retrieve broadcast analytics for your organization. Supports two modes:

1. **Individual broadcast** — pass `broadcast_id` to get detailed analytics for a single broadcast, including per-button click tracking, opt-out detection, conversion funnel, and revenue attribution.
2. **Overall analytics** — pass `start_date` and `end_date` to get aggregated analytics across all broadcasts in a date range.

## Requirements
- Valid API key with `fiq_` prefix
- For individual mode: a valid broadcast UUID
- For overall mode: both `start_date` and `end_date` query parameters

<Note>
  Retrieve broadcast analytics for your organization. Supports individual broadcast deep-dives (with per-button tracking, opt-out detection, and revenue attribution) or overall date-range aggregations.
</Note>

## Two Modes

The endpoint supports two query modes based on which parameters you provide:

| Mode           | Parameters                | Description                                                |
| -------------- | ------------------------- | ---------------------------------------------------------- |
| **Individual** | `broadcast_id`            | Detailed analytics for a single broadcast                  |
| **Overall**    | `start_date` + `end_date` | Aggregated analytics across all broadcasts in a date range |

***

## Individual Broadcast Analytics

Pass a `broadcast_id` to get detailed metrics for a single broadcast, including delivery stats, per-button click tracking, opt-out detection, and Shopify revenue attribution.

```bash theme={null}
curl "https://api.flowiq.live/broadcast-analytics?broadcast_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "Authorization: Bearer fiq_YOUR_API_KEY"
```

### Response Fields

| Field               | Description                                                      |
| ------------------- | ---------------------------------------------------------------- |
| `broadcastInfo`     | Broadcast metadata (name, template, date, total recipients)      |
| `deliveryStats`     | Sent, delivered, read, failed counts with rates                  |
| `conversionFunnel`  | Funnel from sent → delivered → read → button clicked → opted out |
| `buttonAnalytics`   | First button stats (backward compatible)                         |
| `allButtons`        | Per-button breakdown with text, clicks, and conversion rate      |
| `totalButtonClicks` | Sum of clicks across all buttons                                 |
| `optOutAnalytics`   | Total opt-outs and opt-out rate                                  |
| `revenue`           | Shopify revenue attributed to this broadcast via UTM tracking    |

### Per-Button Tracking

All quick reply buttons on the template are tracked individually. The response includes an `allButtons` array with each button's text, click count, and conversion rate:

```json theme={null}
{
  "allButtons": [
    { "buttonText": "Shop Now", "clicks": 29, "conversionRate": 3.26 },
    { "buttonText": "View More", "clicks": 23, "conversionRate": 2.58 },
    { "buttonText": "Not Interested", "clicks": 11, "conversionRate": 1.24 }
  ],
  "totalButtonClicks": 63
}
```

### Opt-Out Detection

Opt-outs are detected from customer responses within 48 hours of the broadcast using multilingual keyword matching:

| Language   | Keywords                                       |
| ---------- | ---------------------------------------------- |
| English    | stop, unsubscribe, opt out, optout             |
| Portuguese | parar, pare, cancelar                          |
| Spanish    | detener, basta                                 |
| French     | arreter, desabonner                            |
| Italian    | fermare, ferma, annullare, annulla, cancellare |
| General    | quit, end, cancel                              |

### Revenue Attribution

Revenue is automatically attributed by tracing the broadcast's shortcode through to Shopify orders:

1. Broadcast button parameter contains a **shortcode**
2. Shortcode resolves to a **redirect URL** with a `utm_campaign` parameter
3. Shopify orders with `utm_source=whatsapp` and a matching `utm_campaign` are summed

```json theme={null}
{
  "revenue": {
    "totalRevenue": 19302.00,
    "currency": "ZAR",
    "orderCount": 11,
    "avgOrderValue": 1754.73,
    "utmCampaign": "31marstockup",
    "utmCampaigns": [
      { "campaign": "31marstockup", "orderCount": 6, "revenue": 10880.00, "avgOrderValue": 1813.33 },
      { "campaign": "31marstockup_vm", "orderCount": 5, "revenue": 8422.00, "avgOrderValue": 1684.40 }
    ],
    "orders": [
      { "orderName": "#28556", "totalPrice": 1650.00, "currency": "ZAR", "utmCampaign": "31marstockup_vm", ... }
    ]
  }
}
```

The `utmCampaigns` array breaks down revenue per UTM variant, so you can see exactly how much came from the main link vs the "View More" button (`_vm` suffix). Each order also includes its own `utmCampaign` field.

<Tip>
  Revenue attribution also matches UTM campaign suffix variants: `_viewmore`, `_view_more`, and `_vm` (case-insensitive). This captures orders from "View More" button clicks on the same campaign.
</Tip>

***

## Overall Broadcast Analytics

Pass `start_date` and `end_date` to get aggregated analytics across all broadcasts in the date range.

```bash theme={null}
curl "https://api.flowiq.live/broadcast-analytics?start_date=2026-03-01&end_date=2026-03-31" \
  -H "Authorization: Bearer fiq_YOUR_API_KEY"
```

### Response Fields

| Field                 | Description                                                             |
| --------------------- | ----------------------------------------------------------------------- |
| `overallStats`        | Aggregated totals: sent, delivered, read, failed, rates, campaign count |
| `campaignPerformance` | Per-campaign breakdown with delivery stats                              |
| `timeSeriesData`      | Daily breakdown of sent/delivered/read/failed                           |
| `templateAnalytics`   | Per-template aggregated stats and usage counts                          |
| `errorAnalysis`       | Ranked error codes with counts and percentages                          |

***

## POST Method

The same analytics are also available via POST, with parameters in the request body instead of query string:

```bash theme={null}
curl -X POST "https://api.flowiq.live/broadcast-analytics" \
  -H "Authorization: Bearer fiq_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "broadcast_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }'
```

```bash theme={null}
curl -X POST "https://api.flowiq.live/broadcast-analytics" \
  -H "Authorization: Bearer fiq_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "start_date": "2026-03-01", "end_date": "2026-03-31" }'
```

***

## Integration Example

```javascript theme={null}
async function getBroadcastAnalytics(apiKey, broadcastId) {
  const response = await fetch(
    `https://api.flowiq.live/broadcast-analytics?broadcast_id=${broadcastId}`,
    {
      headers: {
        Authorization: `Bearer ${apiKey}`,
      },
    }
  );
  const data = await response.json();
  if (!response.ok) throw new Error(data.message || data.error);
  return data;
}

const result = await getBroadcastAnalytics(
  "fiq_YOUR_API_KEY",
  "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
);

console.log(`Delivered: ${result.data.deliveryStats.delivered}`);
console.log(`Revenue: ${result.data.revenue.totalRevenue}`);
console.log(`Buttons: ${result.data.allButtons.length} tracked`);
```

***

<Card title="Revenue Attribution" icon="chart-line">
  Revenue attribution requires your broadcast template to use a FlowIQ shortcode link (via URL redirects) with a `utm_campaign` parameter, and your Shopify store to be connected. Orders are matched where `utm_source=whatsapp` in the landing site URL.
</Card>


## OpenAPI

````yaml flowiq-api-reference/openapi-broadcast-analytics.json GET /broadcast-analytics
openapi: 3.1.0
info:
  title: FlowIQ - Broadcast Analytics
  version: 1.0.0
servers:
  - url: https://api.flowiq.live
    description: FlowIQ Production API
security:
  - BearerAuth: []
paths:
  /broadcast-analytics:
    get:
      tags:
        - Endpoints
      summary: Broadcast Analytics
      description: >-
        Retrieve broadcast analytics for your organization. Supports two modes:


        1. **Individual broadcast** — pass `broadcast_id` to get detailed
        analytics for a single broadcast, including per-button click tracking,
        opt-out detection, conversion funnel, and revenue attribution.

        2. **Overall analytics** — pass `start_date` and `end_date` to get
        aggregated analytics across all broadcasts in a date range.


        ## Requirements

        - Valid API key with `fiq_` prefix

        - For individual mode: a valid broadcast UUID

        - For overall mode: both `start_date` and `end_date` query parameters
      operationId: getBroadcastAnalytics
      parameters:
        - name: broadcast_id
          in: query
          required: false
          description: >-
            UUID of a specific broadcast to get detailed analytics for. If
            provided, `start_date` and `end_date` are ignored.
          schema:
            type: string
            format: uuid
          example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
        - name: start_date
          in: query
          required: false
          description: >-
            Start date for overall analytics (inclusive). Required when
            `broadcast_id` is not provided.
          schema:
            type: string
            format: date
          example: '2026-03-01'
        - name: end_date
          in: query
          required: false
          description: >-
            End date for overall analytics (inclusive). Required when
            `broadcast_id` is not provided.
          schema:
            type: string
            format: date
          example: '2026-03-31'
      responses:
        '200':
          description: Analytics data returned successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    description: >-
                      Analytics data. Structure varies by mode (individual vs
                      overall).
              examples:
                individual:
                  summary: Individual Broadcast Analytics
                  value:
                    success: true
                    data:
                      broadcastInfo:
                        id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                        name: March Promo
                        templateName: march_promo_v2
                        createdAt: '2026-03-15T10:00:00Z'
                        totalRecipients: 1500
                      deliveryStats:
                        sent: 1500
                        delivered: 1420
                        read: 890
                        failed: 80
                        deliveryRate: 94.67
                        readRate: 62.68
                      conversionFunnel:
                        sent: 1500
                        delivered: 1420
                        read: 890
                        buttonClicked: 63
                        optedOut: 4
                      buttonAnalytics:
                        quickReplyButton: Shop Now
                        quickReplyClicks: 29
                        quickReplyConversionRate: 3.26
                      allButtons:
                        - buttonText: Shop Now
                          clicks: 29
                          conversionRate: 3.26
                        - buttonText: View More
                          clicks: 23
                          conversionRate: 2.58
                        - buttonText: Not Interested
                          clicks: 11
                          conversionRate: 1.24
                      totalButtonClicks: 63
                      optOutAnalytics:
                        totalOptOuts: 4
                        optOutRate: 0.45
                      revenue:
                        totalRevenue: 19302
                        currency: ZAR
                        orderCount: 11
                        avgOrderValue: 1754.73
                        utmCampaign: 31marstockup
                        utmCampaigns:
                          - campaign: 31marstockup
                            orderCount: 6
                            revenue: 10880
                            avgOrderValue: 1813.33
                          - campaign: 31marstockup_vm
                            orderCount: 5
                            revenue: 8422
                            avgOrderValue: 1684.4
                        orders:
                          - orderName: '#28556'
                            totalPrice: 1650
                            currency: ZAR
                            orderDate: '2026-04-03T07:35:39+02:00'
                            financialStatus: paid
                            utmCampaign: 31marstockup_vm
                overall:
                  summary: Overall Broadcast Analytics
                  value:
                    success: true
                    data:
                      overallStats:
                        totalSent: 12500
                        totalDelivered: 11800
                        totalRead: 7400
                        totalFailed: 700
                        deliveryRate: 94.4
                        readRate: 62.71
                        failureRate: 5.6
                        totalCampaigns: 8
                        totalRecipients: 12500
                      campaignPerformance:
                        - id: uuid-here
                          name: March Promo
                          templateName: march_promo_v2
                          sent: 1500
                          delivered: 1420
                          read: 890
                          failed: 80
                          deliveryRate: 94.67
                          readRate: 62.68
                          createdAt: '2026-03-15T10:00:00Z'
                      timeSeriesData:
                        - date: '2026-03-01'
                          sent: 500
                          delivered: 470
                          read: 310
                          failed: 30
                      templateAnalytics:
                        - templateName: march_promo_v2
                          totalUsage: 3
                          avgDeliveryRate: 94.5
                          avgReadRate: 61.2
                          totalSent: 4500
                          totalDelivered: 4252
                          totalRead: 2754
                          totalFailed: 248
                      errorAnalysis:
                        - errorCode: 131026
                          errorTitle: Message undeliverable
                          count: 45
                          percentage: 6.43
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                  usage:
                    type: object
              example:
                error: Missing required parameters
                message: >-
                  Either broadcast_id (for individual) or start_date and
                  end_date (for overall) are required
                usage:
                  individual: '?broadcast_id=<uuid>'
                  overall: '?start_date=2026-03-01&end_date=2026-03-31'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
              example:
                error: Invalid API key
                message: API key has been revoked
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
              example:
                error: No data
                message: No analytics data returned for this broadcast
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
              example:
                error: Analytics query failed
                message: Error details here
      security:
        - BearerAuth: []
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: 'Bearer token for authentication. Format: `Bearer fiq_YOUR_API_KEY`'
      bearerFormat: JWT

````