Article · Developers
How can a subscription box brand pause, resume or skip a subscriber's box from its own helpdesk or ERP?
A subscription box brand with its own helpdesk or ERP (the system that runs orders and stock) can call Supr's REST API (a web address your software sends requests to) to change a subscriber from there. Five calls cover it: POST /subscriptions/:id/pause, /resume, /skip, /reschedule and /plan, all under https://subscriptions.super-simple.co/api/v1, each with a bearer token and an Idempotency-Key header so a retry never does the same change twice.
Who this is for: For subscription box brands with a developer or an ERP who want their own tools to pause, resume or skip a subscriber's box.
Before you start
- Open Settings > Integrations > API and find the API tokens card.
- Give the token a Name after the system that will use it, tick Change subscriptions (plus Read subscriptions if it also looks subscriptions up), and click Create token.
- Copy the token straight away. It is shown once and we do not store it, so a lost token means revoking it and making a new one.
The API is switched on store by store while it is new. If Settings > Integrations > API in the app tells you to contact support, message us in the app's live chat and we will turn it on.
A token is the password your software sends with every request. It belongs to one store and cannot see another store's subscriptions.
Call the API from your own server only. Never put a token in a browser, a theme or a mobile app, because anyone who finds it can change your subscriptions. In the examples below the token is read from an environment variable called SUPR_TOKEN.
Find the subscription first
Every call needs the subscription's id. Your helpdesk usually has the customer's email, and the list call takes it as a filter. Run:
curl "https://subscriptions.super-simple.co/api/v1/subscriptions?customer_email=customer@example.com" -H "Authorization: Bearer $SUPR_TOKEN"
Nobody with that address returns an empty list, not an error. The id in the answer is a number written as a string, such as 1000001, and the same call without a filter lists subscriptions with status ACTIVE, PAUSED, CANCELLED, EXPIRED or FAILED.
What an idempotency key is, in one sentence
If a request times out you cannot know whether it happened, and a second try could pause twice or skip twice. An idempotency key is a unique string you invent for the change; send the same one on the retry and we return the first answer instead of doing the work again. Use a fresh UUID per change, up to 255 characters.
| Situation | Answer |
|---|---|
| First use of the key | The change runs |
| Same key, same request | The stored response, with the header X-SSS-Idempotent-Replayed: true |
| Same key, a different request | 422. We refuse rather than let you believe the second change happened |
| Same key, first still running | 409. Retry shortly |
Keys are per token and last 24 hours. An answer in the 5xx range is not remembered, so retrying after our error runs the change for real.
The five calls
All five need the subscriptions:write scope, which is the Change subscriptions tick, and all answer with the subscription as it now stands, so you never need a read straight after a write.
1. Pause. Stops billing: no orders are created until it is resumed. The optional reason is kept in the subscription's timeline. Run:
curl -X POST "https://subscriptions.super-simple.co/api/v1/subscriptions/1000001/pause" -H "Authorization: Bearer $SUPR_TOKEN" -H "Content-Type: application/json" -H "Idempotency-Key: 9f1c2a7e-4b0d-4f2a-9c3e-8a1b2c3d4e5f" -d '{"reason":"Customer is travelling"}'
2. Resume. Never charges at once. Without a date, a billing date that has already passed moves to the next cycle and any other date is kept. With next_billing_date (ISO 8601, in the future) you choose when the next box is created. Run:
curl -X POST "https://subscriptions.super-simple.co/api/v1/subscriptions/1000001/resume" -H "Authorization: Bearer $SUPR_TOKEN" -H "Content-Type: application/json" -H "Idempotency-Key: 3b7e1d52-6c0a-4a8e-b1f4-5d2c9e7a1f08" -d '{"next_billing_date":"2026-12-01T09:00:00Z"}'
3. Skip. Skips the next box and takes no body. Skipping a box that is already skipped returns 409 conflict. The matching unskip call brings it back. Run:
curl -X POST "https://subscriptions.super-simple.co/api/v1/subscriptions/1000001/skip" -H "Authorization: Bearer $SUPR_TOKEN" -H "Idempotency-Key: 7a2d9c14-0e5b-4f63-8a1d-2b9e4c6f0d37"
4. Reschedule. Moves the next box to another date and time. next_billing_date is required. Run:
curl -X POST "https://subscriptions.super-simple.co/api/v1/subscriptions/1000001/reschedule" -H "Authorization: Bearer $SUPR_TOKEN" -H "Content-Type: application/json" -H "Idempotency-Key: c41f8e60-2a9d-4b17-9e35-7d0a1b6c8f22" -d '{"next_billing_date":"2026-11-15T09:00:00Z"}'
5. Change plan (the delivery frequency, which Shopify calls a selling plan). selling_plan_id is required. The current one is on lines[].selling_plan_id of the subscription. A plan the merchant has switched off for the API is refused with 400, and so is a plan whose bulk minimum the current quantities do not meet. Run:
curl -X POST "https://subscriptions.super-simple.co/api/v1/subscriptions/1000001/plan" -H "Authorization: Bearer $SUPR_TOKEN" -H "Content-Type: application/json" -H "Idempotency-Key: e5d03a98-71b4-4c2f-a6e0-9f1b3d8c4a57" -d '{"selling_plan_id":"7000008"}'
The 1000001, 7000008 and the keys above are placeholders. Take the real subscription id from the list call, and the id of the plan you want from a subscription that is already on it.
What can come back
Every error has the same shape, with a code to switch on and a message for people. Every response carries X-Request-Id: quote it to support and we can find that exact call.
- 400 invalid_request: a body, id or filter is missing or malformed. The message says which, for example a date that is not in the future.
- 401 unauthorized: the token is missing, wrong, revoked or expired.
- 403 forbidden: the token lacks the scope, or the API is not on for this store.
- 404 not_found: no such subscription. An id from another store looks exactly the same.
- 409 conflict: a state the request cannot have, such as skipping a box already skipped.
- 429 rate_limited: slow down. The Retry-After header says how many seconds to wait. Each token has a short burst allowance and a daily one.
Where this fits
Use the API for changes your own systems make regularly. For one-off bulk changes, such as moving many renewal dates, the Reschedule bulk action in the Subscriptions list needs no code. To get a message when a subscriber changes something themselves, read Subscription webhooks done safely. To keep subscribers from leaving in the first place, see How to build a cancellation flow for a subscription box.
Questions
Do I need a developer?
Yes, or a tool that can send web requests. If you only need a one-off change for many subscribers, use the bulk actions in the Subscriptions list instead.
Can I use it from a browser?
No. No CORS headers are sent, on purpose, and a token must never reach a browser. Call it from your server.
Is there a test environment?
Use a development store. The API works the same there and never touches your live store.
Can I cancel a subscription with it too?
Yes, POST /subscriptions/:id/cancel takes an optional reason. It cannot be undone through the API.
Every setting is covered in the help center: Using the API.
Install on ShopifyRelated
- How do I sell a monthly or weekly subscription box on Shopify?
- How do I stop subscribers cancelling on Shopify?
- Should a coffee roaster let subscribers skip, pause or cancel, and in what order?
- How does a subscription box brand receive subscription webhooks safely?
- How does a snack shop let customers pick 6 from 20 flavours without selling a flavour it has run out of?
- What should a coffee roaster charge on repeat orders of a subscribed bundle?
- How do I run a monthly art supplies club on Shopify?