curl --request POST \
--url https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"atPeriodEnd": true
}
'import requests
url = "https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel"
payload = { "atPeriodEnd": True }
headers = {
"x-api-key": "<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': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({atPeriodEnd: true})
};
fetch('https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel', 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.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel",
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([
'atPeriodEnd' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <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://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel"
payload := strings.NewReader("{\n \"atPeriodEnd\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<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))
}HttpResponse<String> response = Unirest.post("https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"atPeriodEnd\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"atPeriodEnd\": true\n}"
response = http.request(request)
puts response.read_body{
"status": "active",
"currentPeriodEnd": "2026-09-06T12:00:00.000Z",
"cancelAtPeriodEnd": true,
"effectiveCancelDate": "2026-09-06T12:00:00.000Z"
}{
"statusCode": 400,
"message": "amount is required when creating a session without a link",
"timestamp": "2026-08-06T12:00:00.000Z"
}{
"statusCode": 401,
"message": "Invalid API key",
"timestamp": "2026-08-06T12:00:00.000Z"
}{
"statusCode": 403,
"message": "Payment link belongs to another organization",
"timestamp": "2026-08-06T12:00:00.000Z"
}{
"statusCode": 404,
"message": "Payment link not found",
"timestamp": "2026-08-06T12:00:00.000Z"
}Cancel a subscription
Cancels at the end of the current paid period by default: the subscriber keeps what they already paid for, no refund. Pass atPeriodEnd: false to cancel immediately instead. Calling cancel again on an already-canceled subscription is a no-op. Returns 400 if the subscription never completed a first successful charge (stripeSubscriptionId is null).
curl --request POST \
--url https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"atPeriodEnd": true
}
'import requests
url = "https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel"
payload = { "atPeriodEnd": True }
headers = {
"x-api-key": "<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': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({atPeriodEnd: true})
};
fetch('https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel', 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.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel",
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([
'atPeriodEnd' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <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://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel"
payload := strings.NewReader("{\n \"atPeriodEnd\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<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))
}HttpResponse<String> response = Unirest.post("https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"atPeriodEnd\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/cancel")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"atPeriodEnd\": true\n}"
response = http.request(request)
puts response.read_body{
"status": "active",
"currentPeriodEnd": "2026-09-06T12:00:00.000Z",
"cancelAtPeriodEnd": true,
"effectiveCancelDate": "2026-09-06T12:00:00.000Z"
}{
"statusCode": 400,
"message": "amount is required when creating a session without a link",
"timestamp": "2026-08-06T12:00:00.000Z"
}{
"statusCode": 401,
"message": "Invalid API key",
"timestamp": "2026-08-06T12:00:00.000Z"
}{
"statusCode": 403,
"message": "Payment link belongs to another organization",
"timestamp": "2026-08-06T12:00:00.000Z"
}{
"statusCode": 404,
"message": "Payment link not found",
"timestamp": "2026-08-06T12:00:00.000Z"
}canceled subscription is a no-op. It returns the same result without hitting the card processor a second time. If the subscription never completed a first successful charge (stripeSubscriptionId is null), cancel returns 400.Authorizations
Your secret key, from app.agentaos.ai -> Settings -> Developers -> API Keys. The key's prefix is both its identity and its environment: sk_test_... (sandbox, free, no verification) or sk_live_... (real money, requires business verification). A missing or invalid key returns 401.
Path Parameters
Subscription UUID (the id field from the list response, not stripeSubscriptionId).
Body
true schedules the cancellation for period end. false cancels now.
Response
The subscription's updated cancellation state.