Custom Store Events

Send Custom Store Events

Changed on

Reports subscription lifecycle events (purchases, renewals, cancellations, refunds, ...) from a custom store. Accepted events update the user's entitlements, are delivered to your webhooks and count toward revenue charts (sandbox events only when charts are filtered to the Sandbox environment).

Send 1-100 events per request. A malformed request is rejected as a whole with 400: an unknown field anywhere in the body (a misspelled event or price field included), an unknown event type, a timestamp that is not a real ISO 8601 instant with a timezone in years 2000-9999, app_user_id with surrounding whitespace, or a price amount that is not a decimal string.

Otherwise the response is 200 with one result per event, in request order: accepted, or rejected with an error code, a message and the offending field as param. A rejection is always a problem with that event (an unknown product, a timestamp more than 5 minutes ahead of our clock, a missing price, a currency we have no exchange rate for); correct it before resending.

A failure on our side never rejects single events: the whole request fails, with 503 custom_store_ingestion_failed (retryable: true; resend the same batch unchanged) or, for an internal error, 500. The request is answered within 20 seconds; on a timeout, resend too. Environments that do not record custom store events answer 503 custom_store_ingestion_unavailable (retryable: false).

event_id is the idempotency key: re-sending an event never applies it twice, so retrying a batch is always safe. Never re-send an event_id with a different body: it is accepted, but analytics may keep either body and can count it twice. Correct a mistake with a new event. Events may arrive out of order; occurred_at decides which change is newest.

Prices convert to USD at our current exchange rate when the event is received, so the USD value of a resent event can differ slightly from the first.

The first accepted production event sets the store's reporting_since (see the custom stores API) to the time that request was received: from then on, revenue for this store's products is counted from these events rather than from SDK purchase events. It never moves on its own afterwards.

Rate limited per custom store: a 429 carries Retry-After.

Requires custom_store_events:write scope.

post/v2/custom-stores/{custom_store_id}/events

Request

  • Base URL
    https://api.superwall.com
  • URL
    https://api.superwall.com/v2/custom-stores/{custom_store_id}/events
  • Auth
    • HTTP bearer
    • or API key in cookie accounts_superwall_token
    • or HTTP bearer

Path parameters

custom_store_idstring required

Request body

Example request

{
  "events": [
    {
      "type": "renewal",
      "product_id": "pro_monthly",
      "subscription_id": "sub_4f1c",
      "transaction_id": "inv_9a77"
    }
  ]
}

Response

Success

object'custom_store_event_batch' required
custom_store_idstring required
acceptednumber required

Number of accepted events

rejectednumber required

Number of rejected events

Example response

{
  "results": [
    {
      "error": {
        "param": "events[2].product_id"
      }
    }
  ]
}

Changes

    • warning

      added the new credentials_missing enum value to the / response property for the response status

    • warning

      added the new credentials_missing enum value to the / response property for the response status

    • warning

      added the new credentials_missing enum value to the / response property for the response status

    • warning

      added the new credentials_missing enum value to the / response property for the response status

    • warning

      added the new credentials_missing enum value to the / response property for the response status

    • info

      added subschema #1 subschema #2 subschema #3 subschema #4 subschema #5 to the response body anyOf list for the response status

    • info

      removed subschema #1 subschema #2 subschema #3 subschema #4 subschema #5 from the response body anyOf list for the response status

    • warning

      added the new expires_at_required enum value to the //// response property for the response status

    • warning

      added the new product_archived enum value to the //// response property for the response status