> For the complete documentation index, see [llms.txt](https://docs.amply.tools/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amply.tools/concepts/campaign-delivery.md).

# Campaign delivery

How an active campaign actually reaches a user. This page covers triggers (what causes a campaign to fire), frequency (how often it can fire for the same user), and rollout (how you take a campaign live safely and roll back instantly if something is wrong).

## The delivery model in one paragraph

Amply ships a configuration of active campaigns to each device. The SDK evaluates that configuration locally on every event. When an event matches a campaign's trigger, and the user passes the campaign's targeting, and the frequency rules allow it, the campaign's action runs on the device — an external URL opens, a deeplink routes to one of your screens, or the native rate prompt appears. Because the configuration is delivered from the server, you change campaigns without releasing the app.

## Triggers — what causes evaluation

A trigger is an event plus optional conditions on that event's properties. Every active campaign has exactly one trigger.

The event can be a standard event emitted by the SDK, or a custom event you call `track()` on. See [Sessions and events](/concepts/sessions-and-events.md) for the full list.

### Session-start campaigns

Set the trigger event to the standard `SessionStarted` event. The campaign is considered every time the user opens the app.

Common uses:

* Show a paywall on session N.
* Reactivate users whose last session was more than 7 days ago.
* Route first-time users into an onboarding variant.

### Event-triggered campaigns

Set the trigger event to any custom event you track in your app.

Common uses:

* Trigger a rate prompt after `PurchaseCompleted`.
* Open a feature-discovery deeplink after `CoreActionCompleted`.
* Show a winback deeplink when `CheckoutAbandoned` fires.

### Event-property conditions on the trigger

A trigger can filter on the event's properties. For example, the trigger `PurchaseCompleted` can additionally require `plan == "annual"`. This is separate from audience targeting (which filters on the user). Property conditions filter on the event occurrence.

## Frequency — how often a campaign can fire

Amply models frequency in two parts: a repeat rule and a limit. Together they answer "at which occurrences of the trigger should the campaign fire, and what is the overall cap?"

### Repeat rule — which occurrences fire

Two repeat modes, applied against either event count or session count:

* **Every N** — fire on every Nth occurrence. "Every 3rd session", "every 5th `FeatureViewed`".
* **Interval** — fire on specific occurrence numbers from a list. "On sessions 2, 4 and 7" or "on the 1st and 10th `SearchPerformed`".

The "entity" picks what you are counting:

* **event** — count all occurrences of this event across the user's history.
* **session** — count occurrences within the current session only.

Plain-English examples:

* "Show on every 3rd session from session 3 onwards" — repeat type = every, entity = session, value = 3.
* "Show on session 2 and session 5 only" — repeat type = interval, entity = session, value = \[2, 5].
* "Show every 10th `PurchaseCompleted`" — repeat type = every, entity = event, value = 10.

### Limit — the overall cap

A limit caps total impressions over a window:

* **Count per device or per session** — "at most 3 times, ever" or "at most 1 time in this session".
* **Rate limit over a time window** — "at most 1 impression per day", "at most 2 per hour".

Limits are evaluated in addition to the repeat rule. Even if the repeat rule matches, the limit can block the impression.

## Rollout controls

Rollout is how you take a campaign from "it looks right in the dashboard" to "it is live for everyone" without surprises.

### Audience targeting as rollout

The simplest rollout is to narrow the audience. Start active with a tight audience (for example: internal testers identified by a custom property, one country, one app version), verify impressions, then widen by editing the targeting rule.

Because targeting is evaluated live, broadening the audience instantly adds users to eligibility; narrowing it instantly removes them.

### State-based rollout

Every campaign has a state: Draft, Active, or Cancel. See [Scenarios and campaigns](/concepts/scenarios-and-campaigns.md) for the lifecycle.

* While editing, keep the campaign in **Draft**. No device sees it.
* When ready, flip to **Active**. It goes live on every device within moments — no app release.
* To stop it, flip to **Cancel**. It stops firing on every device within moments.

### Instant rollback

Rolling back a bad campaign is the same as flipping it to **Cancel** in the dashboard — it stops firing on every device within moments. You do not need an app release, a code change, or a feature-flag provider.

This is the core promise: in-app behavior is editable without a release.

## Order of evaluation

When an event fires on a device, the SDK:

1. Finds every active campaign whose trigger event matches.
2. For each match, evaluates the campaign's targeting against the current user.
3. For each targeted match, evaluates the frequency rules (repeat + limit).
4. Runs the action for the first campaign that passes all three.

Only one campaign fires per event. Order your campaigns so that the more specific, more time-sensitive campaigns sit above the fallback ones.

## What happens if the SDK can't reach the server

If the device is offline, the SDK uses the most recently fetched configuration. Campaigns already known to the device continue to evaluate. A newly activated campaign on the server reaches the device only on its next successful fetch.

For the practical side — previewing before going live, staged rollout, rolling back — see [Testing and rollout](/user-guide/testing-and-rollout.md).

## Related

* [Scenarios and campaigns](/concepts/scenarios-and-campaigns.md) — the Draft / Active / Cancel lifecycle
* [Sessions and events](/concepts/sessions-and-events.md) — what events you can trigger on
* [Targeting and audiences](/concepts/targeting-and-audiences.md) — the Who layer
* [Campaign actions](/concepts/campaign-actions.md) — what actually runs when the campaign fires
* [Testing and rollout](/user-guide/testing-and-rollout.md) — how-to for safe deployment
* [Creating a campaign](/user-guide/creating-a-campaign.md) — end-to-end dashboard walkthrough


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.amply.tools/concepts/campaign-delivery.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
