Skip to main content
This page lists every developer-facing change to the Memberships Admin API, the Storefront API and the Partner Framework, newest first. Each entry is dated the day the change reached production.
  • Additive changes (new endpoints, new response fields, new optional parameters, new values of an existing field) don’t break a client that ignores what it doesn’t know. Parse JSON leniently and don’t treat enum fields as closed lists.
  • Entries tagged Action required may need a code change in your integration. Each one says who is affected and what to do.
  • The API reference is generated from the live API, so it always shows the current contract. The Admin API base URL is https://membership-admin.appstle.com, and Storefront API paths start with /memberships/cp/api/.
Partner FrameworkAdmin APIBehavior change
Partner tokens, calls to partner endpoints

Partner tokens work on any plan again

Admin API calls made with a scoped partner token work whether or not the store’s plan includes API access. From August 19, 2026, they returned 401 with the detail You do not have permission to access the External API. Please contact the Appstle Membership Support team. on a plan without it. Keys a merchant creates under API Access still need a plan that includes API access.

Appstle authenticates its connect and verify calls to your app

Appstle’s calls to your /appstle/connect and /appstle/verify endpoints now carry the same headers as its calls to /appstle/approved and your disconnect endpoint: X-Partner-Timestamp and X-Partner-Signature in HMAC-SHA256 mode, and X-Partner-Secret in Partner Secret mode if you gave Appstle an outbound secret. Until now, the Nonce Handshake calls to these two endpoints carried no authentication header, and the Simple Token Exchange call to /appstle/connect carried none in Partner Secret mode.Who is affected: partners whose /appstle/connect or /appstle/verify endpoint accepts requests without checking that they come from Appstle.Action required: none. You can now check these headers on /appstle/connect and /appstle/verify as well.Reference: Authentication: Partner integrations, Partner integration.
Admin APIStorefront APIBehavior changeNew fieldsAction required
Plans, billing intervals, selling plan products

Plans report whether they’re excluded from upgrades and downgrades

  • GET /api/external/v2/subscription-groups and GET /api/external/v2/subscription-groups/{subscriptionGroupId} return excludedFromUpgradeDowngrade (boolean) on each entry in subscriptionPlans.
  • GET /api/external/v2/subscription-contract-details/billing-interval returns excludedFromUpgradeDowngrade (boolean).
  • GET /memberships/cp/api/subscription-groups/all-selling-plans returns excludedFromUpgradeDowngrade (boolean) on each plan.
  • GET /memberships/cp/api/data/selling-plan-products accepts an optional sellingPlanIds query parameter (string). For a signed-in customer, the list now leaves out plans the merchant excluded from upgrades and downgrades. A plan stays in the list when its ID is in sellingPlanIds, so pass the IDs of the plans the member is on (separated by | or ,) and the member still sees their own plan.
Reference: Get a membership plan group, List all membership plan groups, Get all selling plans, List products attached to selling plans.

Customers can’t switch into an excluded plan

PUT /memberships/cp/api/subscription-contract-update-variant returns 400 with the title UserGeneratedError:This membership plan isn't available for upgrade or downgrade when a signed-in customer switches to a variant that belongs only to plans the merchant excluded from upgrades and downgrades. A variant in a plan the membership is already on still works. The Admin API call PUT /api/external/v2/subscription-contract-update-variant doesn’t check the exclusion.Who is affected: storefronts that offer every variant of a membership product as an upgrade or downgrade choice.Action required: build the choices from GET /memberships/cp/api/data/selling-plan-products, as above, and handle 400 on the switch by showing the title.Reference: Update line item variant.
Admin APIStorefront APIBehavior changeAction required
Reactivating a cancelled membership

Reactivating a cancelled membership can retry a billing attempt that ran out of retries

