Skip to content

Search the documentation by title, section, or page text.

Adapty

Integrate Botsi AI Pricing with Adapty so each user sees the optimal paywall based on Botsi's prediction. Adapty handles paywall display and audience targeting. Botsi decides which paywall that user should get.

Complete the AI Pricing Model Setup first. This page assumes the Botsi side already works end to end.

Integration flow#

Adapty integration flow across Launch, Onboarding, At the paywall, and Purchase

  1. Create a Botsi Profile at launch and keep the profileId.
  2. Send events, attributes, and attribution during onboarding so the model has signal.
  3. Call Fetch Paywall with the profile and placement → receive the predicted externalId (and paywallSessionId).
  4. Set an Adapty custom attribute to that externalId.
  5. Fetch the Adapty paywall for your placement → Adapty returns the paywall matched by audience targeting.
  6. Send paywall_shown via the Send Paywall Shown Event API when the paywall is presented.
  7. Validate the purchase with Botsi after a successful Adapty transaction.

See the full API sequence in the AI Pricing Model API.

Matching paywalls in Adapty and Botsi#

Decide which prices you want to show, then configure paywalls on both sides with the same products.

In Adapty, create Paywalls with the products and price points you want to test. For several annual price points:

  • Paywall standard_paywall — annual → com.app.pro.annual_standard
  • Paywall discounted_paywall — annual → com.app.pro.annual_discounted

Then create corresponding Paywalls in Botsi and attach the same Products. That is what tells the model which prices are available to choose between.

External ID and Fetch Paywall#

Set the external ID on each Botsi Paywall when you configure it. Any unique value works; a readable convention pays off when you see the same string in Adapty audiences and Botsi analytics (for example onboardingPaywall_29.99Annual_v2).

Fetch Paywall returns that value as data.externalId. You could use data.id instead, but it is a number you cannot set or recognize at a glance. Use externalId.

Audience targeting with a custom attribute#

Write the externalId into an Adapty custom attribute, then fetch the paywall. The attribute name is yours; something like botsi_paywall_id or botsi_paywall_prediction is legible to teammates. Use the externalId as the value.

Configure Adapty audiences to filter on that attribute so each predicted ID maps to the matching Adapty Paywall. See Adapty's audience docs and add audience and paywall to placement guide.

Set the attribute before fetching the paywall

Adapty resolves audience targeting when you request the paywall. An attribute written afterwards has no effect on the paywall already returned.

// Set the custom attribute with Botsi's predicted paywall ID
var builder = AdaptyProfileParameters.Builder()
builder = try builder.with(customAttribute: botsiExternalPaywallId, forKey: "botsi_paywall_id")
try await Adapty.updateProfile(params: builder.build())

// Then fetch the paywall — Adapty uses the attribute for targeting
let paywall = try await Adapty.getPaywall(placementId: "your_placement_id")

Sending the impression#

When the paywall is shown, send paywall_shown with the paywallSessionId from the Fetch Paywall response. Details: Send Paywall Shown Event.

Sending the purchase#

After a successful purchase through Adapty, extract the iOS transaction ID and original transaction ID, or the Android purchase token, and post them to the matching validate endpoint.

let result = try await Adapty.makePurchase(product: product)

if let transaction = result.sk2Transaction {
    let appleTransactionId = transaction.id       // e.g. "2000001234567890"
    let originalTxId = transaction.originalID     // stable across renewals
    // POST /v2/purchases/apple-store/validate
}

See Validate Apple Store Purchase and Validate Google Play Store Purchase. Adapty's own purchase handling is covered in their iOS, Android, and React Native purchase docs.

Reporting revenue through the Adapty webhook#

Botsi can receive Adapty's webhook and record App Store and Google Play revenue from it for revenue reporting. The webhook records revenue only: it doesn't change subscriber status or Access Levels. See Notification URLs.

Connecting the webhook#

Botsi generates the Authorization value Adapty sends, instead of you choosing one.

  1. In Botsi, go to App Settings → Adapty → Connect your webhook and copy the Webhook URL.
  2. Generate the Authorization value for production. If you test, generate a separate one for sandbox too.
  3. Copy each value immediately. Botsi shows it once, when it's generated.
  4. In Adapty's webhook integration, enter the Webhook URL and the Authorization value.
  5. In the same Adapty settings, keep the default event names, turn Exclude historical events on, and turn Send attribution and Send Play Store purchase token off.

To rotate a value, generate a new one in Botsi. The previous value stays valid for 24 hours, which gives you time to update Adapty.

When Adapty reports your revenue, don't send App Store or Google Play notifications to Botsi as well. Only one of RevenueCat, Superwall, and Adapty can report an app's revenue at a time. See Using one revenue platform at a time.

How Botsi verifies deliveries#

The Authorization header must equal a current Botsi-generated value, or a previous one still within its 24-hour grace period. The value's environment must also match the event's environment, so a sandbox value only authenticates sandbox events.

Adapty's verification request, which has an empty {} body, is answered with 200 and {}.

What the webhook records#

App Store and Google Play revenue, for revenue reporting. Status events are recorded at $0.

Webhook responses#

StatusWhen
200The event was stored
400The event is invalid
401The Authorization value doesn't match
403The integration isn't configured or is disabled, or the value's environment doesn't match the event's
503Storing the event failed

Notes#

  • Configure server-side notifications in both Adapty and Botsi for accurate analytics.
  • The custom attribute you set must match the audience filters in the Adapty dashboard, or targeting silently fails to match.
  • Handle errors from both APIs. A failed Fetch Paywall should fall back to a known paywall rather than showing nothing.
  • Test in sandbox before production.