Loyalty

Preview a campaign audience

Estimate the reach of a targeting filter before a campaign is created or sent. Returns how many opted-in customers match the filter, how many are reachable right now, and how many are temporarily withheld by the per-card notification cap (with the time the whole audience frees up). This is a wizard estimate: the authoritative per-recipient consent and cap checks run again at send time. A POST (not GET) because the targeting filter is a structured body, but it has no side effects.

post/v1/loyalty/campaigns/audience-preview

Request

  • Base URL: https://api.prod.keyban.io
  • URL: https://api.prod.keyban.io/v1/loyalty/campaigns/audience-preview
  • Auth: API key in header X-Api-Key

Request body

applicationIdstring uuid required

Application (brand) whose audience is previewed. The preview is scoped to this application only, matching the application a campaign is created against.

channelsstring[]

Wallet channels the campaign targets. A matching customer is reachable only if they have an installed card on at least one of these channels — the same per-channel card check the send pipeline applies (NoCardOnChannel). Omitted means "any channel": a card on either Apple or Google counts.

Example request

{
  "applicationId": "550e8400-e29b-41d4-a716-446655440000",
  "targeting": {
    "minPoints": 100,
    "maxPoints": 500,
    "minVisits": 3,
    "rewardTierIds": [
      "550e8400-e29b-41d4-a716-446655440000"
    ]
  },
  "channels": [
    "google",
    "apple"
  ]
}

Response

Audience preview computed successfully

matchingCountinteger required

Opted-in customers matching the targeting filter — the campaign reach before the frequency cap and the card-installation check are applied.

accessibleCountinteger required

Subset of matching customers reachable right now: they have an installed wallet card on at least one targeted channel and are below the all-channel notification cap over the rolling window. Invariant: accessibleCount + cappedCount + noCardCount === matchingCount.

cappedCountinteger required

Subset of matching customers that have an installed card but are temporarily withheld because they already hit the notification cap. They become reachable again at fullAvailabilityAt.

noCardCountinteger required

Subset of matching customers with no installed wallet card on any targeted channel (Apple pass never registered on a device, or Google card never added). They match the targeting and consented, but the send pipeline excludes them as NoCardOnChannel, so they are not reachable.

fullAvailabilityAtstring date-time nullable required

Earliest RFC 3339 instant at which every capped customer can be reached again. Null when cappedCount is 0 (no customer is capped). Serialized from a Date to an ISO 8601 string by the HTTP layer.

Example response

{
  "matchingCount": 1234,
  "accessibleCount": 1180,
  "cappedCount": 54,
  "fullAvailabilityAt": "2026-06-17T09:00:00Z"
}

Changes

No recorded changes to this operation across all 1 revision of this API.