Membership Contracts
Update membership contract status (pause/resume/activate)
Changes the status of a membership contract. This allows pausing, resuming, or activating memberships to control billing and delivery.
Key Features:
- Pause Memberships: Temporarily stop billing and deliveries
- Resume Memberships: Reactivate paused memberships
- Activate Memberships: Start inactive memberships
- Activity Logging: All status changes are logged for audit trail
- Customer Restrictions: Includes minimum cycle checks when called from customer portal
Status Values:
- ACTIVE: Membership is active and billing/delivering normally
- PAUSED: Membership is temporarily paused (no billing, no deliveries)
- CANCELLED: Membership is cancelled (use DELETE endpoint instead)
Pause vs. Cancel:
- Pause: Temporary hold, customer can resume anytime
- Cancel: Permanent termination, requires creating new membership to restart
Common Use Cases:
- Vacation Hold: Customer going on vacation, pause deliveries temporarily
- Financial Pause: Customer needs temporary break from payments
- Product Surplus: Customer has too much product, pause until they use it
- Seasonal Pause: Pause memberships during off-season (e.g., lawn care in winter)
- Resume After Pause: Customer ready to restart after temporary hold
- Reactivate Failed: Reactivate membership after payment method updated
Pause Behavior:
- Billing Paused: No charges while paused
- Deliveries Paused: No orders created while paused
- Next Billing Date: Preserved or recalculated on resume (merchant setting)
- Unlimited Duration: Pauses can be indefinite unless merchant sets limits
Resume Behavior:
- Immediate Reactivation: Membership becomes active immediately
- Next Billing Date: Calculated based on pause duration settings
- Deliveries Resume: Next delivery scheduled according to interval
Customer Portal Restrictions: When called from customer portal (vs. merchant API):
- Minimum Cycles: Cannot pause/cancel until minimum billing cycles met
- Freeze Period: Updates may be frozen until minimum requirements satisfied
- Retention Rules: Special retention discounts may be offered on cancellation
Important Notes:
- Customer Communication: Consider sending email notifications on status changes
- Billing Cycles Not Lost: Paused cycles don’t count toward minimums
- No Pro-rata: No refunds or credits when pausing mid-cycle
Authentication: Requires API key authentication via X-API-Key header or api_key parameter
PUT
/
api
/
external
/
v2
/
subscription-contracts-update-status
Update membership contract status (pause/resume/activate)
curl --request PUT \
--url https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-statusimport requests
url = "https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-status"
response = requests.put(url)
print(response.text)const options = {method: 'PUT'};
fetch('https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-status', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-status';
const options = {method: 'PUT'};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-status",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-status"
req, _ := http.NewRequest("PUT", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}require 'uri'
require 'net/http'
url = URI("https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-status")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
response = http.request(request)
puts response.read_body{
"detail": "Invalid subscription status",
"status": 400,
"title": "Bad Request"
}{
"detail": "Cannot pause subscription until minimum billing cycles completed",
"status": 403,
"title": "Forbidden"
}Headers
Query Parameters
Membership contract ID
New membership status
Available options:
ACTIVE, PAUSED API Key (Deprecated - Use Header X-API-Key instead)
Response
Membership status successfully updated (no content returned)
⌘I
Update membership contract status (pause/resume/activate)
curl --request PUT \
--url https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-statusimport requests
url = "https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-status"
response = requests.put(url)
print(response.text)const options = {method: 'PUT'};
fetch('https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-status', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-status';
const options = {method: 'PUT'};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-status",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-status"
req, _ := http.NewRequest("PUT", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}require 'uri'
require 'net/http'
url = URI("https://membership-admin.appstle.com/api/external/v2/subscription-contracts-update-status")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
response = http.request(request)
puts response.read_body{
"detail": "Invalid subscription status",
"status": 400,
"title": "Bad Request"
}{
"detail": "Cannot pause subscription until minimum billing cycles completed",
"status": 403,
"title": "Forbidden"
}