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

# MessageAnalytics

> Counts and rates for a marketing send over a period. Rates are fractions rather than percentages, and are null when the denominator is zero. Counts cover events that happened inside the range, which for an automation may include engagement with messages sent before it — so a rate can exceed 1.

**Implemented by:** [`MessageAnalyticsPoint`](/docs/api-reference/v3/reference/marketing/message-analytics-point), [`MessageAnalyticsTotals`](/docs/api-reference/v3/reference/marketing/message-analytics-totals), [`MessageChannelAnalytics`](/docs/api-reference/v3/reference/marketing/message-channel-analytics)

<ResponseField name="averageOrderValue" type={<a href="/docs/api-reference/v3/reference/common/money">Money</a>}>
  `revenue / orders`. Null when there were no orders.

  <Expandable title="fields" lazyRender>
    <ResponseField name="amount" type={<a href="/docs/api-reference/v3/reference/common/decimal">Decimal!</a>} required>
      The exact amount as a decimal string (e.g. "19.99").
    </ResponseField>

    <ResponseField name="currency" type="String!" required>
      ISO 4217 currency code (e.g. USD).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="clickThroughRate" type="Float">
  `uniqueClicks / delivered`. Null when nothing was delivered.
</ResponseField>

<ResponseField name="clickToOpenRate" type="Float">
  `uniqueClicks / uniqueOpens`. Null when nothing was opened, so null on SMS.
</ResponseField>

<ResponseField name="conversionRate" type="Float">
  `orders / delivered`. Null when nothing was delivered.
</ResponseField>

<ResponseField name="delivered" type="Int!" required>
  Messages the provider confirmed were delivered.
</ResponseField>

<ResponseField name="deliveryRate" type="Float">
  `delivered / sends`. Null when nothing was sent.
</ResponseField>

<ResponseField name="failures" type="Int!" required>
  Messages the delivery provider refused or gave up on, so they never reached a delivery attempt. Distinct from a bounce, which is a delivery that came back — these never left. Together with `delivered` they account for what `sends` became.
</ResponseField>

<ResponseField name="newCustomerOrders" type="Int!" required>
  Attributed orders that are this customer's first paid order Redo has for the store. Complements `returningCustomerOrders`; the two sum to `orders`. Customers whose earlier orders fall outside the history Redo has synced are counted as new.
</ResponseField>

<ResponseField name="newCustomerRevenue" type={<a href="/docs/api-reference/v3/reference/common/money">Money!</a>} required>
  Attributed revenue from `newCustomerOrders`. Complements `returningCustomerRevenue`. Warehouse amounts sum to `revenue` before each is rounded to currency precision.

  <Expandable title="fields" lazyRender>
    <ResponseField name="amount" type={<a href="/docs/api-reference/v3/reference/common/decimal">Decimal!</a>} required>
      The exact amount as a decimal string (e.g. "19.99").
    </ResponseField>

    <ResponseField name="currency" type="String!" required>
      ISO 4217 currency code (e.g. USD).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="openRate" type="Float">
  `uniqueOpens / delivered`, over email deliveries only. Null when nothing measurable was delivered — including an SMS-only send, where opens do not exist and a rate of 0 would be misleading. For a continuously-sending automation this can exceed 1, since opens inside the range may belong to sends made before it.
</ResponseField>

<ResponseField name="orders" type="Int!" required>
  Orders attributed to this send within the attribution window.
</ResponseField>

<ResponseField name="recipients" type="Int!" required>
  Distinct customers sent to, counted once per day.
</ResponseField>

<ResponseField name="returningCustomerOrders" type="Int!" required>
  Attributed orders from customers who already had an earlier paid order on this store. Complements `newCustomerOrders`; the two sum to `orders`.
</ResponseField>

