Skip to content

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

Send Paywall Shown Event

POST https://api.botsi.com/v2/events

Call this immediately after the Paywall is displayed. The impression is what conversion is measured against, and what lets the model learn from the outcome.

Impressions are not deduplicated. Sending the same event twice for one paywallSessionId records two impressions, so send it once per Paywall view.

Request body#

The body is a single JSON object, and these two fields are the entire accepted field set.

ParameterTypeRequiredDescription
eventTypestringRequiredMust be paywall_shown
paywallSessionIdstringRequiredSession token from data.paywallSessionId on the Fetch Paywall response

Everything else about the event — Paywall, Placement, A/B test, AI Pricing Model, and the Profile itself — is derived server-side from the token.

Send an object, not an array

A JSON array is v1's shape, and v2 rejects it with 400 Request body must be a single event object, not an array.

Any field beyond the two above is rejected rather than ignored. Sending profileId or customerUserId returns a 400 naming the field: the signed token is the single source of identity, so a client value that disagrees with it is an error worth being told about instead of being silently overridden.

curl -X POST "https://api.botsi.com/v2/events" \
  -H "Authorization: $BOTSI_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "eventType": "paywall_shown",
    "paywallSessionId": "v1.eyJhIjo0MDIxLCJ3Ijo5MDUsInAiOiJvbmJvYXJkaW5nIiwiaSI6MTc4NTMxMjAwMH0.QmzR1w"
  }'

Working with the token#

Every Fetch Paywall response includes a unique paywallSessionId for the API response.

  • Size. Roughly 200 characters today, no fixed maximum. Use TEXT or VARCHAR(512).
  • One token per Paywall fetch.

Views expire after 24 hours. Transactions do not.

A paywall_shown event is accepted for 24 hours after the fetch that minted the token. Send it later and the request is rejected. Fetch a new Paywall before reporting the view.

Errors#

Every rejection is a 400 with code set to bad_request, and nothing is stored.

MessageCause
paywallSessionId is not a valid Botsi paywall session token.Malformed, truncated, or the signature does not verify
paywallSessionId was issued for a different app.The token belongs to another app's secret key
paywallSessionId uses an unsupported token version.A version prefix Botsi does not recognize
paywallSessionId has expired for this event type. Fetch a new paywall before reporting the view.A paywall_shown sent outside the 24-hour window
Request body must be a single event object, not an arrayThe body was sent as a JSON array
profileId is not accepted on v2 events; the profile is taken from the paywallSessionId that minted the paywallAn identity field was sent alongside the token

Response#

{ "ok": true }