Subscription Management
Split or duplicate an existing subscription contract
Creates a new subscription contract by either splitting (moving) or duplicating selected line items from an existing contract. This endpoint allows you to divide a subscription into multiple contracts or create a copy with specific products.
Split vs Duplicate Mode:
- Split (isSplitContract=true): Moves the selected line items from the original contract to a new contract. The original contract will no longer contain these items.
- Duplicate (isSplitContract=false): Creates a new contract with copies of the selected line items while keeping them in the original contract.
Important Notes:
- When splitting, at least one subscription product must remain in the original contract
- The new contract inherits all settings from the original: customer, payment method, billing/delivery policies, shipping address, and custom attributes
- Billing schedule is automatically generated for the new contract
- One-time products and free products don’t count towards the minimum product requirement
Use Cases:
- Split a subscription when customer wants different delivery schedules for different products
- Create a gift subscription from an existing subscription
- Separate products for different shipping addresses
- Duplicate a subscription for testing or backup purposes
Authentication: Requires valid X-API-Key header
POST
/
api
/
external
/
v2
/
subscription-contract-details
/
split-existing-contract
Split or duplicate an existing subscription contract
curl --request POST \
--url https://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <x-api-key>' \
--data '[
"<string>"
]'import requests
url = "https://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract"
payload = ["<string>"]
headers = {
"X-API-Key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify(['<string>'])
};
fetch('https://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract';
const options = {
method: 'POST',
headers: {'X-API-Key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify(['<string>'])
};
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://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <x-api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract"
payload := strings.NewReader("[\n \"<string>\"\n]")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<x-api-key>")
req.Header.Add("Content-Type", "application/json")
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://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "[\n \"<string>\"\n]"
response = http.request(request)
puts response.read_body{
"billingPolicy": {
"interval": "MONTH",
"intervalCount": 1
},
"customAttributes": [
{
"key": "_origin_type",
"value": "SPLIT_CONTRACT"
},
{
"key": "_original_contract_id",
"value": "123456789"
}
],
"customer": {
"email": "customer@example.com",
"id": "gid://shopify/Customer/111111"
},
"deliveryPolicy": {
"interval": "MONTH",
"intervalCount": 1
},
"id": "gid://shopify/SubscriptionContract/987654321",
"lines": {
"edges": [
{
"node": {
"currentPrice": {
"amount": "29.99",
"currencyCode": "USD"
},
"id": "gid://shopify/SubscriptionLine/222222",
"quantity": 2,
"title": "Premium Coffee - Medium Roast",
"variantId": "gid://shopify/ProductVariant/333333"
}
}
]
},
"nextBillingDate": "2024-02-15T00:00:00Z",
"originOrder": {
"id": "gid://shopify/Order/123456789"
},
"status": "ACTIVE"
}Headers
API Key
Query Parameters
API Key (Deprecated)
Subscription contract ID
Split or duplicate mode
Attempt billing immediately
Body
application/json
Response
Contract successfully split/duplicated
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Available options:
SUCCEEDED, FAILED, $UNKNOWN Show child attributes
Show child attributes
Show child attributes
Show child attributes
Available options:
ACTIVE, PAUSED, CANCELLED, EXPIRED, FAILED, $UNKNOWN ⌘I
Split or duplicate an existing subscription contract
curl --request POST \
--url https://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <x-api-key>' \
--data '[
"<string>"
]'import requests
url = "https://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract"
payload = ["<string>"]
headers = {
"X-API-Key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify(['<string>'])
};
fetch('https://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));const url = 'https://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract';
const options = {
method: 'POST',
headers: {'X-API-Key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify(['<string>'])
};
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://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <x-api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract"
payload := strings.NewReader("[\n \"<string>\"\n]")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<x-api-key>")
req.Header.Add("Content-Type", "application/json")
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://subscription-admin.appstle.com/api/external/v2/subscription-contract-details/split-existing-contract")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "[\n \"<string>\"\n]"
response = http.request(request)
puts response.read_body{
"billingPolicy": {
"interval": "MONTH",
"intervalCount": 1
},
"customAttributes": [
{
"key": "_origin_type",
"value": "SPLIT_CONTRACT"
},
{
"key": "_original_contract_id",
"value": "123456789"
}
],
"customer": {
"email": "customer@example.com",
"id": "gid://shopify/Customer/111111"
},
"deliveryPolicy": {
"interval": "MONTH",
"intervalCount": 1
},
"id": "gid://shopify/SubscriptionContract/987654321",
"lines": {
"edges": [
{
"node": {
"currentPrice": {
"amount": "29.99",
"currencyCode": "USD"
},
"id": "gid://shopify/SubscriptionLine/222222",
"quantity": 2,
"title": "Premium Coffee - Medium Roast",
"variantId": "gid://shopify/ProductVariant/333333"
}
}
]
},
"nextBillingDate": "2024-02-15T00:00:00Z",
"originOrder": {
"id": "gid://shopify/Order/123456789"
},
"status": "ACTIVE"
}