Before you start
You'll need access to the API & Integrations section of your Skio Dashboard.
You'll need an endpoint (a URL you control) that can accept incoming POST requests. Skio doesn't host or provide this endpoint for you.
What are webhooks?
Webhooks let Skio automatically send subscription event data to an external system in real time, so you can trigger custom logic (like updating a CRM or logging events in your own database) without polling the Skio API.
How do I set up a webhook?
You can add a webhook URL and choose which subscription events get sent to it from the API Keys page.
Step 1: Navigate to API Keys
In the left-hand menu of your Skio Dashboard, go to API & Integrations > API Keys, then select the Webhooks tab.
Step 2: Add your webhook URL
Enter the URL you'd like Skio to send webhook events to.
Click Add webhook.
Once added, your webhook appears in the table along with a Token. Use this token to verify that incoming requests actually came from Skio (see Verifying webhook authenticity below).

The Webhooks tab under API & Integrations > API Keys.
Step 3: Choose which event types to send
Under Event Types, search for and select the events you want this webhook to receive.
Verifying webhook authenticity
Every webhook Skio sends includes a skioWebhookToken field. Compare this value against the token shown for that webhook on the API Keys page to confirm the request actually came from Skio and not a spoofed source.
Always check the
skioWebhookTokenon every webhook you receive. Skipping this check means your endpoint could act on requests that didn't actually come from Skio.
Webhook payload structure
Every webhook sends a payload with the following top-level structure:
{
"domain": string; // The domain of the shop.
"subscriptionId": string; // The Skio subscription ID that this event affects.
"eventType": string; // The type of event in this webhook (see below for a full list of event types).
"eventData": json; // A JSON blob containing details about the event (see below for a full specification).
"skioWebhookToken": string; // The webhook token from above.
}
Event types and payload schema
The eventType field tells you what happened, and the shape of eventData depends on which event fired. The full JSON schema for every event type is below.
Full JSON Schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AuditEventType": {
"enum": [
"Discount code applied",
"Subscription activated",
"Subscription cancelled",
"Subscription interval/date update",
"orderPlaced",
"productsUpdated"
],
"type": "string"
},
"SellingPlanInterval": {
"description": "Represents valid selling plan interval.",
"enum": [
"DAY",
"MONTH",
"WEEK",
"YEAR"
],
"type": "string"
},
"UserType": {
"enum": [
"DashboardUser",
"Skio",
"StorefrontUser"
],
"type": "string"
}
},
"properties": {
"domain": {
"type": "string"
},
"eventData": {
"anyOf": [
{
"properties": {
"shopifyOrderId": {
"type": "string"
},
"shopifyOrderName": {
"type": "string"
},
"subscriptionId": {
"type": "string"
},
"timestamp": {
"type": "string"
},
"userCognitoUsername": {
"type": [
"null",
"string"
]
},
"userEmail": {
"type": [
"null",
"string"
]
},
"userType": {
"$ref": "#/definitions/UserType"
}
},
"type": "object"
},
{
"properties": {
"subscriptionId": {
"type": "string"
},
"timestamp": {
"type": "string"
},
"userCognitoUsername": {
"type": [
"null",
"string"
]
},
"userEmail": {
"type": [
"null",
"string"
]
},
"userType": {
"$ref": "#/definitions/UserType"
}
},
"type": "object"
},
{
"properties": {
"subscriptionId": {
"type": "string"
},
"timestamp": {
"type": "string"
},
"userCognitoUsername": {
"type": [
"null",
"string"
]
},
"userEmail": {
"type": [
"null",
"string"
]
},
"userType": {
"$ref": "#/definitions/UserType"
}
},
"type": "object"
},
{
"properties": {
"newProducts": {
"items": {
"properties": {
"price": {
"type": "number"
},
"productTitle": {
"type": "string"
},
"productVariantId": {
"type": "string"
},
"productVariantTitle": {
"type": "string"
},
"quantity": {
"type": "number"
}
},
"type": "object"
},
"type": "array"
},
"oldProducts": {
"items": {
"properties": {
"price": {
"type": "number"
},
"productTitle": {
"type": "string"
},
"productVariantId": {
"type": "string"
},
"productVariantTitle": {
"type": "string"
},
"quantity": {
"type": "number"
}
},
"type": "object"
},
"type": "array"
},
"subscriptionId": {
"type": "string"
},
"timestamp": {
"type": "string"
},
"userCognitoUsername": {
"type": [
"null",
"string"
]
},
"userEmail": {
"type": [
"null",
"string"
]
},
"userType": {
"$ref": "#/definitions/UserType"
}
},
"type": "object"
},
{
"properties": {
"newIntervalAndDate": {
"properties": {
"billingDate": {
"type": "string"
},
"interval": {
"$ref": "#/definitions/SellingPlanInterval"
},
"intervalCount": {
"type": "number"
}
},
"type": "object"
},
"oldIntervalAndDate": {
"properties": {
"billingDate": {
"type": "string"
},
"interval": {
"$ref": "#/definitions/SellingPlanInterval"
},
"intervalCount": {
"type": "number"
}
},
"type": "object"
},
"skipped": {
"type": "boolean"
},
"subscriptionId": {
"type": "string"
},
"timestamp": {
"type": "string"
},
"userEmail": {
"type": [
"null",
"string"
]
},
"userType": {
"$ref": "#/definitions/UserType"
}
},
"type": "object"
},
{
"properties": {
"amount": {
"type": "number"
},
"codePlatformId": {
"type": "string"
},
"method": {
"enum": [
"FIXED_VALUE",
"PERCENTAGE"
],
"type": "string"
},
"redeemCode": {
"type": "string"
},
"subscriptionId": {
"type": "string"
},
"timestamp": {
"type": "string"
},
"type": {
"anyOf": [
{
"enum": [
"CANCEL_DISCOUNT",
"DISCOUNT_CODE",
"FREE_SHIPPING",
"GROUP_SUBSCRIPTION",
"MANUAL_DISCOUNT",
"PREPAID_DISCOUNT",
"VOLUME_DISCOUNT"
],
"type": "string"
},
{
"type": "null"
}
]
},
"userCognitoUsername": {
"type": [
"null",
"string"
]
},
"userEmail": {
"type": [
"null",
"string"
]
},
"userType": {
"$ref": "#/definitions/UserType"
}
},
"type": "object"
}
]
},
"eventType": {
"$ref": "#/definitions/AuditEventType"
},
"subscriptionId": {
"type": "string"
}
},
"type": "object"
}
FAQ
Can I limit a webhook to specific events?
Yes. Use the Event Types section on the Webhooks tab to search for and select only the events you want that webhook to receive.
How do I know a webhook actually came from Skio?
Check that the skioWebhookToken value in the payload matches the token shown for that webhook on the API Keys page. If it doesn't match, discard the request.
