> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encorekit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# placement()

> Present Encore offers with an immutable builder that resolves to a result record

Creates a placement builder for presenting offers. It is the one way to present, and it matches the builder across every Encore SDK.

## Signature

```dart theme={null}
static EncorePlacementBuilder placement([String? id])

class EncorePlacementBuilder {
  EncorePlacementBuilder useCase(EncoreUseCase useCase);
  EncorePlacementBuilder headline(String text);
  EncorePlacementBuilder subheadline(String text);
  Future<EncorePresentationResult> show();
}
```

`placement()` is static: call it as `Encore.placement('cancel_flow')`.

Each option returns a **new** builder, so a builder can be reused or shared without one call site changing another's configuration.

## Parameters

| Name | Type      | Description                                                                                                                         |
| ---- | --------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `id` | `String?` | The placement identifier configured in the Encore Dashboard. Pass it so results and analytics are attributed to the right placement |

## show()

```dart theme={null}
final result = await Encore.placement('cancel_flow').show();
```

`show()` fetches offers, presents the native offer sheet, and completes when the presentation record is sealed. It **never throws** on iOS or Android: every failure, including "nothing was presented", is a value on the returned [`EncorePresentationResult`](./presentation-result).

```dart theme={null}
final result = await Encore.placement('cancel_flow').show();

if (result.claim != null || result.publisher == EncorePublisherOutcome.purchased) {
  grantAccess();
} else {
  proceedWithCancellation();
}
```

## Use cases

`useCase()` selects which Encore surface the placement presents. It defaults to `EncoreUseCase.reduceChurn`.

```dart theme={null}
await Encore.placement('workout_completed')
    .useCase(EncoreUseCase.rewardUsers)
    .headline('Five workouts this week 🔥')
    .subheadline("Here's a little thank you from us")
    .show();
```

```dart theme={null}
enum EncoreUseCase {
  reduceChurn('churn-intervention'),
  rewardUsers('post-action-reward');

  final String nativeValue;
}
```

| Case                        | Wire value           | Surface                                                                                                |
| --------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------ |
| `EncoreUseCase.reduceChurn` | `churn-intervention` | Second-chance monetization after a paywall decline. The default                                        |
| `EncoreUseCase.rewardUsers` | `post-action-reward` | A brand-funded reward at a moment the user just accomplished something. Claim-only; never presents IAP |

The case names describe the capability; `nativeValue` is the label the backend stores.

<Note>
  A use case with no enabled variant resolves `EncoreNotPresented` with `EncoreNotPresentedReason.useCaseUnavailable` rather than falling back to the churn-intervention sheet.
</Note>

## Copy overrides

`headline()` and `subheadline()` override the sheet's copy for one presentation, on **every** use case. The native side writes the value into the variable the active template reads.

Priority order, first one set wins: this value, then the copy configured for your app in the Encore portal, then the shipped template default. A blank string is ignored.

You pass the finished string, so localization, pluralization, wording, and emoji stay yours.

## Platform notes

* **iOS** presents only on iOS 17 or later. On older versions `show()` resolves `EncoreNotPresented` with `EncoreNotPresentedReason.unsupportedOS`, even though the plugin installs on iOS 15.
* **Android** attaches the sheet to the Activity the plugin is bound to. With no foreground Activity, `show()` resolves `EncoreNotPresentedReason.noForegroundActivity`.

## Related

* [EncorePresentationResult](./presentation-result): what `show()` resolves to
* [EncorePurchaseController](./purchase-controller): the purchase path a presented offer runs through
* [Reward Users](/publishers/use-cases/post-action-reward) and [Reduce Churn](/publishers/use-cases/churn-intervention) for what each surface is for
