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

# Get Template Metrics

> Returns Meta's template analytics for up to 10 templates of a single application: an overall `summary`, a per-template `summary`, and a daily `series`.

**Gap-filled buckets.** Days Meta returns no data for are emitted as zero points, so the series is always continuous across the requested range.

**Pending days.** Zero buckets that fall after Meta's `dataAvailableUntil` watermark are flagged `isPending: true`, telling you the day is not yet aggregated rather than genuinely empty.

**Derived rates.** `deliveredRate`, `readRate`, `clickRate`, and `costPerDelivered` are computed for you — rates to 4 decimals, `amountSpent` to 6. Rates are always recomputed from the totals, never averaged from the buckets.

**Invariants.** `Σ series[].sent == summary.sent` for each template, and the same holds for `delivered`, `read`, `clicked`, and `amountSpent`. The top-level `summary` is the sum of every template summary.

**Limits.** At most 10 `templateId` values and at most a 90-day range per request; split larger reports into several calls.

This endpoint is per-application and per-template. For organization-wide message volume, use Get Messages instead.

Note that this path is matched before `/wa/{app_id}/templates/{source_id}`, so `metrics` is never treated as a template ID.



## OpenAPI

````yaml /public-openapi.json get /wa/{app_id}/templates/metrics
openapi: 3.0.3
info:
  title: Connexease Public API
  version: 1.0.0
  description: >-
    Panel-independent API for managing WhatsApp Business operations from your
    own servers.


    Every endpoint is scoped to the organization resolved from your secret key.
    Read endpoints are uncached and proxy straight to the source.


    **On-premises installations** are served from your own domain with an extra
    `/public` segment: `https://{your_domain}/public/api/v1/...`.
    Authentication, bodies, responses, and error codes are identical.
servers:
  - url: https://public-api.gateway.connexease.com/api/v1
    description: Production
security:
  - secretKey: []
tags:
  - name: Analytics
    description: Organization-wide message volume.
  - name: Application
    description: The WhatsApp business profile linked to an application.
  - name: Template
    description: >-
      The full template lifecycle: create, list, inspect, update, delete, and
      measure.
  - name: Media
    description: >-
      Uploads that produce the single-use handle for template headers and the
      profile picture.
  - name: Developers
    description: Webhook configuration and API keys.
