When a store moves its subscriptions to Subi, whatever it built on the old app's API has to point at ours: a members' area, a sheet, a helpdesk view, a loyalty or affiliate sync. This page puts the common calls and webhooks of Recharge, Skio and Loop beside Subi's, and says what to do where Subi has none. The other apps' names are as their own developer docs gave them on 20 October 2026; check their reference for the details.
The Subi API and webhooks come with the Starter, Subi and Subi Plus plans; the Free plan does not include them. The developers page has the first call, the limits and both references.
What changes in your code
- The key goes in an
X-Api-Keyheader, where Recharge usedX-Recharge-Access-Token, Skioauthorization: API <token>and LoopX-Loop-Token. Every Subi path starts athttps://api.subi.co/public/v1.0/and ends with a slash. - Subi is REST with an OpenAPI file. A Skio integration moves from GraphQL queries and mutations to plain calls.
- The limit is 60 requests a minute per key. Past that the API answers 429.
- Every webhook carries
X-Subi-Hmac-Sha256, the base64 HMAC-SHA256 of the raw body made with your shop's secret. Recharge also signs its webhooks; Skio puts a token in the payload; Loop's guide names no signature. A check that compares hex rejects every Subi delivery. - Answer a webhook with a 2xx within 10 seconds. Subi retries a failed delivery up to five times, the first after five minutes and each wait doubling, and does not follow redirects.
Calls
| What you do | Subi | Recharge | Skio | Loop |
|---|---|---|---|---|
| List subscriptions | GET subscription-contracts/, filtered by status, customer, dates and interval | GET /subscriptions | the Subscriptions query | see their reference |
| Read one subscription with its products | GET subscription-contracts/{id}/; the list leaves the lines out | GET /subscriptions/{id} | the Subscriptions query | see their reference |
| Find a customer | GET subscribers/?email= | GET /customers | the StorefrontUsers query | GET /customer |
| Cancel | POST subscription-contracts/{id}/cancel/ | POST /subscriptions/{id}/cancel | cancelSubscription | POST /subscription/{id}/cancel |
| Pause and resume | POST .../pause/, .../resume/ | see their reference | pauseSubscription, unpauseSubscription | POST /subscription/{id}/pause, /resume |
| Skip the next order | POST .../skip/ | POST /charges/{id}/skip | skipSubscription | POST /subscription/{id}/skipNext |
| Move the next billing date | POST .../reschedule/, on plans that allow editing the next billing date | POST /subscriptions/{id}/set_next_charge_date | updateNextBillingDate | POST /subscription/{id}/reschedule |
| Reactivate a cancelled subscription | POST .../resume/, the same call that resumes a paused one | POST /subscriptions/{id}/activate | reactivateSubscription | POST /subscription/{id}/reactivate |
| Swap, add, change or remove a product | PATCH .../lines/ with lines_to_swap, lines_to_update, lines_to_add or lines_to_remove | PUT /subscriptions/{id} to swap or change; see their reference to add or remove | swapSubscriptionProductVariants, addSubscriptionLine, updateSubscriptionLine | see their reference |
| Discount a subscription | PATCH .../lines/, a line's discount_percentage in lines_to_update | POST /charges/{id}/apply_discount | applyDiscountCode | see their reference |
Subi paths in the Subi column are under /public/v1.0/; ... stands for subscription-contracts/{id}. Loop's paths start with its API version, such as /2026-04.
Webhooks
| What you do | Subi | Recharge | Skio | Loop |
|---|---|---|---|---|
| A subscription starts | SUBSCRIPTION_CREATED | subscription/created | see their reference | subscription/created |
| A subscription is cancelled | SUBSCRIPTION_CANCELED, with the cancellation reasons | subscription/cancelled | Subscription cancelled | subscription/cancelled |
| Paused, then resumed | SUBSCRIPTION_PAUSED, SUBSCRIPTION_RESUMED | subscription/paused, subscription/activated | see their reference | subscription/paused, subscription/resumed |
| A renewal is paid | SUBSCRIPTION_BILLING_SUCCEEDED, with the renewal's Shopify order id | charge/paid, order/processed | orderPlaced | order/processed |
| A renewal payment fails | SUBSCRIPTION_BILLING_FAILED | charge/failed | see their reference | order/paymentFailed |
Where Subi has no call or webhook yet
- Creating a subscription (Recharge
POST /subscriptions, SkiocreateSubscription): a Subi subscription starts at Shopify's checkout with a Subi selling plan. To bring your existing subscribers over, our team imports them. - Changing the address or the frequency (Recharge
change_addressandPUT /subscriptions/{id}, SkioupdateSubscriptionShippingAddressandsubscriptionEditInterval, LoopPUT /address/{id}): no route in the public API. The subscriber changes the address in the Subi customer portal, and the frequency too on the Subi and Subi Plus plans once you turn it on under Customer permissions. You can change either in the Subi app. - Charges, orders and refunds (Recharge
/chargesand/orders, Skio'sOrdersquery): a Subi renewal is a Shopify order.SUBSCRIPTION_BILLING_SUCCEEDEDcarries its order id, and you read or refund the order through Shopify's own Admin API. - An upcoming renewal (Recharge
charge/upcoming, Looporder/upcoming): no webhook. Once a day, listGET subscription-contracts/?status=ACTIVE&next_billing_date__gte=<date>&next_billing_date__lte=<date>. - A skip, or a product or frequency change (Recharge
subscription/skippedandsubscription/updated, SkioproductsUpdated, Looporder/skippedandsubscription/updated): no webhook. ListGET subscription-contracts/?updated_at__gte=<time of your last run>and read each contract that changed. - A new payment method (Recharge
customer/payment_method_updated, LooppaymentMethod/updated): no webhook in Subi. Payment methods live in Shopify.
Moving a store and would rather not rebuild the integration yourself? Tell us what it connects to and, on any paid Subi plan, we prepare it for your store. Stuck on a call? Write to [email protected] with the request you sent and the answer you got, and leave the key out.