# Create a campaign

> Write a push, choose who gets it, and send it now, at a set time or at the same hour in each user's own timezone.

Source: https://docs.grovs.io/docs/engagement/push-campaigns/create-a-campaign

Go to **Engage › Push** and click **New campaign**. The composer has four steps: **Message**, **Audience**, **Experiment** and **Delivery**. **Save draft** keeps your work; a draft stays editable until you send it.

The example is Fitloop, a fictional fitness app, bringing back people who haven't logged a workout this week.

## 1. Message

What people see on the lock screen, and where a tap takes them. The preview shows the notification on iOS and Android as you type.

| Field           | What to enter                                                                                             | Limits                                                                                           |
| --------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| **Title**       | The bold first line.                                                                                      | 255 characters.                                                                                  |
| **Body**        | The text under the title.                                                                                 | 1,000 characters.                                                                                |
| **Image**       | Upload an image, or paste an `https://` URL.                                                              | PNG, JPEG or GIF. Uploads up to 1 MB. Around 1038 × 1038 px works well; Grovs doesn't resize it. |
| **Deep link**   | A Grovs link from this project. Search by name, title or path.                                            | Optional. **No link** opens the app.                                                             |
| **Custom data** | Key–value pairs delivered to your app with the push.                                                      | 2 KB in total.                                                                                   |
| **Sound**       | **Default sound**, **Silent**, or **Custom…** with a sound file bundled in your app, such as `chime.caf`. | 64 characters. On Android, the sound needs a notification channel that uses it.                  |

The whole notification must fit Apple's 4 KB payload limit. A long body plus a long image URL or lots of custom data can exceed it. Grovs then refuses to save and shows the size.

**On tap**, your app receives the link's data merged with your custom data, through the same callback as any Grovs deep link. Grovs adds `grovs_campaign_id`, plus `grovs_link` and `grovs_image` when set. These names are reserved. Keys that would break the APNs or FCM payload are refused, such as `aps`, `notification` and keys starting with `google` or `gcm`. See [What your app receives](https://docs.grovs.io/docs/sdk/ios/push-notifications#what-your-app-receives).

> **Note:** iOS images need a Notification Service Extension in your app, or the push arrives without its image. See [Campaign images](https://docs.grovs.io/docs/sdk/ios/push-notifications#4-campaign-images-optional). Android shows images natively.

## 2. Audience

Pick one of three tabs:

| Tab             | Sends to                                                                                    | Notes                                                                           |
| --------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| **Segment**     | Every device of every person in a [segment](https://docs.grovs.io/docs/analytics/segments). | Evaluated at send time. Later segment edits don't change who got this campaign. |
| **My user ids** | Every device of each user ID your app set with the SDK, up to 50 devices per user.          | Up to 10,000 IDs.                                                               |
| **Devices**     | Single devices, by device ID.                                                               | Up to 10,000 IDs.                                                               |

For the two lists, type or paste IDs one per line or comma-separated, upload a CSV, or use **Add from visitors** to search and add visitors. Duplicates are dropped. To send to one person, add only their user ID or device ID.

**Estimated reach** updates after each saved change. Per platform, it shows the audience's devices, those with no way to get a push (**No channel**) and those on a platform you haven't set up. For a segment, the platform split is estimated from devices active in the last 30 days, and may be skipped for a very large segment.

> **Note:** The audience is frozen when the campaign goes out. People who sign in or join the segment afterwards aren't added.

### Testing your campaign

There is no test button. To check a campaign on your phone, send it with the **Devices** tab and your device ID, or **My user ids** and your user ID. Then click **Duplicate** on the report to make the real campaign. Xcode builds only get pushes from the Grovs test environment.

## 3. Experiment (optional)

Measure what the push does. You can:

- set a **goal**, such as Fitloop's `workout_logged` event within 1 day
- hold back a **control group** that doesn't get the push
- add up to two **variants** of the title and body in the Message step, send them to a **test share** first, then the winner to everyone else

See [Experiments](https://docs.grovs.io/docs/engagement/experiments).

## 4. Delivery

Choose **Send now** or **Schedule**.

- **Send now** starts a few seconds after you confirm.
- **Schedule** sends at a date and time up to 30 days ahead, read in your browser's timezone. You can cancel until it starts sending.

### Each user's local time

Under **Schedule**, turn on **Deliver in each user's local time** to send at the same wall-clock time everywhere: 09:00 in Berlin, then 09:00 in New York. Grovs uses the timezone each device last reported. Devices without one use the timezone you pick below the switch.

The first devices to reach 09:00 are in UTC+14, so delivery starts that early and spans about 26 hours. Schedule at least 14 hours minus your zone's UTC offset ahead:

| Your timezone                        | Minimum lead time |
| ------------------------------------ | ----------------- |
| Europe/Berlin, winter (UTC+1)        | 13 hours          |
| America/Los_Angeles, summer (UTC−7) | 21 hours          |
| Asia/Tokyo (UTC+9)                   | 5 hours           |

The composer shows the minimum when the time is too close. A device whose slot has already passed gets the push right away. Local-time delivery can't be combined with an experiment test share.

### Confirm

Click **Send now** or **Schedule…**. The confirmation shows the title, audience, reach, experiment and time.

Only drafts can be edited. A scheduled or sent campaign stays as it is and is never sent twice. To resend, with or without changes, use **Duplicate** to make a new draft.

## Cancel a campaign

Cancel a draft, scheduled or sending campaign from its menu or the **Cancel** button on its report.

- **Scheduled**: nothing is sent.
- **Sending**: devices not yet handed to Apple or Google are dropped and counted as **Cancelled**. Batches already in flight still go out, at most about 1,000 devices per platform.
- **Waiting for the winner**: people still waiting don't get the push.

Cancel is unavailable for the few seconds a campaign is being evaluated.
