curl --request POST \
--url https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/plan-change \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"targetLinkId": "c9e44cf2-b3c3-465c-8ab8-de0706be4974",
"prorationDate": 1788434542
}
'import requests
url = "https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/plan-change"
payload = {
"targetLinkId": "c9e44cf2-b3c3-465c-8ab8-de0706be4974",
"prorationDate": 1788434542
}
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({
targetLinkId: 'c9e44cf2-b3c3-465c-8ab8-de0706be4974',
prorationDate: 1788434542
})
};
fetch('https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/plan-change', 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}/plan-change",
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([
'targetLinkId' => 'c9e44cf2-b3c3-465c-8ab8-de0706be4974',
'prorationDate' => 1788434542
]),
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}/plan-change"
payload := strings.NewReader("{\n \"targetLinkId\": \"c9e44cf2-b3c3-465c-8ab8-de0706be4974\",\n \"prorationDate\": 1788434542\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}/plan-change")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"targetLinkId\": \"c9e44cf2-b3c3-465c-8ab8-de0706be4974\",\n \"prorationDate\": 1788434542\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/plan-change")
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 \"targetLinkId\": \"c9e44cf2-b3c3-465c-8ab8-de0706be4974\",\n \"prorationDate\": 1788434542\n}"
response = http.request(request)
puts response.read_body{
"direction": "upgrade",
"applied": true,
"status": "active",
"unitAmountMinor": 4900,
"currency": "eur"
}Change the plan
Apply a plan change quoted by the preview. Echo the preview’s prorationDate so the amount charged matches the quote. An upgrade charges the prorated difference on the saved card now and the response carries the new per-cycle amount; a downgrade is scheduled for the current period end (effectiveAt) and charges nothing today. Idempotent on (subscription, target plan, prorationDate). Same plan, a non-active subscription, a different currency, or a different billing interval return 400.
curl --request POST \
--url https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/plan-change \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"targetLinkId": "c9e44cf2-b3c3-465c-8ab8-de0706be4974",
"prorationDate": 1788434542
}
'import requests
url = "https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/plan-change"
payload = {
"targetLinkId": "c9e44cf2-b3c3-465c-8ab8-de0706be4974",
"prorationDate": 1788434542
}
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({
targetLinkId: 'c9e44cf2-b3c3-465c-8ab8-de0706be4974',
prorationDate: 1788434542
})
};
fetch('https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/plan-change', 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}/plan-change",
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([
'targetLinkId' => 'c9e44cf2-b3c3-465c-8ab8-de0706be4974',
'prorationDate' => 1788434542
]),
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}/plan-change"
payload := strings.NewReader("{\n \"targetLinkId\": \"c9e44cf2-b3c3-465c-8ab8-de0706be4974\",\n \"prorationDate\": 1788434542\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}/plan-change")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"targetLinkId\": \"c9e44cf2-b3c3-465c-8ab8-de0706be4974\",\n \"prorationDate\": 1788434542\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.agentaos.ai/api/v1/gateway/subscriptions/{id}/plan-change")
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 \"targetLinkId\": \"c9e44cf2-b3c3-465c-8ab8-de0706be4974\",\n \"prorationDate\": 1788434542\n}"
response = http.request(request)
puts response.read_body{
"direction": "upgrade",
"applied": true,
"status": "active",
"unitAmountMinor": 4900,
"currency": "eur"
}prorationDate; that is what makes the charge equal the quote. A downgrade charges nothing today and switches at the current period end.prorationDate): retrying the same request does not charge twice. Same plan, a subscription that is not active or trialing, a different currency, or a different billing interval return 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 id.
Body
Response
The applied change. Shape depends on direction.
- Upgrade applied
- Downgrade scheduled
- Pending downgrade reverted