View Categories

Subscriptions, memberships and queue endpoints

7 min read

The Subscriptions & Memberships add-on registers its endpoints under https://your-store.com/wp-json/wc-sisubscriptions/v1/. Authentication and conventions are the same as for the rental endpoints: a WooCommerce REST API key with Read/Write permissions, JSON bodies, X-WP-Total pagination headers and 409 for conflicts. See the REST API overview. For what subscriptions, memberships and queues are from the store owner’s side, see Setting up Subscriptions and Setting up Memberships.

Subscriptions #

Method and pathWhat it does
GET /subscriptionsList subscriptions. Filters: user_id, status, search, page, per_page.
POST /subscriptionsCreate one. Required: user_id, items (array of { product_id, quantity, recurring_amount }), billing_period (day, week, month, year). Optional: billing_interval (default 1), next_payment_date, parent_order_id, status (default active).
GET /subscriptions/{id}One subscription with its items, its pending scheduled renewals and the ids of memberships it pays for.
PUT /subscriptions/{id}Change billing_period, billing_interval, next_payment_date, parent_order_id, user_id, status or replace the items.
DELETE /subscriptions/{id}Remove the subscription, its items and its scheduled actions. Orders already created are kept.
POST /subscriptions/{id}/cancelCancel it. The parent order’s rental reservations are released and a note is added to the order.
POST /subscriptions/{id}/pausePause billing (status paused).
POST /subscriptions/{id}/resumeResume a paused subscription (only a paused one; anything else is a 409).
{
  "id": 57,
  "user_id": 2,
  "status": "active",
  "parent_order_id": 4402,
  "last_synced_order_id": 4519,
  "billing_period": "month",
  "billing_interval": 1,
  "next_payment_date": "2026-10-14 00:00:00",
  "last_payment_date": "2026-09-14 09:12:31",
  "date_created": "2026-06-14 09:12:31",
  "date_modified": "2026-09-14 09:12:31",
  "items": [
    { "id": 91, "subscription_id": 57, "product_id": 2101, "variation_id": 0, "quantity": 1, "recurring_amount": 89, "line_subtotal": 89, "billing_period": "month", "billing_interval": 1, "tax_class": "", "is_one_time": 0, "priced": 1 }
  ],
  "scheduled_actions": [
    { "action_id": 3310, "subscription_id": 57, "action_type": "renewal_order", "action_date": "2026-10-14 00:00:00", "status": "pending", "renewal_order_id": null, "completed_date": null, "notes": null, "created_date": "2026-09-14 09:12:31" }
  ],
  "memberships": [ 12 ]
}

Renewals are charged by the plugin’s daily cron using the payment method saved on the parent order, so a subscription created through the API with no parent_order_id has nothing to charge: it is useful for migrating records or for subscriptions billed outside WooCommerce, and its next_payment_date should then be managed by the caller. Setting status to cancelled or expired through PUT has the same side effects as the /cancel action.

Switching plans #

These two routes are for the store admin: they move one line of a subscription to another plan, the same change a customer makes from My Account. They are in Subscriptions & Memberships 1.1.0 and later. A plan is another variation of the line’s product, or a product listed in the product’s “Customers can switch to” field. Only subscription products that sell the subscription’s billing length are offered, never a rental. The subscription must be active and have a next_payment_date.

An upgrade applies at once and charges the prorated difference. A downgrade applies at the next renewal. With when you can force either one as an admin. Only one change waits at a time: a new switch replaces a scheduled one, and a change waiting for its payment blocks the next one for 7 days.

GET /subscriptions/{id}/switch-options #

Lists the plans the subscription can move to, each with its price preview, and the subscription’s switch log (newest first).

ParameterNotes
item_idInteger, default 0. The subscription line to switch (the id of an entry in items). Leave it out when the subscription has one line; with several lines and no item_id the first line is used.

The response has two keys. options is a list of previews, one per plan (empty when the product lists no other plan). log is the list of earlier switches: id, item_id, from_product_id, to_product_id, from_amount, to_amount, direction, apply_at, amount, credit_topup, order_id, status (scheduled, pending_payment, applying, done, failed or cancelled), actor, notify, note, created_at and applied_at. A preview has these fields:

FieldNotes
subscription_id, item_idThe subscription and the line.
from_product_id, from_variation_id, from_name, from_amountThe current plan and what it costs per cycle.
to_product_id, to_variation_id, target_id, name, to_amount, price_htmlThe new plan. target_id is the variation id, or the product id when the plan is not a variation. Send it as target_id to the switch route.
directionup, down or same, from the two amounts.
apply_atnow or next_renewal.
dueThe amount charged now, in the store currency. 0 for a change at the next renewal.
days_left, days_in_cycleWhat the proration is based on.
credit_topupStore credit added now when both plans are store credit memberships.
benefits, summary, notes, tax_classText for display (it can contain HTML entities such as $) and the new plan’s tax class.

POST /subscriptions/{id}/switch #

Switches one line to another plan, or previews the switch with dry_run.

