Update Usage Cap
curl --request POST \
--url https://api.launchmystore.io/api/v1/billing/usage/cap \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"cappedAmount": 123,
"returnUrl": "<string>"
}
'import requests
url = "https://api.launchmystore.io/api/v1/billing/usage/cap"
payload = {
"cappedAmount": 123,
"returnUrl": "<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({cappedAmount: 123, returnUrl: '<string>'})
};
fetch('https://api.launchmystore.io/api/v1/billing/usage/cap', 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.launchmystore.io/api/v1/billing/usage/cap",
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([
'cappedAmount' => 123,
'returnUrl' => '<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;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.launchmystore.io/api/v1/billing/usage/cap"
payload := strings.NewReader("{\n \"cappedAmount\": 123,\n \"returnUrl\": \"<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))
}HttpResponse<String> response = Unirest.post("https://api.launchmystore.io/api/v1/billing/usage/cap")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"cappedAmount\": 123,\n \"returnUrl\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.launchmystore.io/api/v1/billing/usage/cap")
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 \"cappedAmount\": 123,\n \"returnUrl\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyApp Billing
Update Usage Cap
Lower the usage cap of the installation at once, or ask the merchant to approve a higher one.
POST
/
api
/
v1
/
billing
/
usage
/
cap
Update Usage Cap
curl --request POST \
--url https://api.launchmystore.io/api/v1/billing/usage/cap \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"cappedAmount": 123,
"returnUrl": "<string>"
}
'import requests
url = "https://api.launchmystore.io/api/v1/billing/usage/cap"
payload = {
"cappedAmount": 123,
"returnUrl": "<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({cappedAmount: 123, returnUrl: '<string>'})
};
fetch('https://api.launchmystore.io/api/v1/billing/usage/cap', 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.launchmystore.io/api/v1/billing/usage/cap",
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([
'cappedAmount' => 123,
'returnUrl' => '<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;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.launchmystore.io/api/v1/billing/usage/cap"
payload := strings.NewReader("{\n \"cappedAmount\": 123,\n \"returnUrl\": \"<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))
}HttpResponse<String> response = Unirest.post("https://api.launchmystore.io/api/v1/billing/usage/cap")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"cappedAmount\": 123,\n \"returnUrl\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.launchmystore.io/api/v1/billing/usage/cap")
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 \"cappedAmount\": 123,\n \"returnUrl\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyThe cap is the most your app may charge the merchant for usage in one billing
period. It starts at
Open
pricing.usage.cappedAmount and changes like Shopify’s
capped-amount update:
- Lowering it (or setting a first cap on an uncapped install) applies at once. It cannot go below the usage already accrued this period.
- Raising it needs the merchant’s approval. The request is stored as
pending and the response carries a
confirmationUrl— a page in the merchant’s admin that shows the current and requested limit. The cap only changes when the merchant approves there. A new raise request replaces a pending one.
write_billing.
Request
number
required
The new cap in major units of the pricing currency (e.g.
40.25 =
$40.25), rounded to two decimals. 0 stops further usage charges until the
cap is raised again.string
Where to send the merchant after they approve or decline. Used only when it
is an
https URL on your App URL’s origin or on the origin of one of your
registered redirect URLs; otherwise the merchant stays in their admin.curl -X POST "https://api.launchmystore.io/api/v1/billing/usage/cap" \
-H "Authorization: Bearer <APP_ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "cappedAmount": 100, "returnUrl": "https://my-app.example.com/billing" }'
Response — applied (lowering)
{
"status": 200,
"state": "success",
"data": { "requiresApproval": false, "newCap": 8, "capAmountCents": 800 }
}
Response — approval required (raising)
{
"status": 200,
"state": "success",
"data": {
"requiresApproval": true,
"confirmationUrl": "https://app.launchmystore.io/appstore/usage-cap?installationId=…&returnUrl=…",
"currentCap": 50,
"requestedCap": 100
}
}
confirmationUrl in the top-level window (from an embedded app, use the
App Bridge Redirect action to the remote URL). While the request waits,
GET /api/v1/billing/usage reports
it as pendingCapAmountCents.
After the merchant decides
- They are returned to
returnUrl(when it passed the check above). - Your app receives an
app_subscriptions/updatewebhook withreason: "usage_cap_approved"or"usage_cap_declined"and the resultingcapAmountCents. - An approved cap applies to the next
POST /api/v1/billing/usagecall.
Errors
Errors use{ "errors": { "base": ["…"] } }.
| Status | When |
|---|---|
400 | The app’s pricing has no usage component. |
401 | Missing or invalid access token. |
403 | Token lacks write_billing. |
404 | Installation or app not found. |
422 | cappedAmount is missing, negative or not a number, or lower than the usage already accrued this period. |