This applies when PUT /api/external/v2/subscription-contracts-update-status or PUT /memberships/cp/api/subscription-contracts-update-status sets a cancelled membership to ACTIVE, the membership’s last billing attempt failed for a cycle that’s already due after using up the retries set under the store’s Failed Payment Recovery settings, and the membership has no upcoming order to copy. Appstle now retries the failed billing attempt once. If that charge fails, Appstle takes the action the store chose under Once the membership reaches the maximum number of failures, such as cancelling the membership again. Until now, nothing was charged in this case. A store without Failed Payment Recovery settings still charges nothing.Who is affected: integrations and storefront code that set a cancelled membership to ACTIVE.Action required: treat setting a cancelled membership to ACTIVE as a charge. Do it only when the customer has agreed to pay for the cycle they missed.Reference: Update membership contract status (pause/resume/activate), Update membership contract status.
Admin APIStorefront APIBehavior changeAction required
Reactivating a cancelled membership

Reactivating a cancelled membership retries its failed billing attempt

When PUT /api/external/v2/subscription-contracts-update-status or PUT /memberships/cp/api/subscription-contracts-update-status sets a cancelled membership to ACTIVE and the membership’s last billing attempt failed, Appstle tries to charge the customer for the unpaid cycle. Until now, it billed a copy of the membership’s next upcoming order right away. Cancelling deletes the upcoming orders, so often nothing was charged.Now, when the failed billing attempt is for a cycle that’s already due and hasn’t used up the retries set under the store’s Failed Payment Recovery settings, Appstle retries that billing attempt itself and turns its retries back on. If this charge fails too, the store’s Failed Payment Recovery settings decide what happens next, as for any failed renewal. The membership’s activity log shows a Retry Enabled entry. In every other case, Appstle still bills a copy of the next upcoming order, or nothing if there is none.Who is affected: integrations and storefront code that set a cancelled membership to ACTIVE.Action required: treat setting a cancelled membership to ACTIVE as a charge. Do it only when the customer has agreed to pay for the cycle they missed.Reference: Update membership contract status (pause/resume/activate), Update membership contract status.
Admin APIBehavior changeAction required
API keys

Merchants can revoke the legacy API key

Under API Access in the Appstle admin, the Legacy API Key now has a Revoke button. After a merchant revokes it, every request that sends that key returns 401 with Content-Type: application/problem+json and the detail Invalid API key., the same response as any other unknown legacy key (see Authentication errors). Revoking can’t be undone, and Appstle doesn’t issue a replacement legacy key. Keys that start with apst_ aren’t affected.Who is affected: integrations that still send the key shown on the Legacy API Key card.Action required: create an apst_ key under API Access and move your integration to it before the merchant revokes the legacy key.
Admin APIStorefront APIPartner FrameworkBehavior changeAction required
Error responses

Error responses use appstle.com problem types and hide internal messages

The application/problem+json error responses changed in two ways:
  • The type of an error now starts with https://appstle.com/problem/, for example https://appstle.com/problem/problem-with-message. Before, it started with a different base URL.
  • detail no longer carries internal error text. A server error (5xx) has the detail An unexpected error occurred. Please try again later. A 400 for a path or query parameter of the wrong type, such as a contract ID that isn’t a number, has the detail Unexpected runtime exception. A 400 for a request body that isn’t valid JSON has the detail Unable to convert http message.
Who is affected: clients that match on the type URL, or on the text of detail in these errors.Action required: stop matching on type. Branch on status, and on errorKey or title where the body has them. Treat detail in these errors as a generic message.
Storefront APIBehavior changeAction required
Pickup locations, product data

Pickup locations are no longer available to customers

GET /memberships/cp/api/delivery-profiles/get-locations returns 403 with the detail Access is denied for a signed-in customer. Only the merchant’s admin session can call it. Until now, a signed-in customer could.Who is affected: storefront code that loads the store’s pickup locations for customers.Action required: stop calling it from the storefront.

Product data for customers covers only products on the Online Store

For a signed-in customer, the Storefront API product calls now cover only products that are active and published to the Online Store sales channel:
  • GET /memberships/cp/api/data/products and GET /memberships/cp/api/data/selling-plan-products leave other products out of products and productHandleData.
  • GET /memberships/cp/api/data/product and GET /memberships/cp/api/data/product-selling-plan-variant return 200 with an empty body for any other product.
  • GET /memberships/cp/api/data/variant-contextual-pricing returns 400 with the title UserGeneratedError:Product is not available for a variant of any other product.
  • POST /memberships/cp/api/product-swaps-by-variant-groups returns the same 400 when a variant in the request or in its swap options belongs to any other product.
