Creating subscriptions

Start a Shopify subscription for a customer with the Subscriptions REST API: find the product, list its priced plans, create, and wait until it's ready.

Last updated: 2026-11-09

Creating a subscription starts a Shopify subscription for a customer with a payment method they already have in Shopify. Nothing is charged when you create it; billing starts on the first billing date.

1

Find the product

GET /products?query= and pick a variant's product_selection.

2

List its plans

GET /subscription_plans with that product_selection. Each entry is a ready subscription_selection.

3

Create

POST /customers/{customer_id}/subscriptions with the selection, quantity and first billing date. Needs a key that can create subscriptions (subscriptions:create).

4

Wait until it's ready

Poll GET /subscription_creations/{id} until status is ready.

1. Find the product

Every word of the query must appear in the product's title, vendor, product type, product ID or a variant's name. Each match lists its selections, one per variant, each with a product_selection. When has_more is true, search with more specific words.

GET /products
curl -G "https://api.chargezen.com/v1/products" \
  --data-urlencode "query=morning coffee" \
  -H "X-Chargezen-Key-Id: $CHARGEZEN_KEY_ID" \
  -H "Authorization: Bearer $CHARGEZEN_SECRET"

# matches[0].selections[0].product_selection:
{ "product_record_id": "501", "provider": "shopify", "product_id": "gid://shopify/Product/8812",
  "variant_id": "gid://shopify/ProductVariant/44100", "product_card_id": null }

2. List its subscription plans

Send each field of the product_selection as a product_selection[…] query parameter. Leave product_card_id empty when it's null. The plans come from your Chargezen plans, priced for that variant: the first 10 plan groups with 10 plans each, with has_more when there are more. To pick one exact plan, add plan_ref[selling_plan_group_id] and plan_ref[selling_plan_id].

GET /subscription_plans
curl -G "https://api.chargezen.com/v1/subscription_plans" \
  --data-urlencode "product_selection[product_record_id]=501" \
  --data-urlencode "product_selection[provider]=shopify" \
  --data-urlencode "product_selection[product_id]=gid://shopify/Product/8812" \
  --data-urlencode "product_selection[variant_id]=gid://shopify/ProductVariant/44100" \
  --data-urlencode "product_selection[product_card_id]=" \
  -H "X-Chargezen-Key-Id: $CHARGEZEN_KEY_ID" \
  -H "Authorization: Bearer $CHARGEZEN_SECRET"

{
  "subscription_selections": [
    {
      "product_selection": { "product_record_id": "501", "provider": "shopify", "product_id": "gid://shopify/Product/8812", "variant_id": "gid://shopify/ProductVariant/44100", "product_card_id": null },
      "plan_ref": { "selling_plan_group_id": "gid://shopify/SellingPlanGroup/51", "selling_plan_id": "gid://shopify/SellingPlan/71" },
      "plan_name": "Monthly",
      "kind": "subscription",
      "group_name": "Subscribe & Save",
      "billing_interval": "MONTH",
      "billing_interval_count": 1,
      "delivery_interval": "MONTH",
      "delivery_interval_count": 1,
      "price_adjustment": { "type": "percentage", "value": "10" },
      "variant_price_amount": "20.00",
      "currency": "USD"
    }
  ],
  "has_more": false
}

3. Create the subscription

FieldWhat to send
subscription_selectionOne entry from subscription_plans, unchanged.
quantityWhole number per delivery, 1 or more.
first_billing_dateYYYY-MM-DD. Shopify may adjust the actual next billing date, which the answer returns.
discountOptional. { "value_type": "percentage", "value": 15 } (100 makes it free) or { "value_type": "fixed_amount", "value": 5 }, with an optional title.
shipping_addressOptional. first_name, last_name, address1, address2, city, province_code, country_code, zip, phone; address1, city and country_code are required. Leave it out to use the customer's default address.
POST /customers/{customer_id}/subscriptions
curl -X POST "https://api.chargezen.com/v1/customers/8f14e45f-ceea-467f-a0e6-0e1c2f4b9d3a/subscriptions" \
  -H "X-Chargezen-Key-Id: $CHARGEZEN_KEY_ID" \
  -H "Authorization: Bearer $CHARGEZEN_SECRET" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "subscription_selection": { …one entry from subscription_plans, unchanged… },
    "quantity": 1,
    "first_billing_date": "2026-12-01"
  }'

HTTP/1.1 201 Created
{
  "id": "3d6f0b7e-2c41-4a8e-9b1f-5e7d2a90c4b8",
  "status": "created",
  "subscription_contract_id": "gid://shopify/SubscriptionContract/30971998877",
  "requested_first_billing_date": "2026-12-01",
  "next_billing_date": "2026-12-01T00:00:00Z",
  "contract_status": "ACTIVE",
  "billing_interval": "MONTH",
  "billing_interval_count": 1,
  "unit_price": "18.0",
  "currency": "USD"
}

The price is the variant's price with the plan's adjustment, then your discount. No delivery charge is added. Retry with the same Idempotency-Key and the same body to get the same answer; changing the body under that key is refused with SUBSCRIPTION_CREATION_CONFLICT.

4. Wait until it's ready

GET /subscription_creations/{id}
curl "https://api.chargezen.com/v1/subscription_creations/3d6f0b7e-2c41-4a8e-9b1f-5e7d2a90c4b8" \
  -H "X-Chargezen-Key-Id: $CHARGEZEN_KEY_ID" \
  -H "Authorization: Bearer $CHARGEZEN_SECRET"

{
  "status": "ready",
  "subscription_contract_id": "gid://shopify/SubscriptionContract/30971998877",
  "subscription_ref": { "type": "customer_subscription_contract", "id": "48390" },
  "observed_at": "2026-11-09T16:22:40.118204Z"
}

status is pending until Chargezen has stored the new subscription, then ready with its subscription_ref. Use that id to read or change it.

When nothing is created

CodeWhat happened
SUBSCRIPTION_SELECTION_STALEThe plan or the price changed since you listed plans. List them again.
SUBSCRIPTION_PAYMENT_METHOD_REQUIREDThe customer has no payment method in Shopify. They need to add one through Shopify.

When Shopify refuses a creation, such as for a missing payment method, repeating it with the same Idempotency-Key returns the same answer. Once the cause is fixed, send a new request with a new key. Plans with a fixed price, a trial, a limited number of cycles, and bundle plans aren't listed; asking for one by plan_ref answers SUBSCRIPTION_PLAN_UNSUPPORTED.

Subscriptions billed by Recharge or Stripe

The API creates Chargezen and Shopify subscriptions only.

Was this page helpful?

Need more help? Contact support