Cancel Subscription
curl --request POST \
--url https://api.devkit4ai.com/api/v1/payments/stripe/cancel-subscription \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"cancel_immediately": false
}
'import requests
url = "https://api.devkit4ai.com/api/v1/payments/stripe/cancel-subscription"
payload = { "cancel_immediately": False }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({cancel_immediately: false})
};
fetch('https://api.devkit4ai.com/api/v1/payments/stripe/cancel-subscription', 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.devkit4ai.com/api/v1/payments/stripe/cancel-subscription",
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([
'cancel_immediately' => false
]),
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.devkit4ai.com/api/v1/payments/stripe/cancel-subscription"
payload := strings.NewReader("{\n \"cancel_immediately\": false\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.devkit4ai.com/api/v1/payments/stripe/cancel-subscription")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"cancel_immediately\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.devkit4ai.com/api/v1/payments/stripe/cancel-subscription")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cancel_immediately\": false\n}"
response = http.request(request)
puts response.read_body{
"subscription_id": "<string>",
"status": "<string>",
"message": "<string>",
"cancel_at": "2023-11-07T05:31:56Z",
"cancelled_at": "2023-11-07T05:31:56Z"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Stripe Subscriptions
Cancel Subscription
Cancel the user’s active Stripe subscription
POST
/
api
/
v1
/
payments
/
stripe
/
cancel-subscription
Cancel Subscription
curl --request POST \
--url https://api.devkit4ai.com/api/v1/payments/stripe/cancel-subscription \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"cancel_immediately": false
}
'import requests
url = "https://api.devkit4ai.com/api/v1/payments/stripe/cancel-subscription"
payload = { "cancel_immediately": False }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({cancel_immediately: false})
};
fetch('https://api.devkit4ai.com/api/v1/payments/stripe/cancel-subscription', 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.devkit4ai.com/api/v1/payments/stripe/cancel-subscription",
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([
'cancel_immediately' => false
]),
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.devkit4ai.com/api/v1/payments/stripe/cancel-subscription"
payload := strings.NewReader("{\n \"cancel_immediately\": false\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.devkit4ai.com/api/v1/payments/stripe/cancel-subscription")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"cancel_immediately\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.devkit4ai.com/api/v1/payments/stripe/cancel-subscription")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cancel_immediately\": false\n}"
response = http.request(request)
puts response.read_body{
"subscription_id": "<string>",
"status": "<string>",
"message": "<string>",
"cancel_at": "2023-11-07T05:31:56Z",
"cancelled_at": "2023-11-07T05:31:56Z"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Cancel the authenticated user’s active subscription. Can cancel immediately or at the end of the current billing period.
Authentication
This endpoint requires end user authentication via HTTP Bearer Token with project scope.
Query Parameters
boolean
default:"true"
Use test mode credentials. Set to
false for production.Request Body
boolean
default:"false"
If
true, cancels the subscription immediately and revokes access. If false, cancels at the end of the current billing period (user retains access until then).Response
string
Stripe subscription ID
string
New subscription status:
canceled or active (will cancel at period end)datetime
When the subscription will be canceled (if scheduled)
datetime
When the cancellation was processed
string
Human-readable confirmation message
Example Request
Cancel at Period End (Recommended)
curl -X POST "https://api.devkit4ai.com/api/v1/payments/stripe/cancel-subscription?test_mode=true" \
-H "Authorization: Bearer {end_user_jwt}" \
-H "Content-Type: application/json" \
-d '{
"cancel_immediately": false
}'
Cancel Immediately
curl -X POST "https://api.devkit4ai.com/api/v1/payments/stripe/cancel-subscription?test_mode=true" \
-H "Authorization: Bearer {end_user_jwt}" \
-H "Content-Type: application/json" \
-d '{
"cancel_immediately": true
}'
Example Response
Cancel at Period End
{
"subscription_id": "sub_1ABC123def456",
"status": "active",
"cancel_at": "2026-02-01T00:00:00Z",
"cancelled_at": "2026-01-24T15:30:00Z",
"message": "Subscription will be canceled at the end of the current billing period."
}
Immediate Cancellation
{
"subscription_id": "sub_1ABC123def456",
"status": "canceled",
"cancel_at": null,
"cancelled_at": "2026-01-24T15:30:00Z",
"message": "Subscription has been canceled immediately."
}
Cancellation Options
Best Practice: Default to
cancel_immediately: false to give users time to reconsider or allow continued access until they’ve been billed for.Integration Example
// Cancel subscription with confirmation
async function cancelSubscription(immediately: boolean = false) {
const confirmed = await showConfirmDialog(
immediately
? 'Cancel immediately? You will lose access now.'
: 'Cancel at period end? You will retain access until your next billing date.'
);
if (!confirmed) return;
const response = await fetch('/api/cancel-subscription', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ cancel_immediately: immediately })
});
const result = await response.json();
showToast(result.message);
refreshSubscriptionStatus();
}
Handling Scheduled Cancellations
When a subscription is scheduled to cancel, update your UI accordingly:function SubscriptionStatus({ subscription }) {
if (subscription.cancel_at) {
return (
<div className="warning">
<p>Your subscription will end on {formatDate(subscription.cancel_at)}</p>
<button onClick={reactivateSubscription}>Keep Subscription</button>
</div>
);
}
return <p>Active until {formatDate(subscription.current_period_end)}</p>;
}
Reactivating Canceled Subscriptions
To reactivate a subscription scheduled for cancellation, users should use the Customer Portal or start a new checkout.
Error Responses
| Status | Description |
|---|---|
401 | Unauthorized - Invalid or missing authentication |
404 | No active subscription to cancel |
404 | Project not found or Stripe not configured |
Related Pages
Get My Subscription
Check subscription status
Update Subscription
Change plans instead
Customer Portal
Let user manage cancellation
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Query Parameters
Use test mode
Body
application/json
Request to cancel a subscription.
If true, cancels immediately. Otherwise cancels at period end.