<ResponseField name="returningCustomerRevenue" type={<a href="/docs/api-reference/v3/reference/common/money">Money!</a>} required>
  Attributed revenue from `returningCustomerOrders`. Complements `newCustomerRevenue`. Warehouse amounts sum to `revenue` before each is rounded to currency precision.

  <Expandable title="fields" lazyRender>
    <ResponseField name="amount" type={<a href="/docs/api-reference/v3/reference/common/decimal">Decimal!</a>} required>
      The exact amount as a decimal string (e.g. "19.99").
    </ResponseField>

    <ResponseField name="currency" type="String!" required>
      ISO 4217 currency code (e.g. USD).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="revenue" type={<a href="/docs/api-reference/v3/reference/common/money">Money!</a>} required>
  Revenue attributed to this send.

  <Expandable title="fields" lazyRender>
    <ResponseField name="amount" type={<a href="/docs/api-reference/v3/reference/common/decimal">Decimal!</a>} required>
      The exact amount as a decimal string (e.g. "19.99").
    </ResponseField>

    <ResponseField name="currency" type="String!" required>
      ISO 4217 currency code (e.g. USD).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="revenuePerRecipient" type={<a href="/docs/api-reference/v3/reference/common/money">Money</a>}>
  `revenue / recipients`. Carries extra decimal places, since per-recipient revenue is routinely sub-cent. Null when nothing was sent.

  <Expandable title="fields" lazyRender>
    <ResponseField name="amount" type={<a href="/docs/api-reference/v3/reference/common/decimal">Decimal!</a>} required>
      The exact amount as a decimal string (e.g. "19.99").
    </ResponseField>

    <ResponseField name="currency" type="String!" required>
      ISO 4217 currency code (e.g. USD).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="revenuePerSend" type={<a href="/docs/api-reference/v3/reference/common/money">Money</a>}>
  `revenue / sends` — what a message returned, where `revenuePerRecipient` is what a customer returned. The two agree for a campaign, which sends to each recipient once, and diverge for a continuously-running automation that messages the same customer repeatedly over the range. This is the figure to compare against `spend`, which is also per message. Carries extra decimal places, since per-send revenue is routinely sub-cent. Null when nothing was sent.

  <Expandable title="fields" lazyRender>
    <ResponseField name="amount" type={<a href="/docs/api-reference/v3/reference/common/decimal">Decimal!</a>} required>
      The exact amount as a decimal string (e.g. "19.99").
    </ResponseField>

    <ResponseField name="currency" type="String!" required>
      ISO 4217 currency code (e.g. USD).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="sends" type="Int!" required>
  Messages handed to the delivery provider.
</ResponseField>

<ResponseField name="spend" type={<a href="/docs/api-reference/v3/reference/common/money">Money!</a>} required>
  What the store was billed to send these messages: its per-message rate plus any carrier fees. **Always USD**, unlike `revenue`, which is in the store's own currency — Redo prices messaging in dollars. Convert before combining the two. Carries extra decimal places, since one message costs a fraction of a cent.

  <Expandable title="fields" lazyRender>
    <ResponseField name="amount" type={<a href="/docs/api-reference/v3/reference/common/decimal">Decimal!</a>} required>
      The exact amount as a decimal string (e.g. "19.99").
    </ResponseField>

    <ResponseField name="currency" type="String!" required>
      ISO 4217 currency code (e.g. USD).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="uniqueClicks" type="Int!" required>
  Customers who clicked, counted once per day.
</ResponseField>

<ResponseField name="uniqueOpens" type="Int!" required>
  Customers who opened, counted once per day — so a customer who opens on two days counts twice over a range. Always 0 on SMS, which has no open tracking.
</ResponseField>

<ResponseField name="unsubscribeRate" type="Float">
  `unsubscribes / delivered`. Rated against deliveries rather than sends, like the other engagement rates, so it answers what share of messages that arrived cost a subscriber. Null when nothing was delivered.
</ResponseField>

<ResponseField name="unsubscribes" type="Int!" required>
  Customers who opted out of marketing off the back of this send. Only opt-outs the warehouse could attribute to a specific campaign or automation are counted, so these do **not** sum to the store's total unsubscribes over the same period — an opt-out arriving without that attribution belongs to no send and is absent here.
</ResponseField>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.