paths:
  /wa/{app_id}/templates/metrics:
    get:
      tags:
        - Template
      summary: Get Template Metrics
      description: >-
        Returns Meta's template analytics for up to 10 templates of a single
        application: an overall `summary`, a per-template `summary`, and a daily
        `series`.


        **Gap-filled buckets.** Days Meta returns no data for are emitted as
        zero points, so the series is always continuous across the requested
        range.


        **Pending days.** Zero buckets that fall after Meta's
        `dataAvailableUntil` watermark are flagged `isPending: true`, telling
        you the day is not yet aggregated rather than genuinely empty.


        **Derived rates.** `deliveredRate`, `readRate`, `clickRate`, and
        `costPerDelivered` are computed for you — rates to 4 decimals,
        `amountSpent` to 6. Rates are always recomputed from the totals, never
        averaged from the buckets.


        **Invariants.** `Σ series[].sent == summary.sent` for each template, and
        the same holds for `delivered`, `read`, `clicked`, and `amountSpent`.
        The top-level `summary` is the sum of every template summary.


        **Limits.** At most 10 `templateId` values and at most a 90-day range
        per request; split larger reports into several calls.


        This endpoint is per-application and per-template. For organization-wide
        message volume, use Get Messages instead.


        Note that this path is matched before
        `/wa/{app_id}/templates/{source_id}`, so `metrics` is never treated as a
        template ID.
      operationId: getTemplateMetrics
      parameters:
        - $ref: '#/components/parameters/AppId'
        - name: templateId
          in: query
          required: true
          description: >-
            Repeatable: `?templateId=a&templateId=b`. Between 1 and 10 IDs per
            request. Blank values are discarded and duplicates collapsed before
            the request reaches Meta; more than 10 distinct IDs returns `422`
            with `META_104`.
          schema:
            type: array
            minItems: 1
            maxItems: 10
            items:
              type: string
          style: form
          explode: true
        - name: startDate
          in: query
          required: false
          description: >-
            ISO-8601 datetime. Start of the range. Defaults to 30 days before
            today 00:00:00 UTC.
          schema:
            type: string
            format: date-time
        - name: endDate
          in: query
          required: false
          description: >-
            ISO-8601 datetime. End of the range; must be greater than
            `startDate`, and the total span cannot exceed 90 days. Defaults to
            today 23:59:59 UTC.
          schema:
            type: string
            format: date-time
        - name: granularity
          in: query
          required: false
          description: >-
            Bucket size of the series. `DAILY` is the only value Meta exposes
            for template analytics, so this is effectively fixed.
          schema:
            type: string
            enum:
              - DAILY
            default: DAILY
        - name: metricType
          in: query
          required: false
          description: >-
            Repeatable. Omit for the full core set (`SENT`, `DELIVERED`, `READ`,
            `CLICKED`, `COST`). Conversion metrics can be requested explicitly
            and are surfaced per bucket under `additionalMetrics`.
          schema:
            type: array
            items:
              type: string
              enum:
                - SENT
                - DELIVERED
                - READ
                - CLICKED
                - COST
                - APP_ACTIVATIONS
                - APP_ADD_TO_CART
                - APP_CHECKOUTS_INITIATED
                - APP_PURCHASES
                - APP_PURCHASES_CONVERSION_VALUE
                - WEBSITE_ADD_TO_CART
                - WEBSITE_CHECKOUTS_INITIATED
                - WEBSITE_PURCHASES
                - WEBSITE_PURCHASES_CONVERSION_VALUE
          style: form
          explode: true
        - name: productType
          in: query
          required: false
          description: >-
            Restricts the result to one messaging product. Omit for all
            products.
          schema:
            type: string
            enum:
              - CLOUD_API
              - MARKETING_MESSAGES_LITE_API
        - name: useWabaTimezone
          in: query
          required: false
          description: >-
            When `true`, Meta buckets the days in the WABA's own timezone
            instead of UTC. The applied choice is echoed back as
            `usesWabaTimezone`.
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: >-
            Range metadata, an overall summary, and one entry per requested
            template — in the order you sent them. A template with no data is
            still returned, with a zeroed summary and a fully gap-filled series.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      granularity:
                        type: string
                        description: >-
                          The granularity Meta applied, falling back to the
                          requested value.
                      productType:
                        type: string
                        description: Dropped when Meta does not report one.
                      periodStart:
                        type: string
                        format: date-time
                      periodEnd:
                        type: string
                        format: date-time
                      dataAvailableUntil:
                        type: string
                        format: date-time
                        description: >-
                          The latest moment Meta has aggregated data for.
                          Buckets after it come back with `isPending: true`.
                          Dropped when Meta returned no data at all.
                      usesWabaTimezone:
                        type: boolean
                      summary:
                        $ref: '#/components/schemas/TemplateMetricsSummary'
                      templates:
                        type: array
                        items:
                          type: object
                          properties:
                            templateId:
                              type: string
                            summary:
                              $ref: '#/components/schemas/TemplateMetricsSummary'
                            series:
                              type: array
                              items:
                                $ref: '#/components/schemas/TemplateMetricsBucket'
                  isSuccess:
                    type: boolean
                    enum:
                      - true
              example:
                data:
                  granularity: DAILY
                  productType: CLOUD_API
                  periodStart: '2026-07-14T00:00:00+00:00'
                  periodEnd: '2026-08-13T23:59:59+00:00'
                  dataAvailableUntil: '2026-08-13T00:00:00+00:00'
                  usesWabaTimezone: false
                  summary:
                    sent: 1200
                    delivered: 1140
                    read: 860
                    clicked: 210
                    deliveredRate: 0.95
                    readRate: 0.7544
                    clickRate: 0.1842
                    amountSpent: 18.42
                    costPerDelivered: 0.0162
                    clicksBreakdown:
                      - type: url_button
                        buttonContent: Track Order
                        count: 210
                    costBreakdown:
                      - type: amount_spent
                        value: 18.42
                      - type: cost_per_delivered
                        value: 0.0162
                  templates:
                    - templateId: '842802041844912'
                      summary:
                        sent: 1200
                        delivered: 1140
                        read: 860
                        clicked: 210
                        deliveredRate: 0.95
                        readRate: 0.7544
                        clickRate: 0.1842
                        amountSpent: 18.42
                        costPerDelivered: 0.0162
                        clicksBreakdown: []
                        costBreakdown: []
                      series:
                        - periodStart: '2026-08-12T00:00:00+00:00'
                          periodEnd: '2026-08-13T00:00:00+00:00'
                          sent: 400
                          delivered: 380
                          read: 290
                          clicked: 70
                          deliveredRate: 0.95
                          readRate: 0.7632
                          clickRate: 0.1842
                          amountSpent: 6.14
                          isPending: false
                          clicksBreakdown:
                            - type: url_button
                              buttonContent: Track Order
                              count: 70
                          costBreakdown:
                            - type: amount_spent
                              value: 6.14
                isSuccess: true
        '400':
          description: >-
            No usable `templateId` — every value was blank — or Meta rejected a
            parameter (`META_102`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: >-
            Secret key missing or invalid (`ORGANIZATION_SECRET_010` / `011`),
            or Meta token invalid or expired (`META_099`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: Meta permission denied (`META_100`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          $ref: '#/components/responses/AppNotFound'
        '409':
          description: >-
            Template analytics is not enabled for this WABA — enable insights
            and retry (`META_103`) — or not available for it yet (`META_106`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                errors:
                  code: META_103
                  group: CONFLICT
                  description: >-
                    Template analytics is not enabled for this WhatsApp Business
                    Account. Enable insights and try again.
                isSuccess: false
        '422':
          description: >-
            `endDate` not after `startDate` (`VAL_019`), more than 10 distinct
            `templateId` values (`META_104`), a range wider than 90 days
            (`META_105`), none of the given IDs valid for this WABA
            (`META_107`), or an invalid `granularity` / `metricType` /
            `productType` value.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              example:
                errors:
                  code: META_105
                  group: VALIDATION
                  description: >-
                    The requested date range is too large. The maximum allowed
                    range is 90 days.
                isSuccess: false
        '429':
          description: Meta rate limit (`META_101`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '502':
          description: General Meta-side analytics failure (`META_098`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
components:
  parameters:
    AppId:
      name: app_id
      in: path
      required: true
      description: >-
        Application ID. Must belong to the organization resolved from your
        secret key, otherwise the request returns `404` with `APPLICATION_004`.
      schema:
        type: string
        example: app_7poyXj8GXuv76e
  schemas:
    TemplateMetricsSummary:
      type: object
      properties:
        sent:
          type: integer
        delivered:
          type: integer
        read:
          type: integer
        clicked:
          type: integer
          description: Counts `url_button` and `quick_reply_button` only.
        deliveredRate:
          type: number
          description: '`delivered / sent`, 4 decimals. `0` when `sent` is `0`.'
        readRate:
          type: number
          description: '`read / delivered`, 4 decimals.'
        clickRate:
          type: number
          description: '`clicked / delivered`, 4 decimals.'
        amountSpent:
          type: number
          description: Total spend, 6 decimals.
        costPerDelivered:
          type: number
          description: '`amountSpent / delivered`, 4 decimals.'
        clicksBreakdown:
          type: array
          items:
            $ref: '#/components/schemas/ClicksBreakdownItem'
        costBreakdown:
          type: array
          items:
            $ref: '#/components/schemas/CostBreakdownItem'
          description: Empty when the range contains no cost data.
    TemplateMetricsBucket:
      type: object
      properties:
        periodStart:
          type: string
          format: date-time
        periodEnd:
          type: string
          format: date-time
        sent:
          type: integer
        delivered:
          type: integer
        read:
          type: integer
        clicked:
          type: integer
        deliveredRate:
          type: number
        readRate:
          type: number
        clickRate:
          type: number
        amountSpent:
          type: number
        isPending:
          type: boolean
          description: >-
            `true` for a zero-filled bucket Meta has not aggregated yet (it
            falls after `dataAvailableUntil`). `false` for a real data point or
            a genuinely empty day.
        additionalMetrics:
          type: object
          additionalProperties: true
          description: >-
            Extra metrics outside the core set, e.g. conversion metrics
            requested via `metricType`. Dropped when there are none.
        clicksBreakdown:
          type: array
          items:
            $ref: '#/components/schemas/ClicksBreakdownItem'
        costBreakdown:
          type: array
          items:
            $ref: '#/components/schemas/CostBreakdownItem'
    ErrorEnvelope:
      type: object
      description: >-
        Every failure shares this shape. `description` already has any `params`
        interpolated into it.
      properties:
        isSuccess:
          type: boolean
          enum:
            - false
        errors:
          type: object
          properties:
            code:
              type: string
              description: >-
                `VAL_*`, `WA_*`, `META_*`, `APPLICATION_*`,
                `ORGANIZATION_SECRET_*`, `REQ_001`, or `SYS_001`.
              example: META_075
            group:
              type: string
              enum:
                - VALIDATION
                - NOT_FOUND
                - CONFLICT
                - AUTHENTICATION
                - NOT_ALLOWED
                - LIMIT_EXCEEDED
                - SERVICE_UNAVAILABLE
                - SYSTEM
            description:
              type: string
              example: Template with 0000000000 not found in Meta.
            params:
              type: object
              additionalProperties: true
              description: >-
                Raw values interpolated into `description`. Present only on
                parametric messages.
            fields:
              type: object
              description: >-
                Field-level validation errors only. Field name (dot-joined for
                nested fields, list indices omitted) to its own `code` /
                `description` / `params`.
              additionalProperties:
                type: object
                properties:
                  code:
                    type: string
                  description:
                    type: string
                  params:
                    type: object
                    additionalProperties: true
          required:
            - code
            - group
            - description
      required:
        - isSuccess
        - errors
    ClicksBreakdownItem:
      type: object
      properties:
        type:
          type: string
          enum:
            - url_button
            - quick_reply_button
            - unique_url_button
          description: >-
            `url_button` and `quick_reply_button` are counted in `clicked`;
            `unique_url_button` is reported here but excluded from the total so
            clicks are not double-counted.
        buttonContent:
          type: string
          description: The button label or URL. Dropped when Meta does not report one.
        count:
          type: integer
    CostBreakdownItem:
      type: object
      properties:
        type:
          type: string
          enum:
            - amount_spent
            - cost_per_delivered
            - cost_per_url_button_click
        value:
          type: number
  responses:
    AppNotFound:
      description: '`app_id` does not belong to the organization (`APPLICATION_004`).'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      description: >-
        Secret key in `Bearer sk_...` format. Server-to-server only — never
        embed it in a browser or mobile client. The organization is resolved
        from the key, so `organization_id` is never passed explicitly.

````