# Offers

Offers describe the commercial terms available to the authenticated issuer.

## Listing and lookup

- `GET /api/v1/omni/offer` returns offers that are current or upcoming for the issuer.
- `GET /api/v1/omni/offer/{offerId}` returns one issuer-scoped offer by UUID and supports historical lookup after an offer has ended.


The list is ordered by start date and then offer ID. Treat ordering as a convenience, not an incremental synchronization cursor.

## Immutability

An offer is immutable after creation except for `endDate`. Percents can extend, shorten, or end an offer by changing that field. A change to any other published commercial term is represented by a new offer with a new `id`.

Consumers should therefore:

- key records by offer `id`;
- allow `endDate` to change during synchronization;
- never overwrite the historical terms of one offer ID with terms from another; and
- retain ended offers when reconciliation requires historical lookup.


## Field reference

| Field | Meaning |
|  --- | --- |
| `id` | Stable Omni offer UUID |
| `merchantId` | Omni merchant UUID used by merchant lookup |
| `spatialCondition` | `online`, `offline`, or `onlineAndOffline` |
| `cardholderRate` | Cardholder reward rate in basis points when `rateIsPercent` is true; otherwise a minor-unit fixed amount |
| `publisherRate` | Publisher rate in basis points when `rateIsPercent` is true; otherwise a minor-unit fixed amount |
| `startDate` | Inclusive California calendar date in `YYYY-MM-DD`; never a timestamp or time-zone-qualified value |
| `endDate` | Inclusive California calendar date in `YYYY-MM-DD`, or `null` for an open-ended offer; never a timestamp or time-zone-qualified value |
| `minSpend` | Minimum eligible transaction amount in minor currency units, or `null` |
| `maxEarn` | Maximum cardholder reward per qualifying transaction in minor currency units, or `null` |
| `maxTransactionValue` | Maximum eligible transaction amount in minor currency units, or `null` |
| `maxRedemptions` | Maximum qualifying redemptions per cardholder, or `null` |
| `segment` | Cardholder lifecycle segment: `new`, `loyal`, `lapsed`, or `null` when no segment restriction applies |
| `description` | Required, customer-facing English copy that explains the reward and all applicable availability and eligibility restrictions |
| `rateIsPercent` | Controls both rates: `true` means `cardholderRate` and `publisherRate` are basis-point percentages; `false` means both are minor-unit fixed amounts |


When `rateIsPercent` is `false`, both rate fields are integers in the currency's minor unit. For USD, `500` means `$5.00`. When it is `true`, both rate fields are basis points; `1250` means `12.50%`.

The required `description` must be clear, high-quality English for a cardholder. It must not hide eligibility in a generic phrase such as "terms apply." State the reward, eligible channel, calendar dates, minimum spend, maximum transaction value, maximum reward, redemption cap, and segment restriction whenever each applies. The structured fields remain the source of truth for matching.

Offer calendar dates are defined in `America/Los_Angeles` (California time), including across daylight-saving transitions. For example, an `endDate` of `2026-09-30` remains active through the end of September 30 in California. This date-only rule is the public Omni API contract; internal partner reporting records may retain timestamp precision.

## Eligibility boundaries

A transaction must satisfy every applicable constraint, including date, spatial condition, minimum spend, maximum transaction value, segment requirements, and redemption count. Do not display an unconstrained offer by discarding nullable constraint fields; `null` means the specific constraint is not set.