Skip to content
Last updated

🔔 Webhooks

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

🚀 Getting Started

1️⃣ Configure Your Endpoint

  • Log in to your Appstle dashboard
  • Navigate to SettingsWebhooks
  • Add your webhook endpoint URL
  • Select which events you want to receive

2️⃣ Respond Quickly

  • Return a 2xx status code (e.g., 200 OK)
  • Process events asynchronously in background
  • Return success immediately
  • Timeouts trigger automatic retries

3️⃣ Verify Signatures

  • Always verify webhook signatures
  • Ensures requests are authentic
  • Prevents unauthorized access
  • See Signature Verification below

📡 Event Types

Appstle sends webhooks for the following subscription events:

Event TypeDescriptionPayload Type
subscription.createdNew subscription createdSubscription Contract
subscription.updatedSubscription details updatedSubscription Contract
subscription.activatedSubscription activatedSubscription Contract
subscription.pausedSubscription pausedSubscription Contract
subscription.cancelledSubscription cancelledSubscription Contract
subscription.next-order-date-changedNext order date modifiedSubscription Contract
subscription.billing-interval-changedBilling frequency changedSubscription Contract
subscription.billing-successPayment processed successfullyBilling Attempt
subscription.billing-failurePayment failedBilling Attempt
subscription.billing-skippedBilling cycle skippedBilling Attempt
subscription.upcoming-order-notificationUpcoming order reminderBilling Attempt

Webhook Payload

All webhooks follow this structure:

{
  "type": "subscription.created",
  "data": {
    // Event-specific payload
  }
}

Subscription Contract Events

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
  }
}

Billing Attempt Events

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
  }
}

Signature Verification

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 ID
  • svix-timestamp: Unix timestamp of when the message was sent
  • svix-signature: Cryptographic signature

Verification Example (Node.js)

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');
});

Verification Examples in Other Languages

Find your webhook signing secret in your Appstle dashboard under SettingsWebhooks.

Testing Webhooks

Using Svix Play

Svix provides a testing tool to send sample webhooks to your endpoint:

  1. Go to your Appstle dashboard → SettingsWebhooks
  2. Click on your endpoint
  3. Use the "Send Example" feature to send test events
  4. Verify your endpoint receives and processes the webhook correctly

Local Development

Use tools like ngrok or localtunnel to expose your local development server and test webhooks:

ngrok http 3000

Then add your ngrok URL (e.g., https://abc123.ngrok.io/webhooks/appstle) as a webhook endpoint in your Appstle dashboard.

Retry Schedule

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 SettingsWebhooksMessage Logs.

Troubleshooting

Common Issues

IssueSolution
Signature verification failsEnsure you're using the correct webhook signing secret from your dashboard. Don't modify the raw request body before verification.
TimeoutsReturn 200 OK immediately and process events asynchronously. Avoid long-running operations in your webhook handler.
Wrong status codesAlways return 2xx for successful receipt (even if you encounter business logic errors). Use 4xx only for malformed requests.
CSRF protection blocking webhooksExempt your webhook endpoint from CSRF checks in your web framework.
Duplicate eventsWebhooks can be delivered more than once. Use the svix-id header to make your processing idempotent.

Debugging Tips

  • 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

Need Help?

Contact support@appstle.com with your endpoint URL and example svix-id for assistance.


Last updated: January 2026