Offerings, placements and packages
Read current, placed or exact offerings, distinguish current/default and refresh attributes plus offerings within quota.
After configuration and identity, let the SDK select the customer's offer. The first catalog entry is not necessarily appropriate.
Three selection modes
| Intent | Input | Behavior |
|---|---|---|
| Customer's current offer | No placement | Selected current, otherwise default |
| Display location such as upgrade | placementIdentifier: 'upgrade' | Placement selection with current/default fallback |
| One exact offering | getOffering('special_offer') | Exact lookup; missing is null, not substitution |
A placement is a display location; an offeringIdentifier identifies the offer. Targeting can make current differ from the project default. Mobile uses server selection; Web uses the provider's existing rules/fallback resolver.
Flutter
Convenience getOfferings(), getCurrentOffering(placementIdentifier: ...) and getOffering(id) return nullable models. A successful offering lookup with null data is different from network failure.
Kotlin
Collection helpers make no HTTP call. Kotlin/Flutter all is an identifier map. Retain the complete package for purchase; don't reconstruct it from name or price.
JavaScript
JS catalog.all is an array. The old object form getCurrentOffering({placementIdentifier: 'upgrade'}) remains compatible; prefer the simple form above for new code.
Manual refresh
On Kotlin/Flutter mobile, await syncAttributesAndOfferingsIfNeeded() and select from its returned collection. It synchronizes pending attributes before fresh offerings, including a fresh fetch when the queue is empty and quota permits. See attributes.
Each client admits five executions per rolling 60 seconds. Admitted failures count and account changes do not reset quota. Above the limit there is no network: return current-session cache or RATE_LIMITED_NO_CACHE with retry timing in failure details. Do not recreate the SDK to evade the limit.
Normal reads use cache. Android automatic offering refresh runs in foreground with a five-minute freshness window and thirty-second error backoff; it is separate from manual quota. No additional startup pre-warming is needed.
Mobile getCurrentOffering has no refresh, forceRefresh or context argument. Flutter Web 0.2.1 does not implement combined sync, although direct JS 0.2.0 does. Follow the platform matrix.
Missing offers or products
Check placement/offering identifiers, catalog membership, app key, store SKU and targeting conditions. Distinguish failed fetch from a successful empty collection. Do not fabricate packages or silently replace an explicitly requested offering.