Who is affected: storefronts that show members draft or archived products, or products published only to other sales channels, such as a headless storefront’s own channel.Action required: publish the products members should see to the Online Store sales channel. Handle 400 on the pricing and swap calls by showing the title.Reference: Get product details by ID, Get product with selling plans and variants, Search membership-enabled products with pagination, List products attached to selling plans, Get contextual pricing for a variant by currency, Get product swap options by variant.
Storefront APIBehavior changeAction required
Request parameters and bodies

Storefront requests can’t name another customer or store

A Storefront API request that names a customerId other than the signed-in customer’s returns 403 with the detail Customer does not match the authenticated session. This covers customerId and customer_id in the path (for example GET /memberships/cp/api/subscription-contract-details/shopify/customer/{customerId}/payment-methods), in the query string and in the request body. A request body whose shop names another store returns 403 with the detail Shop does not match the authenticated session.Who is affected: storefront code that sends a customerId or shop that isn’t the signed-in customer’s and the store’s own, for example PUT /memberships/cp/api/subscription-contract-details.Action required: leave customerId and shop out of Storefront API request bodies, or send the signed-in customer’s and the store’s own values. The session already identifies both.Reference: Get customer payment methods, Update membership contract details.
Partner FrameworkBehavior changeAction required
Partner authentication

One error for every failed partner authentication

connect, initiate-connect, verify, disconnect and status under /api/partner/{partnerId}/ now return the same error for every authentication failure: 400 with the errorKey TOKEN_INVALID and the title UserGeneratedError:Invalid partner credentials. That covers a Partner ID that is wrong or belongs to a deactivated partner, a wrong X-Partner-Secret (or a missing one on connect, initiate-connect and disconnect), and an invalid HMAC signature or a timestamp more than 5 minutes off. Until now, an unknown or deactivated Partner ID returned PARTNER_NOT_FOUND, and each authentication failure had its own title, such as UserGeneratedError:Invalid partner secret.Who is affected: partners whose code branches on PARTNER_NOT_FOUND, or on the title of a TOKEN_INVALID error.Action required: stop handling PARTNER_NOT_FOUND and the old titles. On TOKEN_INVALID with the title UserGeneratedError:Invalid partner credentials., check the Partner ID first, then the secret or HMAC key.Reference: Partner integration.
Admin APIStorefront APIBehavior changeNew fieldsAction required
Contract revisions, shop parameter

Admin API calls can’t name another store

An Admin API call whose shop, shopName, shopDomain or shop_domain parameter names a store other than the API key’s store returns 403 with the detail Shop does not match the authenticated session. The API key already identifies the store.Who is affected: integrations that send a shop parameter to the Admin API.Action required: leave shop out of Admin API calls, or send the store domain of the key’s own store.

Contract responses return revisionId

Membership contract responses return revisionId (string), the contract’s revision number in Shopify. It appears on the contract reads, for example GET /api/external/v2/subscription-contracts/contract-external/{contractId}, and on the contract-changing calls such as PUT /api/external/v2/subscription-contract-add-line-item and PUT /api/external/v2/subscription-contract-update-variant. The Storefront API contract reads and PUT /memberships/cp/api/subscription-contracts-apply-discount return it too.
Storefront APIBreaking changeAction required
Add line item, contract details, billing attempts

Storefront calls can change less of a membership

  • The Storefront API no longer serves PUT /memberships/cp/api/subscription-contracts-add-line-item. Use PUT /memberships/cp/api/v2/subscription-contracts-add-line-item, which takes contractId, shop, quantity and variantId. It doesn’t take price.
  • PUT /memberships/cp/api/subscription-contract-details saves only orderNote and phone. It ignores every other field in the request body and keeps the stored value.
  • PUT /memberships/cp/api/subscription-billing-attempts changes only billingDate and orderNote, and only on a billing attempt whose status is QUEUED. Otherwise it returns 400 with the title Invalid billing attempt status. It returns 400 with the title Invalid contract when contractId isn’t the billing attempt’s contract, and Invalid id when the billing attempt doesn’t exist.
