cURL
curl --request PUT 'https://api.integrateledger.com/v1/customers/subscriptions/42/cancellation?customerId=user_123' \
-H "Authorization: Bearer $LEDGER_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"cancelAtPeriodEnd":true}'import os
from ledger_sdk import Ledger
ledger = Ledger(api_key=os.environ["LEDGER_API_KEY"])
ledger.set_subscription_cancellation(customer_id="user_123", subscription_id=42, cancel_at_period_end=True)import { Ledger } from "@ledger/sdk";
const ledger = new Ledger({ apiKey: process.env.LEDGER_API_KEY ?? "" });
await ledger.setSubscriptionCancellation({ subscriptionId: 42, customerId: "user_123", body: { cancelAtPeriodEnd: true } });const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({cancelAtPeriodEnd: true})
};
fetch('https://api.integrateledger.com/v1/customers/subscriptions/{subscriptionId}/cancellation', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.integrateledger.com/v1/customers/subscriptions/{subscriptionId}/cancellation",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'cancelAtPeriodEnd' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://api.integrateledger.com/v1/customers/subscriptions/{subscriptionId}/cancellation"
payload := strings.NewReader("{\n \"cancelAtPeriodEnd\": true\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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))
}HttpResponse<String> response = Unirest.put("https://api.integrateledger.com/v1/customers/subscriptions/{subscriptionId}/cancellation")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"cancelAtPeriodEnd\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.integrateledger.com/v1/customers/subscriptions/{subscriptionId}/cancellation")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cancelAtPeriodEnd\": true\n}"
response = http.request(request)
puts response.read_body{
"cancelAtPeriodEnd": true,
"cancelsAt": "2023-11-07T05:31:56Z"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Customers and usage
Stop or resume renewal
Schedule or reverse end-of-cycle cancellation for a paid subscription.
PUT
/
v1
/
customers
/
subscriptions
/
{subscriptionId}
/
cancellation
cURL
curl --request PUT 'https://api.integrateledger.com/v1/customers/subscriptions/42/cancellation?customerId=user_123' \
-H "Authorization: Bearer $LEDGER_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"cancelAtPeriodEnd":true}'import os
from ledger_sdk import Ledger
ledger = Ledger(api_key=os.environ["LEDGER_API_KEY"])
ledger.set_subscription_cancellation(customer_id="user_123", subscription_id=42, cancel_at_period_end=True)import { Ledger } from "@ledger/sdk";
const ledger = new Ledger({ apiKey: process.env.LEDGER_API_KEY ?? "" });
await ledger.setSubscriptionCancellation({ subscriptionId: 42, customerId: "user_123", body: { cancelAtPeriodEnd: true } });const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({cancelAtPeriodEnd: true})
};
fetch('https://api.integrateledger.com/v1/customers/subscriptions/{subscriptionId}/cancellation', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.integrateledger.com/v1/customers/subscriptions/{subscriptionId}/cancellation",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'cancelAtPeriodEnd' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://api.integrateledger.com/v1/customers/subscriptions/{subscriptionId}/cancellation"
payload := strings.NewReader("{\n \"cancelAtPeriodEnd\": true\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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))
}HttpResponse<String> response = Unirest.put("https://api.integrateledger.com/v1/customers/subscriptions/{subscriptionId}/cancellation")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"cancelAtPeriodEnd\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.integrateledger.com/v1/customers/subscriptions/{subscriptionId}/cancellation")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cancelAtPeriodEnd\": true\n}"
response = http.request(request)
puts response.read_body{
"cancelAtPeriodEnd": true,
"cancelsAt": "2023-11-07T05:31:56Z"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Pass the exact opaque
customerId as a URL-encoded query value and the numeric subscriptionId from List customer subscriptions. Set cancelAtPeriodEnd to true to stop the next renewal or false to resume it before the period ends. Retrying the same desired state is safe. Ledger verifies that the Stripe subscription belongs to this customer, organization, environment, and plan before changing it.
Stopping renewal does not refund the current period. The plan and its remaining plan credits stay available until the paid period ends; purchased credit packs are unaffected. Resuming restores future monthly billing. A pending plan upgrade or a Stripe pause, schedule, custom cancellation date, or mismatched subscription blocks the change. Stripe unavailability returns an error rather than guessing the state.
This endpoint manages an active paid subscription. It does not cancel an unpaid Checkout link. Use Billing and Checkout for payment timing and List customer purchases for credit packs.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Required range:
x <= 2147483647Query Parameters
Required string length:
1 - 255Body
application/json