Superwall · Schema

CustomStoreEvent

CompanyMonetizationMobileSDKPaymentsAnalytics

Properties

Name Type Description
event_id string
type string The lifecycle change. - `initial_purchase`: the first period of a subscription started (including a free trial). - `renewal`: a new paid period started. - `product_change`: the subscription moved to a
app_user_id string
product_id string The identifier of a product of this custom store, exactly as created (bare, without the SDK's `custom|` prefix). A new purchase (`initial_purchase`, `non_renewing_purchase`) needs an active product; e
subscription_id string Your stable id for the subscription, constant across renewals (the original transaction). For a `non_renewing_purchase`, the purchase id.
transaction_id string Your id for this period's transaction or invoice.
custom_transaction_id object
environment string `sandbox` for test purchases. Sandbox events are stored and appear in revenue charts only when they are filtered to the Sandbox environment; they never set the store's `reporting_since`.
occurred_at string
purchased_at string
expires_at object End of the current period. Must not be before `purchased_at`. `null` means the period never ends, so it is accepted only where it grants no open-ended access: on a lifetime `non_renewing_purchase`, an
period_type string `trial` for a free trial, `intro` for an introductory price, otherwise `normal`.
price object
cancel_reason object
is_trial_conversion object
View JSON Schema on GitHub

JSON Schema

superwall-custom-store-event-schema.json Raw ↑
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/superwall/json-schema/superwall-custom-store-event-schema.json",
  "title": "CustomStoreEvent",
  "x-generated": "2026-10-28",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/superwall-openapi.json#/components/schemas/CustomStoreEvent",
  "type": "object",
  "properties": {
    "event_id": {
      "type": "string"
    },
    "type": {
      "type": "string",
      "enum": [
        "initial_purchase",
        "renewal",
        "product_change",
        "cancellation",
        "uncancellation",
        "billing_issue",
        "expiration",
        "refund",
        "non_renewing_purchase"
      ],
      "description": "The lifecycle change.\n\n- `initial_purchase`: the first period of a subscription started (including a free trial).\n- `renewal`: a new paid period started.\n- `product_change`: the subscription moved to another product; `product_id` is the new product. It carries no price: report any charge for the new product as a `renewal`.\n- `cancellation`: auto-renew was turned off. Access continues until `expires_at`.\n- `uncancellation`: auto-renew was turned back on before expiry.\n- `billing_issue`: a renewal payment failed and is being retried. Access continues until `expires_at`.\n- `expiration`: the subscription ended. Access stops.\n- `refund`: the current period was refunded in full. Access stops immediately and the subscription ends: cancel it in your billing system too, so the customer is not billed again. A refunded `subscription_id` is final: no later event restores its access, so a customer who subscribes again needs a new `subscription_id`. Partial refunds are not supported: do not report them.\n- `non_renewing_purchase`: a one-time purchase; send `expires_at: null` for lifetime access."
    },
    "app_user_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255
    },
    "product_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255,
      "description": "The identifier of a product of this custom store, exactly as created (bare, without the SDK's `custom|` prefix). A new purchase (`initial_purchase`, `non_renewing_purchase`) needs an active product; every other event also accepts an archived one, so existing subscribers keep renewing, cancelling and expiring after you archive their product."
    },
    "subscription_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255,
      "description": "Your stable id for the subscription, constant across renewals (the original transaction). For a `non_renewing_purchase`, the purchase id."
    },
    "transaction_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255,
      "description": "Your id for this period's transaction or invoice."
    },
    "custom_transaction_id": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1,
          "maxLength": 255
        }
      ]
    },
    "environment": {
      "type": "string",
      "enum": [
        "production",
        "sandbox"
      ],
      "description": "`sandbox` for test purchases. Sandbox events are stored and appear in revenue charts only when they are filtered to the Sandbox environment; they never set the store's `reporting_since`."
    },
    "occurred_at": {
      "type": "string"
    },
    "purchased_at": {
      "type": "string"
    },
    "expires_at": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "End of the current period. Must not be before `purchased_at`. `null` means the period never ends, so it is accepted only where it grants no open-ended access: on a lifetime `non_renewing_purchase`, and on `expiration` and `refund`, which end access regardless. Every other type rejects `null` with `expires_at_required`."
    },
    "period_type": {
      "type": "string",
      "enum": [
        "normal",
        "trial",
        "intro"
      ],
      "description": "`trial` for a free trial, `intro` for an introductory price, otherwise `normal`."
    },
    "price": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "amount": {
              "type": "string"
            },
            "currency": {
              "type": "string"
            }
          },
          "required": [
            "amount",
            "currency"
          ],
          "additionalProperties": false,
          "description": "What the customer paid for this period. Required on revenue events (`initial_purchase`, `renewal`, `non_renewing_purchase`, `refund`) and rejected on the others. Send `0` for a free trial."
        }
      ]
    },
    "cancel_reason": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "unsubscribe",
            "billing_error",
            "developer_initiated",
            "price_increase",
            "customer_support",
            "unknown"
          ],
          "description": "Why the subscription was cancelled or refunded. Only on `cancellation`, `expiration` and `refund`."
        }
      ]
    },
    "is_trial_conversion": {
      "anyOf": [
        {
          "type": "boolean",
          "description": "`true` on the `renewal` that converts a free trial into a paid period."
        }
      ]
    }
  },
  "required": [
    "event_id",
    "type",
    "app_user_id",
    "product_id",
    "subscription_id",
    "transaction_id",
    "environment",
    "occurred_at",
    "purchased_at",
    "expires_at",
    "period_type"
  ],
  "additionalProperties": false
}

Work with this as data

Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for schemas

4 MCP tools reach this
  • find_json_schemasBrowse and filter every JSON Schema in the catalog.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/superwall-custom-store-event"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.