# Using ContextSDK with Superwall

ContextSDK integrates seamlessly with Superwall to help you show paywalls at the perfect moment. This integration leverages ContextSDK's ML-powered recommendations to optimize when Superwall displays paywalls, improving conversion rates.

## How it works

ContextSDK provides real-world context about whether it's a good moment to show a paywall through the **`shouldUpsell`** property - a boolean indicating whether it's a good moment to show a paywall.

This value is passed to Superwall as a parameter (`contextGoodMoment`), allowing you to:

* Use it in paywall display rules
* Track it in your analytics
* A/B test different timing strategies

## Integration Guide

### Step 1: Capture Context and Show Paywall

Before showing a paywall, capture the user's context using `instantContext` and pass it to Superwall:

```swift
import ContextSDK
import SuperwallKit

class OnboardingViewController: UIViewController {

    func showPaywall() {
        // 1. Capture the user's context
        let context = ContextManager.instantContext(flowName: "superwall_onboarding_step", duration: 3)

        // 2. Create handler for paywall callbacks
        let handler = PaywallPresentationHandler()
        handler.onDismiss { paywallInfo, result in
            switch result {
            case .purchased(let product):
                // User completed a purchase
                context.logRevenueOutcome(from: product)

            case .declined:
                // User declined the paywall by pressing close button
                context.log(.negative)

            case .restored:
                // User restored their purchases
                context.log(.skipped)

            default:
                context.log(.skipped)
            }
        }
        handler.onSkip { reason in
            // Paywall was skipped (no paywall configured, user already subscribed, etc.)
            context.log(.skipped)
        }

        // 3. Register Superwall placement with context
        Superwall.shared.register(
            placement: "onboarding_step",
            params: ["contextGoodMoment": context.shouldUpsell],
            handler: handler
        )
    }
}
```

### Step 2: Use Context in Superwall Rules

You can use the context parameter in Superwall's display rules to control when paywalls appear:

**In Superwall Dashboard:**

1. Go to your paywall configuration
2. Add display rules using the parameter:
   * `contextGoodMoment` (Boolean)

**Example rule:**

* Show paywall only when `contextGoodMoment` is `true`

This gives you the flexibility to A/B test different strategies and adjust timing logic without code changes.

## Best Practices

### Choose a Flow Name

Select a descriptive flow name that represents your use case. Use a consistent naming pattern with the `superwall_` prefix:

```swift
// Examples of good flow names:
ContextManager.instantContext(flowName: "superwall_onboarding_step", duration: 3)
ContextManager.instantContext(flowName: "superwall_premium_upgrade", duration: 3)
ContextManager.instantContext(flowName: "superwall_feature_unlock", duration: 3)
```

### Always Log Outcomes

**Critical:** Always log an outcome for every context you create. This data trains the ML model:

```swift
let handler = PaywallPresentationHandler()

// Log outcomes in onDismiss
handler.onDismiss { paywallInfo, result in
    switch result {
    case .purchased(let product):
        context.logRevenueOutcome(from: product)
    case .declined:
        context.log(.negative)
    case .restored:
        context.log(.skipped)
    default:
        context.log(.skipped)
    }
}

// Always log skipped when paywall doesn't show
handler.onSkip { reason in
    context.log(.skipped)
}
```

### Handle Multiple Placements

You can use this pattern across multiple placements in your app:

```swift
func showOnboardingPaywall() {
    let context = ContextManager.instantContext(flowName: "superwall_onboarding", duration: 3)
    showSuperwall(placement: "onboarding_step", context: context)
}

func showSettingsPaywall() {
    let context = ContextManager.instantContext(flowName: "superwall_settings", duration: 3)
    showSuperwall(placement: "settings", context: context)
}

private func showSuperwall(placement: String, context: Context) {
    let handler = PaywallPresentationHandler()
    handler.onDismiss { paywallInfo, result in
        switch result {
        case .purchased(let product):
            context.logRevenueOutcome(from: product)
        case .declined:
            context.log(.negative)
        case .restored:
            context.log(.skipped)
        default:
            context.log(.skipped)
        }
    }
    handler.onSkip { reason in
        context.log(.skipped)
    }

    Superwall.shared.register(
        placement: placement,
        params: ["contextGoodMoment": context.shouldUpsell],
        handler: handler
    )
}
```

## Related Documentation

* [Revenue Outcomes](/context-decision/revenue-outcomes.md) - Learn more about logging revenue outcomes
* [Logging Conversions](/context-decision/logging-conversions.md) - General guide to logging outcomes
* [Custom Outcome Metadata](/context-decision/advanced/custom-outcome-metadata.md) - Track additional purchase context

{% hint style="success" %}
ContextSDK's ML models learn from your outcome data. The more purchases you log with `logRevenueOutcome()`, the better the model becomes at predicting optimal moments to show paywalls.
{% endhint %}


---

# Agent Instructions: 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.contextsdk.com/context-decision/revenue-outcomes/superwall.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.
