# Delivery and reporting

> Campaign statuses, what targeted, delivered, opened and failed mean, and how Grovs keeps the numbers right.

Source: https://docs.grovs.io/docs/engagement/push-campaigns/delivery-and-reporting

Open a campaign from **Engage › Push** to see its report. Numbers update live while it sends, and the counts are kept as long as the campaign exists.

## Campaign status

| Status                 | Meaning                                                                                                                                  |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Draft                  | Being written. Only drafts can be edited.                                                                                                |
| Scheduled              | Waiting for its send time. Can be cancelled.                                                                                             |
| Evaluating             | Grovs is resolving the audience: seconds for a list, longer for a large segment.                                                         |
| Sending                | Pushes are being handed to Apple and Google. Can be cancelled.                                                                           |
| Sent                   | Every device handed off. The last pushes reach Apple and Google seconds later, and pushes they asked to retry keep going out after that. |
| Waiting for the winner | Sent to the test share of an [experiment](https://docs.grovs.io/docs/engagement/experiments). The rest get the winning variant later.    |
| Failed                 | The audience couldn't be resolved. The report shows why.                                                                                 |
| Cancelled              | Stopped before every device got it.                                                                                                      |

Why a campaign fails:

| Reason            | What happened                                                                         | What to do                      |
| ----------------- | ------------------------------------------------------------------------------------- | ------------------------------- |
| Segment busy      | The segment couldn't be evaluated in ten attempts over about three hours.             | Retry later with **Duplicate**. |
| Segment invalid   | The segment was archived, its definition no longer works, or its time window expired. | Fix the segment.                |
| Segment too heavy | The segment query was too expensive to run.                                           | Narrow the segment.             |
| Evaluation error  | Something else went wrong.                                                            | Contact support.                |

## Reach

**Reach** tracks every device in the audience:

| Number                 | Meaning                                                                                          |
| ---------------------- | ------------------------------------------------------------------------------------------------ |
| Targeted               | Devices selected for this push. Excludes the control group.                                      |
| No channel             | No push token on file, or a web or desktop device. Skipped.                                      |
| Not found              | A user ID or device ID in your list that Grovs doesn't know.                                     |
| Queued                 | Handed to the push service, no result yet.                                                       |
| Delivered              | Accepted by APNs or FCM. Not proof it was shown: the phone may be off or notifications disabled. |
| Failed                 | Rejected by APNs or FCM, or not sent. See [Failures](#failures).                                 |
| Opened                 | Tapped, as reported by the SDK.                                                                  |
| Cancelled              | Not sent because the campaign was cancelled first.                                               |
| Control group          | Held back on purpose, for comparison.                                                            |
| Waiting for the winner | Outside the test share. Sent once a variant is chosen.                                           |

The report also shows audience size in people and devices. A segment whose time window reaches past your data retention is marked incomplete.

### How opens are counted

- An open is a tap on the notification reported by the SDK. Dismissing it or tapping a custom action button doesn't count. See [Push notifications on iOS](https://docs.grovs.io/docs/sdk/ios/push-notifications).
- Each device counts once per campaign, however many taps or SDK retries.
- The open is recorded as a `push_open` event with the campaign ID, visible in your analytics.
- A tap on a push with a deep link isn't also counted as a link open, and later events from that device aren't attributed to the link. The push gets the credit, once.
- Android devices don't report opens yet.

## Failures

**Failures by reason** groups failed devices by Apple's or Google's answer. APNs reasons keep their name; FCM failures show the HTTP status.

| Reason            | Meaning                                                                                                                                                                                 |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Unregistered`    | App uninstalled or token expired. Grovs removes the token.                                                                                                                              |
| `BadDeviceToken`  | A malformed token, or one from the other APNs environment. See [Tokens](https://docs.grovs.io/docs/engagement/push-campaigns/limits-and-troubleshooting#how-grovs-handles-push-tokens). |
| `PayloadTooLarge` | The notification exceeded the size limit.                                                                                                                                               |
| FCM `404`         | Device not registered. Grovs removes the token.                                                                                                                                         |
| `no_app`          | No push credentials for this platform. Add them in **Developers › SDK Setup**.                                                                                                          |
| `no_token`        | The device lost its token between the audience freeze and delivery.                                                                                                                     |
| `capped`          | The person already hit the daily maximum. See [Daily cap](https://docs.grovs.io/docs/engagement/push-campaigns/limits-and-troubleshooting#daily-cap).                                   |
| `app_removed`     | Your push credentials were replaced or removed while the push waited.                                                                                                                   |

More reasons: [Limits and troubleshooting](https://docs.grovs.io/docs/engagement/push-campaigns/limits-and-troubleshooting#common-failures).

## Deliveries

The **Deliveries** table lists every device with its status, platform, visitor, any error, and open time. Filter by status, for example to find every failed device.

Per-device rows are kept for 30 days after the send. Report counts are kept for good.

## How the numbers stay accurate

- **At least once.** Grovs marks a push queued and hands it off in one step, so a crash never sends a batch twice. If the push service stops after Apple or Google accepted a push but before saving that, the push is resent on restart. A rare duplicate is possible; a lost push is not.
- **Retries.** APNs `429`, `500` and `503` are retried every 10 seconds until accepted. FCM `5xx` is retried with backoff, and FCM `429` up to 8 retries.
- **Reconciliation.** Every minute, Grovs settles devices still **Queued** after 10 minutes from the push service's own record. If a result was lost, the report catches up on its own.
