To add a webhook as you read, open Webhooks in Subi.
Would you rather have it prepared for you? Tell us what you want to connect and we prepare it for your store on any paid Subi plan: a Zap, a Make scenario, a Google Sheet or the first lines of code for your developer.
Webhooks are a powerful way to integrate Subi with your external systems, such as custom CRMs, accounting software, email marketing platforms, or automation tools like Zapier.
Whenever a specific subscription event happens in your store, Subi will automatically send a real-time JSON payload to your destination URL.
In this article:
What your store needs
Webhooks are included in every current paid Subi plan and in almost every older one, the older Free and Essential plans included, so most stores do not need an add-on to use them. The Free plan offered to new stores today does not include them.
If your plan does not include webhooks, Settings > Webhooks shows a locked screen with an Upgrade your plan button, which lists the plans that include them. If your store is on an older plan and the page still shows a lock, click Upgrade your plan: it offers a current plan that includes it, or the API, webhook & MCP access add-on.
How to create a webhook
Each webhook covers one event type, so create one webhook for each event you want to track. Several webhooks can share the same URL.
To add a new webhook:
Open the Subi app in your Shopify Admin and go to Settings > Webhooks.
Make sure webhooks are turned on. The label next to the Webhooks page title reads Inactive until you click Activate in the top-right corner; it then reads Active and the button changes to Deactivate. While webhooks are inactive, no events are delivered.
In the Registered webhooks card, click Create webhook.
In the modal that appears, select your desired Event from the dropdown menu.
Enter your destination URL (Must be secure and start with
https://).Select the Webhook API version (We recommend always using the Latest version).
Click Save.
📘 Note: Your webhook is active as soon as you save it, provided webhooks are Active on the page (step 2 above).
Supported events
You can subscribe to the following subscription lifecycle events, named as they appear in the Event dropdown:
Subscription Created is sent when a customer starts a new subscription.
Subscription Canceled is sent when a subscription is canceled by the customer or the merchant.
Subscription Paused is sent when an active subscription is paused.
Subscription Resumed is sent when a paused subscription is resumed.
Subscription Billing Succeeded is sent when a renewal payment succeeds.
Subscription Billing Failed is sent when a renewal payment fails (e.g., insufficient funds, expired card).
The reactivation link on the Subscription Canceled event
Every Subscription Canceled payload includes a top-level winback_url field. It is a ready-made link that brings that exact subscription back, so you can drop it straight into your own win-back email or automation without building anything.
Use it when you run your own win-back campaigns from a tool like Klaviyo, Omnisend or a custom CRM, and you want the customer to restart in one click.
What to expect from the link:
It is on every Subscription Canceled payload. In the rare case the link could not be issued, the field is
nullrather than missing, so check for that in your integration before you use it.It opens the subscription at its current price, with no discount attached. Any offer you want to make is yours to add in your own email.
It stays valid for 30 days from the cancellation.
Each cancellation gets its own link. If the same subscription is canceled again later, the newer payload carries a new link and the older one stops working.
Once a customer uses it, it cannot be used a second time.
After 30 days, or once it has been used, the customer sees a short page telling them the link is no longer valid, with a way to log in to their subscriptions instead.
📘 Note: the link does not ask the customer to log in, so treat it like a password. Anyone who has it can restart that subscription and its recurring charges. Send it only to the customer whose subscription it belongs to, and avoid putting it anywhere public.
The card-update link on the Subscription Billing Failed event
Every Subscription Billing Failed payload includes a top-level card_update_url field. It is a ready-made link that takes the customer straight to the page where they update the card on that subscription, so you can drop it into your own payment-reminder email or automation without building anything.
Use it when you run your own failed-payment campaigns from a tool like Klaviyo, Omnisend or a custom CRM, and you want the customer to fix their card in one click.
What to expect from the link:
It is filled only when the customer pays with Shop Pay. For any other payment method the field is
nullrather than missing, because Shopify only offers a card-update page for Shop Pay — check for that in your integration before you use it.It is on the Subscription Billing Failed payload only. The Subscription Billing Succeeded payload never carries it.
It stays valid until the later of 24 hours and the end of the recovery window, and can be opened up to 10 times.
Each failed charge gets its own link.
Once it expires, the customer sees a short page telling them the link is no longer valid, with a way to log in to their subscriptions instead.
📘 Note: the link does not ask the customer to log in, so treat it like a password. Anyone who has it can update the card on that subscription. Send it only to the customer whose subscription it belongs to, and avoid putting it anywhere public.
Testing and managing webhooks
Once created, your webhooks will appear in the Registered webhooks list. To manage a webhook, click the ... icon on the right side of the webhook's row.
From this menu, you can:
Edit: Update the destination URL or change the API version.
Delete: Permanently remove the webhook.
To check that your server receives webhooks, use the Test webhook card: enter an Endpoint URL and click Send test. Subi queues a test event to that URL and confirms with Test webhook sent. Check the delivery logs for the result. The outcome appears in the Recent Deliveries & Logs card below once you reload the page. The Test webhook card is only shown while webhooks are Active. Always test your endpoint during setup to verify your server connection.
Troubleshooting using Logs
If your external system isn't receiving data, you can use Subi's built-in developer logs to find the issue.
Scroll down to the Recent Deliveries & Logs card. It lists every delivery attempt, newest first, with the event, a status badge, how long your server took to answer and the time.
A green badge such as 200 OK means your server accepted the delivery. Any status from 200 to 299 counts as accepted.
A red badge such as 404 Error or 500 Error shows the status code your server answered with.
A Pending badge means no status code was recorded: your server did not answer within 10 seconds, or it could not be reached. The badge stays that way; if Subi tries again, the new attempt gets its own line.
To look at one delivery:
Click View details next to it.
The Webhook Log Detail window shows the Request Payload Subi sent and the Response Status Code your server returned. The payload there is laid out for reading, so to check a signature use the raw body your server received, not a copy of this one.
Subi keeps the status code only, not the body your server sent back. To see why your server turned a delivery down, look in your server's own logs for that request. Every delivery carries an X-Subi-Webhook-Id header with the same number as the ID at the top of the Webhook Log Detail window, so you can search your server's logs for it.
What the most common failures mean:
If your server answers with a 301, 302 or any other 3xx code, the delivery fails, because Subi does not follow redirects. Use the final URL. If the endpoint sits behind a login or an access service such as Cloudflare Access, let requests to that path through without it.
If your own signature check answers with a 401 or 403, compare the signature as base64, not hex, and compute it over the raw request body before your code parses it. See Security and payload verification below.
A Pending badge means your endpoint did not answer in time or could not be reached. It has to answer within 10 seconds, so answer with a 200 first and do any slow work after that.
To test your endpoint: in the Test webhook card, enter your URL and click Send test. The message Test webhook sent means Subi has queued the test, not that your server accepted it. Wait about 10 seconds, then reload the page to see the result in Recent Deliveries & Logs. A test is sent once and is never retried, while a real event that fails is tried again.
Sending Subi webhooks to Zapier or Make
Subi has an app on Zapier, added with an invite link: see Connect Subi to Zapier. Zapier checks it for changes every 1 to 15 minutes, depending on your Zapier plan. Make has no Subi app. To get a change the moment it happens, or to use Make, send Subi's webhooks to either tool directly, as below.
In Zapier, start a Zap with the Webhooks by Zapier trigger and choose Catch Hook. Zapier gives you a URL to copy. Webhooks by Zapier needs a paid Zapier plan, so check that yours includes it. In Make, add the Custom webhook module from Make’s Webhooks app as the first step of a scenario and copy the address it creates.
Back in Subi, open Settings > Webhooks, create a webhook for the event you want and paste that URL as the destination. Each webhook covers one event, so add a webhook for each event you want to automate. Several webhooks can share the same URL.
Zapier and Make learn the shape of your data from the first request they receive. The Test webhook card sends only a short test message with a time, not a subscription, so build your steps on a real event instead. With webhooks Active, pause and then resume a subscription you use for testing, or wait for the next real event of that type, and then map its fields.
Subi’s webhooks name the customer by their Shopify customer ID (customer_id) and do not include their email address. If a later step needs the email, for example to update a contact in your CRM or email tool, look the customer up in Subi first: send a GET request to https://api.subi.co/public/v1.0/subscribers/<customer_id>/ with your API key in the X-Api-Key header, and the answer includes the customer’s email, first name and last name. In Make, use the HTTP app’s Make a request module; in Zapier, the Subi app’s Get Subscriber step does this lookup for you. See the Subi API guide to create a key.
Recipe: subscription changes as rows in Google Sheets
This keeps one row per subscription change in a Google Sheet, using Make.
In Google Sheets, create a sheet with a header row, for example: Date, Subscription ID, Customer ID, Status, Next billing date, Total, Currency.
In Make, create a scenario that starts with Webhooks > Custom webhook and copy the address.
In Subi, open Settings > Webhooks and create a webhook with that address for each of Subscription Created, Subscription Canceled, Subscription Paused and Subscription Resumed.
With webhooks Active, pause and then resume a subscription you use for testing, so Make receives a real payload.
Add the Google Sheets > Add a Row module and map the columns from
subscription_contract:updated_at,id,customer_id,status,next_billing_date,total_priceandcurrency_code. The status column shows what happened:ACTIVEfor a new or resumed subscription,PAUSEDorCANCELLED.Turn the scenario on.
Recipe: a Slack alert when a renewal payment fails
This posts a message in a Slack channel each time a subscription renewal fails, using Make.
In Make, create a scenario that starts with Webhooks > Custom webhook and copy the address.
In Subi, open Settings > Webhooks and create a webhook for Subscription Billing Failed with that address.
When the first failed renewal arrives, open the scenario and click Run once, so Make reads the fields of the payload.
Add the Slack > Create a Message module, pick your channel and write the text from the payload, for example: Renewal failed for subscription
billing_attempt.subscription_contract.id(customerbilling_attempt.subscription_contract.customer_id):billing_attempt.error_message.Turn the scenario on.
Subi retries a failed payment, so the same subscription can post more than one alert. If the channel gets busy, add a filter on error_code before the Slack step.
Security and payload verification
To ensure the data your server receives is genuinely from Subi and hasn't been tampered with, you must verify the webhook signature.
At the top of the Webhooks page, the Webhook Signing Secret card shows your secret key. Click the copy icon next to it (Copy secret) to copy it to your clipboard.
Subi uses this secret key to generate an HMAC-SHA256 hash of the JSON payload.
This hash is included in the headers of every webhook request under the key:
X-Subi-Hmac-Sha256.
For Developers: Configure your server to compute an HMAC-SHA256 hash of the raw request body using your Secret Key, and encode the result as base64, not hex. If it matches the value in the X-Subi-Hmac-Sha256 header, the request is verified and safe to process. A hex digest never matches, so every delivery would be rejected. Code samples are in the webhooks API reference.



