Real-Time Event Notifications
Webhooks allow you to receive real-time notifications when subscription events occur in your Appstle account. Build reactive, event-driven integrations with automatic retries, signature verification, and detailed delivery logs.
Webhooks are HTTP POST requests sent to a URL you configure (your endpoint). When an event happens, Appstle sends a POST request with event data to your endpoint.
Powered by Svix — Enterprise-grade webhook infrastructure with:
- ✅ Automatic retries with exponential backoff
- ✅ Cryptographic signature verification
- ✅ Detailed delivery logs and monitoring
- ✅ Developer-friendly debugging tools
- Log in to your Appstle dashboard
- Navigate to Settings → Webhooks
- Add your webhook endpoint URL
- Select which events you want to receive
- Return a
2xxstatus code (e.g.,200 OK) - Process events asynchronously in background
- Return success immediately
- Timeouts trigger automatic retries
- Always verify webhook signatures
- Ensures requests are authentic
- Prevents unauthorized access
- See Signature Verification below
Appstle sends webhooks for the following subscription events:
| Event Type | Description | Payload Type |
|---|---|---|
subscription.created | New subscription created | Subscription Contract |
subscription.updated | Subscription details updated | Subscription Contract |
subscription.activated | Subscription activated | Subscription Contract |
subscription.paused | Subscription paused | Subscription Contract |
subscription.cancelled | Subscription cancelled | Subscription Contract |
subscription.next-order-date-changed | Next order date modified | Subscription Contract |
subscription.billing-interval-changed | Billing frequency changed | Subscription Contract |
subscription.billing-success | Payment processed successfully | Billing Attempt |
subscription.billing-failure | Payment failed | Billing Attempt |
subscription.billing-skipped | Billing cycle skipped | Billing Attempt |
subscription.upcoming-order-notification | Upcoming order reminder | Billing Attempt |
All webhooks follow this structure:
{
"type": "subscription.created",
"data": {
// Event-specific payload
}
}Events like subscription.created, subscription.updated, subscription.activated, subscription.paused, subscription.cancelled, subscription.next-order-date-changed, and subscription.billing-interval-changed contain:
{
"type": "subscription.created",
"data": {
"id": "gid://shopify/SubscriptionContract/12345",
"status": "ACTIVE",
"customer": {
"id": 6789,
"email": "customer@example.com",
"firstName": "John",
"lastName": "Doe"
},
"billingPolicy": {
"interval": "MONTH",
"intervalCount": 1
},
"deliveryPolicy": {
"interval": "MONTH",
"intervalCount": 1
},
"lines": [...],
// Additional contract details
}
}Events like subscription.billing-success, subscription.billing-failure, subscription.billing-skipped, and subscription.upcoming-order-notification contain:
{
"type": "subscription.billing-success",
"data": {
"id": 98765,
"contractId": "gid://shopify/SubscriptionContract/12345",
"status": "SUCCESS",
"billingDate": "2026-02-01",
"order": {
"id": "gid://shopify/Order/11111",
"name": "#1234",
"totalPrice": "49.99"
},
"attemptCount": 1,
// Additional billing details
}
}Every webhook request is signed by Svix. You must verify the signature to ensure the request is authentic and hasn't been tampered with.
Svix includes these headers in every webhook request:
svix-id: Unique message IDsvix-timestamp: Unix timestamp of when the message was sentsvix-signature: Cryptographic signature
const { Webhook } = require('svix');
const secret = 'whsec_your_webhook_signing_secret';
app.post('/webhooks/appstle', (req, res) => {
const payload = JSON.stringify(req.body);
const headers = {
'svix-id': req.headers['svix-id'],
'svix-timestamp': req.headers['svix-timestamp'],
'svix-signature': req.headers['svix-signature'],
};
const wh = new Webhook(secret);
let event;
try {
event = wh.verify(payload, headers);
} catch (err) {
return res.status(400).send('Webhook signature verification failed');
}
// Process the verified webhook
console.log('Event type:', event.type);
console.log('Event data:', event.data);
res.status(200).send('OK');
});Find your webhook signing secret in your Appstle dashboard under Settings → Webhooks.
Svix provides a testing tool to send sample webhooks to your endpoint:
- Go to your Appstle dashboard → Settings → Webhooks
- Click on your endpoint
- Use the "Send Example" feature to send test events
- Verify your endpoint receives and processes the webhook correctly
Use tools like ngrok or localtunnel to expose your local development server and test webhooks:
ngrok http 3000Then add your ngrok URL (e.g., https://abc123.ngrok.io/webhooks/appstle) as a webhook endpoint in your Appstle dashboard.
If your endpoint doesn't return a 2xx status code, Svix automatically retries the webhook delivery:
- Retry Schedule: Exponential backoff over 5 attempts across 3 days
- Manual Retry: You can manually retry failed webhooks from the Svix dashboard
- Endpoint Disabling: Endpoints are automatically disabled after sustained failures to prevent wasted resources
View delivery attempts and retry history in your Appstle dashboard under Settings → Webhooks → Message Logs.
| Issue | Solution |
|---|---|
| Signature verification fails | Ensure you're using the correct webhook signing secret from your dashboard. Don't modify the raw request body before verification. |
| Timeouts | Return 200 OK immediately and process events asynchronously. Avoid long-running operations in your webhook handler. |
| Wrong status codes | Always return 2xx for successful receipt (even if you encounter business logic errors). Use 4xx only for malformed requests. |
| CSRF protection blocking webhooks | Exempt your webhook endpoint from CSRF checks in your web framework. |
| Duplicate events | Webhooks can be delivered more than once. Use the svix-id header to make your processing idempotent. |
- Check the Message Logs in your Appstle dashboard to see delivery attempts and responses
- Log the raw webhook payload to understand the exact data structure
- Verify your endpoint is publicly accessible (not behind VPN/firewall)
- Test with a simple endpoint that just logs and returns
200 OK
Contact support@appstle.com with your endpoint URL and example svix-id for assistance.
Last updated: January 2026