ParameterNotes
target_idInteger, required. The target_id of one of the options.
item_idInteger, default 0. The line to switch, as for switch-options.
whenauto (default), now or next_renewal. auto applies an upgrade now and a downgrade at the next renewal. A plan with the same price counts as an upgrade, so it applies now.
chargeprorated (default), none or custom. Used only when the change applies now. prorated charges the difference for the days left in the cycle, none charges nothing, custom charges amount.
amountNumber. The amount to charge with charge set to custom, in the store currency.
notifyBoolean, default true. Send the customer the plan change email.
dry_runBoolean, default false. Return the preview (the same fields as a switch-options entry) and change nothing.

A real switch returns status, switch_id and message:

statusMeaning
doneThe plan changed. With a charge, the response also has order_id: the switch order was paid with the payment method saved on the parent order.
scheduledThe change waits for the next renewal.
pending_paymentThere is an amount to pay and it could not be charged by itself (no saved payment method, or a gateway that does not charge on its own). The response has order_id and pay_url. The plan changes when the order is paid; an unpaid change lapses after 7 days.
ErrorWhen
400 rest_missing_callback_paramtarget_id is missing.
404 sibooking_rest_not_foundNo subscription with that id.
409 sibooking_rest_sisub_switch_statusThe subscription is not active.
409 sibooking_rest_sisub_switch_no_dateThe subscription has no next_payment_date, so the change cannot be priced.
409 sibooking_rest_sisub_switch_pendingAn earlier change is still waiting for its payment.
409 sibooking_rest_sisub_switch_no_lineitem_id is not a line of this subscription, or the subscription has no items.
409 sibooking_rest_sisub_switch_targettarget_id is not one of the plans this line can switch to.
409 sibooking_rest_sisub_switch_busyThe subscription is being renewed or changed right now. Try again in a minute.
409 sibooking_rest_sisub_switch_declinedThe saved payment method was declined. The plan is unchanged and the switch order is marked failed.

Preview a switch first, then send it without dry_run:

curl -u "ck_your_key:cs_your_secret" \
  "https://example.com/wp-json/wc-sisubscriptions/v1/subscriptions/57/switch-options"

curl -X POST -u "ck_your_key:cs_your_secret" \
  -H "Content-Type: application/json" \
  -d '{"target_id": 2102, "when": "auto", "dry_run": true}' \
  "https://example.com/wp-json/wc-sisubscriptions/v1/subscriptions/57/switch"

curl -X POST -u "ck_your_key:cs_your_secret" \
  -H "Content-Type: application/json" \
  -d '{"target_id": 2102, "charge": "none", "notify": false}' \
  "https://example.com/wp-json/wc-sisubscriptions/v1/subscriptions/57/switch"

Memberships #

Method and pathWhat it does
GET /membershipsList memberships. Filters: user_id, status, page, per_page.
POST /membershipsCreate one. Required: user_id. Then either queue_items (how many rentals the member may have out at once: a rental queue membership) or storecredit_amount (a store credit membership). Optional: subscription_id that pays for it, status (active, paused, cancelled, expired).
GET /memberships/{id}One membership with the credit used so far, the number of rentals out and the linked subscription’s status and dates.
PUT /memberships/{id}Change any of the fields above.
DELETE /memberships/{id}Delete the membership.
{
  "id": 12,
  "user_id": 2,
  "subscription_id": 57,
  "type": "queue",
  "status": "active",
  "storecredit_amount": null,
  "credit_used": 0,
  "queue_items": 3,
  "rentals_out": 1,
  "date_created": "2026-06-14 09:12:31",
  "date_modified": "2026-09-14 09:12:31",
  "subscription_status": "active",
  "next_payment_date": "2026-10-14 00:00:00",
  "last_payment_date": "2026-09-14 09:12:31",
  "parent_order_id": 4402
}

Rental queue #

A rental queue is the list of products a queue member wants next, in priority order. Sending the item at the top checks it out against one of the member’s free slots; returning it frees the slot. These endpoints do exactly what the member’s “Manage Queue” page and the admin Rental queue screens (Send and Return tabs) do.

Method and pathWhat it does
GET /queue?user_id=2The member’s queue, top priority first.
POST /queueAdd a product: user_id, product_id. For a variable product also send variation_id and, for its “Any …” attributes, attributes (an object of attribute values). A product already queued is a 409.
PUT /queue/{id}Move an item: priority (1 = next). Send variation_id (and attributes) instead, or as well, to change a variable product’s option; one already queued is a 409. Send neither and it is a 400.
DELETE /queue/{id}Remove an item from the queue.
POST /queue/{id}/sendCheck the queued item out to the member (with serials on a serial-tracked product). Refused with 409 when the member has no free slot or no unit is available.
POST /queue-sent/{id}/returnTake a sent item back; {id} is the id from /queue/out.
GET /queue/out?user_id=2What the member currently has out, with the sent date and serials.

A queue checkout creates a rental reservation without a WooCommerce order, so it appears in the bookings endpoints with order_id 0 and counts against the product’s availability like any other booking.