Membership Contracts
Cancel membership contract
Cancels a membership contract and sends cancellation confirmation emails. This endpoint terminates the recurring membership and processes all cancellation workflows.
Cancellation Process:
- Contract Termination: Marks membership as cancelled in Shopify
- Billing Stop: Prevents future billing attempts
- Email Notification: Sends cancellation confirmation to customer
- Activity Logging: Records cancellation event with source and feedback
- Feedback Capture: Optional cancellation reason for analytics
Key Features:
- Immediate Cancellation: Stops membership processing immediately
- Feedback Collection: Capture customer cancellation reasons
- Automated Emails: Customer receives cancellation confirmation
- Activity Tracking: Logs cancellation to activity history
- Source Attribution: Tracks whether cancellation came from customer portal or API
Validation Checks:
- Contract Ownership: Verifies contract belongs to authenticated shop
- Minimum Cycles: Checks if minimum billing cycles requirement is met (if configured)
- Freeze Status: Validates membership is not frozen
- Existing Status: Ensures contract is not already cancelled
Email Notifications:
- Sends cancellation confirmation to customer email
- Includes membership details and cancellation date
- Uses customizable email templates from shop settings
Use Cases:
- Allow customers to cancel from custom portals or mobile apps
- Bulk cancellation workflows via external systems
- Integration with customer service platforms
- Automated cancellation based on business rules
- Churn management and retention workflows
Authentication: Requires API key authentication via X-API-Key header or api_key parameter
DELETE
/
api
/
external
/
v2
/
subscription-contracts
/
{id}
Cancel membership contract
curl --request DELETE \
--url https://membership-admin.appstle.com/api/external/v2/subscription-contracts/{id}import requests
url = "https://membership-admin.appstle.com/api/external/v2/subscription-contracts/{id}"
response = requests.delete(url)
print(response.text)const options = {method: 'DELETE'};
fetch('https://membership-admin.appstle.com/api/external/v2/subscription-contracts/{id}', 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/{id}';
const options = {method: 'DELETE'};
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/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
]);
$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/{id}"
req, _ := http.NewRequest("DELETE", 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/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
response = http.request(request)
puts response.read_body{
"detail": "This membership requires 3 minimum billing cycles before cancellation",
"errorKey": "min_cycles_not_met",
"status": 400,
"title": "Bad Request"
}Headers
Path Parameters
Membership contract ID to cancel
Query Parameters
API Key (Deprecated - Use Header X-API-Key instead)
Optional cancellation reason/feedback from customer
Response
Membership successfully cancelled, confirmation email sent
⌘I
Cancel membership contract
curl --request DELETE \
--url https://membership-admin.appstle.com/api/external/v2/subscription-contracts/{id}import requests
url = "https://membership-admin.appstle.com/api/external/v2/subscription-contracts/{id}"
response = requests.delete(url)
print(response.text)const options = {method: 'DELETE'};
fetch('https://membership-admin.appstle.com/api/external/v2/subscription-contracts/{id}', 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/{id}';
const options = {method: 'DELETE'};
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/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
]);
$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/{id}"
req, _ := http.NewRequest("DELETE", 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/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
response = http.request(request)
puts response.read_body{
"detail": "This membership requires 3 minimum billing cycles before cancellation",
"errorKey": "min_cycles_not_met",
"status": 400,
"title": "Bad Request"
}