Upgrade Plan
curl --request POST \
--url https://api.nozle.app/engine/api/v1/billing/upgrade \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"customer_id": "<string>",
"plan_code": "<string>"
}
'import requests
url = "https://api.nozle.app/engine/api/v1/billing/upgrade"
payload = {
"customer_id": "<string>",
"plan_code": "<string>"
}
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({customer_id: '<string>', plan_code: '<string>'})
};
fetch('https://api.nozle.app/engine/api/v1/billing/upgrade', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.nozle.app/engine/api/v1/billing/upgrade"
payload := strings.NewReader("{\n \"customer_id\": \"<string>\",\n \"plan_code\": \"<string>\"\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))
}require 'uri'
require 'net/http'
url = URI("https://api.nozle.app/engine/api/v1/billing/upgrade")
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 \"customer_id\": \"<string>\",\n \"plan_code\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.nozle.app/engine/api/v1/billing/upgrade",
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([
'customer_id' => '<string>',
'plan_code' => '<string>'
]),
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;
}HttpResponse<String> response = Unirest.post("https://api.nozle.app/engine/api/v1/billing/upgrade")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"customer_id\": \"<string>\",\n \"plan_code\": \"<string>\"\n}")
.asString();Checkout & Subscriptions
Upgrade Plan
POST
/
engine
/
api
/
v1
/
billing
/
upgrade
Upgrade Plan
curl --request POST \
--url https://api.nozle.app/engine/api/v1/billing/upgrade \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"customer_id": "<string>",
"plan_code": "<string>"
}
'import requests
url = "https://api.nozle.app/engine/api/v1/billing/upgrade"
payload = {
"customer_id": "<string>",
"plan_code": "<string>"
}
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({customer_id: '<string>', plan_code: '<string>'})
};
fetch('https://api.nozle.app/engine/api/v1/billing/upgrade', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.nozle.app/engine/api/v1/billing/upgrade"
payload := strings.NewReader("{\n \"customer_id\": \"<string>\",\n \"plan_code\": \"<string>\"\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))
}require 'uri'
require 'net/http'
url = URI("https://api.nozle.app/engine/api/v1/billing/upgrade")
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 \"customer_id\": \"<string>\",\n \"plan_code\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.nozle.app/engine/api/v1/billing/upgrade",
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([
'customer_id' => '<string>',
'plan_code' => '<string>'
]),
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;
}HttpResponse<String> response = Unirest.post("https://api.nozle.app/engine/api/v1/billing/upgrade")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"customer_id\": \"<string>\",\n \"plan_code\": \"<string>\"\n}")
.asString();Base URL:
The
https://api.nozle.app/engine/api/v1.
Change a customer’s current plan without checkout from a trusted backend.
Auth: secret key only. Publishable keys are rejected.
string
required
External customer ID.
string
required
The plan code to upgrade the customer to.
Response
Nozle reads the customer’s current subscription and its plan. A customer with one current subscription uses it. With several, Nozle uses the customer’s own subscription (not owned by an Entity) when there is exactly one; otherwise the request returns409 with subscription_required and changes nothing. The most recently started subscription is no longer picked for you. If the target plan’s yearly amount is above zero and at least the current plan’s yearly amount, the request returns 422 and nothing changes. This includes a change between two paid plans with the same price. Otherwise Nozle changes the plan and returns Core’s subscription response, {"subscription": {...}}, with Core’s status code.
The 422 body:
{
"error": "payment_checkout_required",
"code": "payment_checkout_required"
}
409 body:
{
"error": "subscription_required",
"code": "subscription_required"
}
404 means the plan, the active subscription, or the active subscription’s plan was not found. A missing plan_code or customer_id returns 400.
For customer self-service, use a signed preview and POST /checkout for a selected upgrade, or the end-of-period transition API for a scheduled downgrade. The current paid plan stays active until required payment is fulfilled. See Subscription self-service for the complete flow.
Also available to trusted backends as
POST /subscriptions/change (alias). Do not expose either route to browser code.