Skip to main content

Keep your members' Discord, Telegram, course or members' area access in step with their Subi membership

If your membership gives members something outside your Shopify store, such as a role in your Discord server, a Telegram group, a course or community platform, or a members' area on your own site, Subi can keep that access in step with the membership: access is given when a membership starts or resumes, and taken away when it is paused or canceled. This page explains how each setup works. If you would 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.

What every setup uses

  • Subi's webhooks tell your tool the moment a membership is created, resumed, paused or canceled, and when a renewal payment succeeds or fails. You register them in Subi under Settings > Webhooks. See How to set up and manage Webhooks in Subi.

  • A Subi API key, made under Settings > API keys. Webhooks name the member by their Shopify customer ID, so the setup asks the Subi API for the member's email. See the Subi API guide.

  • The API and webhooks are included in every current paid Subi plan and in almost every older one, the older Free and Essential plans included. The Free plan offered to new stores today does not include them.

When access is given and taken away

  • Give access on Subscription Created and Subscription Resumed.

  • Take it away on Subscription Paused and Subscription Canceled, unless the member still has another active membership.

  • A failed renewal payment does not pause or cancel a membership by itself. Subi keeps it active while it retries the charge, and what happens when the retries run out depends on your payment recovery settings. If you want access to stop as soon as a payment fails, also take it away on Subscription Billing Failed and give it back on Subscription Billing Succeeded, which Subi sends when a retry pays. You can allow a few days of grace before taking it away.

  • A membership that ends after its last payment, such as a prepaid membership or one with a set number of renewals, sends no webhook when it ends. Subi marks a membership with a set number of renewals as expired the moment its last payment succeeds, but that payment covers one more period, which ends on the contract's next_billing_date, so access should run until that date. Run the nightly check described under Your own app or members' area, or remove those members by hand once that date has passed.

  • If your store sells other subscriptions too, give access only when the subscription includes your membership product: a Subscription Created, Resumed, Paused or Canceled delivery carries its contract's lines in subscription_contract.lines, each with a product_id, so check those directly. Subscription Billing Failed and Subscription Billing Succeeded wrap the contract in the billing attempt: on those two the lines are in billing_attempt.subscription_contract.lines and the member in billing_attempt.subscription_contract.customer_id. For the member's other contracts, only GET subscription-contracts/{id}/ returns a contract's lines; the list of contracts does not, so read each one to see whether one of its lines is your membership product.

Discord

A small bot gives your members a role that opens the members' channels, and removes it when the membership stops. To know which Discord account belongs to which customer, each member opens a link once and logs in with Discord. If the verified email on their Discord account has an active membership in your store, the bot adds them to your server with the role, and from then on Subi's webhooks keep the role in step: the role is taken away when a membership is paused or canceled, and a membership that ends after its last payment loses the role through a nightly check once the period its last payment paid for has ended, or is removed by hand.

Members who joined your server earlier through a plain invite link get the same link once, for example in a pinned message. Anyone who never uses it keeps the access they have today until you decide. A member whose Discord email is not the email they bought with can be linked by hand.

The setup needs a Discord application with a bot that can manage roles and create invites, a small server to run it, and the six webhooks above registered in Subi. We have the bot written; tell us you want it and we set it up with you.

Telegram

A Telegram bot can create an invite link for one person and remove a member from a group, so the group can follow the membership:

  1. When a membership is created or resumed, the setup reads the member's email from the Subi API, creates an invite link for one person, and emails it to the member.

  2. When they join, the setup records which Telegram account used that link and then revokes the link, so it cannot be used again.

  3. When the membership is paused or canceled and the member has no other active membership, the setup removes them from the group without a permanent ban, so they can join again if they resume.

The bot must be an admin of the group, allowed to invite and to ban users. This runs in Make or Zapier, or as a small script.