Who is affected: storefront code that calls the first add-line-item path or sends price, or that changes contract details or billing attempts beyond the order note, phone and billing date.Action required: call the v2 add-line-item path without price. From the storefront, send both orderNote and phone to update contract details, and both billingDate and orderNote to update a queued billing attempt. Each call overwrites both fields with what you send. Handle 400 on the billing attempt call and show the title.Reference: Add line item to contract, Update membership contract details, Update billing attempt.
Admin APIAction required
Bundle endpoints

Three subscription bundle endpoints are no longer in the Admin API reference

The Memberships Admin API reference no longer lists these three bundle endpoints, which aren’t part of the Memberships API:
  • GET /api/external/v2/subscription-bundle-settings/{id}
  • GET /api/external/v2/subscription-bundlings/external/get-bundle/{handle}
  • PUT /api/external/v2/subscription-bundlings/discount/{token}
A call to subscription-bundle-settings/{id} still answered on November 1, 2026. But none of the three is documented any more, so don’t build on them.Who is affected: integrations that call these three endpoints.Action required: stop calling them.
Admin APIStorefront APINew fields
Contract details

Contract details return nextActivationDate and pauseDurationCycle

  • GET /api/external/v2/subscription-contract-details and GET /api/external/v2/subscription-customers-detail/valid/{customerId} return nextActivationDate (date-time) and pauseDurationCycle (integer, the number of billing cycles to pause when the pause option is selected).
  • GET /memberships/cp/api/subscription-contract-details/customer/{contractId}, GET /memberships/cp/api/subscription-customers-detail/valid/{id} and PUT /memberships/cp/api/subscription-contract-details return both fields.
Reference: Get membership contract list, Get detailed customer membership information, Get customer membership details, Update membership contract details.
Admin APIPartner FrameworkBehavior changeBreaking changeAction required
Authentication errors, API access on the plan

Failed Admin API authentication returns a 401 that says why

A request to an /api/external/ path with a missing, unknown or revoked API key now returns 401 with Content-Type: application/problem+json. The body has title, status, detail, path and message, and detail names the failed check, for example API key can not be blank. Before, these requests got the generic message Full authentication is required to access this resource.Who is affected: clients that match on the old generic message.Action required: none for most clients. Read detail to tell a bad key from a plan without API access, and log it.

The Admin API needs a plan that includes API access

Admin API calls now work only when the store’s Appstle plan includes API access. On a plan without it, every call returns 401 with the detail You do not have permission to access the External API. Please contact the Appstle Membership Support team., whichever key it sends. Until now, calls worked whatever the plan. Appstle checks the plan before it checks whether an apst_ key is revoked, so a store without API access gets this message even when its key has been revoked. Scoped partner tokens got this 401 too, until November 1, 2026.Who is affected: integrations on stores whose plan doesn’t include API access.Action required: when a call returns this detail, ask the merchant to add API access to their plan: in the upgrade notice on the API Access page, they click Chat with us.Reference: Authentication errors.
Admin APIStorefront APIBreaking changeAction required
Billing date

Changing the billing date of a membership with a pending upgrade or downgrade needs confirmation

PUT /api/external/v2/subscription-contracts-update-billing-date and PUT /memberships/cp/api/subscription-contracts-update-billing-date accept an optional cancelPendingScheduledChange (boolean) query parameter.If the membership has a scheduled upgrade or downgrade, a call without cancelPendingScheduledChange=true returns 400, and the billing date and the scheduled change stay as they are. The title names the change and its date, for example UserGeneratedError:A membership downgrade is scheduled for …. With true, the scheduled change is cancelled and the billing date changes.Who is affected: integrations that change billing dates on memberships with a scheduled upgrade or downgrade.Action required: handle 400 on this call. Show the title to the person making the change, and send cancelPendingScheduledChange=true only after they confirm that the scheduled change can be cancelled.Reference: Update membership contract billing date, Update next billing date.