We do not offer this for WhatsApp: we know of no way for a tool to add and remove members of an ordinary WhatsApp group. If your members are on WhatsApp, Telegram or Discord is the way to make their access follow the membership.

A course or community platform

Any platform whose Zapier app can both add a member and remove one works the same way. Mighty Networks is one: its Zapier app, on Mighty's Scale plan and up, has a Plan Action step that can invite a member to a plan or remove them from it. Webhooks by Zapier needs a paid Zapier plan. You make two Zaps, one that gives access and one that takes it away:

  1. Trigger: Webhooks by Zapier, Catch Raw Hook. Register its address in Subi for Subscription Created and Subscription Resumed in the first Zap, and for Subscription Paused and Subscription Canceled in the second.

  2. Code by Zapier: check the X-Subi-Hmac-Sha256 header against the raw body with the Signing secret on Settings > Webhooks (the signature is base64, not hex), and stop if it does not match. In the first Zap, this same step also reads subscription_contract.lines from the body and stops unless one of them is your membership product; the contract that was just created or resumed already carries its own lines on this webhook, so no extra call is needed here.

  3. Webhooks by Zapier, a GET to https://api.subi.co/public/v1.0/subscribers/{customer_id}/ with your key in the X-Api-Key header, for the member's email.

  4. In the second Zap only, a GET to https://api.subi.co/public/v1.0/subscription-contracts/?customer_id={customer_id}&status=ACTIVE, then a GET to https://api.subi.co/public/v1.0/subscription-contracts/{id}/ for each contract it lists, and stop if any of them has a line with your membership product. A count above 0 alone is not enough when your store sells other subscriptions.

  5. Mighty Networks: Plan Action, set to invite in the first Zap and to remove in the second, with that email and your plan.

For Skool, Kartra, Kajabi, Circle or another platform, check first that its Zapier or Make app has both an add step and a remove step. Where it can only add, members are removed by hand.

Your own app or members' area

For a developer, or an AI coding agent working for you, the members' area keeps its own active or inactive flag for each member, and Subi keeps it current:

  1. An https:// endpoint registered in Subi for Subscription Created, Resumed, Paused and Canceled. It checks the signature on the raw body, answers 200 within 10 seconds, and does the work after.

  2. Each delivery carries an X-Subi-Event-Id header. Subi sends a delivery again when it does not get a 2xx answer, so store the ids and skip one you have already seen.

  3. The member is keyed on subscription_contract.customer_id; their email comes from GET subscribers/{customer_id}/ the first time.

  4. Created or Resumed makes the member active only when the delivery's own subscription_contract.lines holds a line for your membership product. Paused or Canceled makes them inactive, unless the member still has another active contract with a line for your membership product: list GET subscription-contracts/?customer_id={customer_id}&status=ACTIVE, then read each one with GET subscription-contracts/{id}/, the only call that returns its lines.

  5. Once a night, page through GET subscription-contracts/?status=ACTIVE, read with GET subscription-contracts/{id}/ each contract whose lines you have not stored yet, and set inactive every member with no active contract holding your membership product. Before setting a member inactive, list GET subscription-contracts/?customer_id={customer_id}&status=EXPIRED, read each with GET subscription-contracts/{id}/, and keep the member active while one of them holds your membership product and its next_billing_date is still ahead: that is the period their last payment paid for. Ask for 100 at a time (limit=100), store each contract's lines from the first read, and stay under the API's limit of 60 requests a minute. This catches a prepaid membership that has ended and any event your server missed while it was down.

Before going live, test that a forged signature is refused, that the same event sent twice changes nothing, that a pause takes access away and a resume gives it back, and that a member with two memberships keeps access when one stops. If you build it with an AI coding agent, give it the points in Everything Subi connects to, under Build it with ChatGPT, Claude or Codex, before it writes any code.

Turning it off

Delete the webhooks under Settings > Webhooks, and remove the bot or turn off the Zaps. Access that was already given stays until you remove it by hand.

Did this answer your question?