Simulate Margin
curl --request POST \
--url https://api.nozle.app/engine/api/v1/margin/simulate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"metric_code": "<string>",
"new_price_dollars": 123
}
'import requests
url = "https://api.nozle.app/engine/api/v1/margin/simulate"
payload = {
"metric_code": "<string>",
"new_price_dollars": 123
}
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({metric_code: '<string>', new_price_dollars: 123})
};
fetch('https://api.nozle.app/engine/api/v1/margin/simulate', 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/margin/simulate"
payload := strings.NewReader("{\n \"metric_code\": \"<string>\",\n \"new_price_dollars\": 123\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/margin/simulate")
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 \"metric_code\": \"<string>\",\n \"new_price_dollars\": 123\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/margin/simulate",
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([
'metric_code' => '<string>',
'new_price_dollars' => 123
]),
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/margin/simulate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"metric_code\": \"<string>\",\n \"new_price_dollars\": 123\n}")
.asString();Margin Intelligence
Simulate Margin
POST
/
engine
/
api
/
v1
/
margin
/
simulate
Simulate Margin
curl --request POST \
--url https://api.nozle.app/engine/api/v1/margin/simulate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"metric_code": "<string>",
"new_price_dollars": 123
}
'import requests
url = "https://api.nozle.app/engine/api/v1/margin/simulate"
payload = {
"metric_code": "<string>",
"new_price_dollars": 123
}
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({metric_code: '<string>', new_price_dollars: 123})
};
fetch('https://api.nozle.app/engine/api/v1/margin/simulate', 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/margin/simulate"
payload := strings.NewReader("{\n \"metric_code\": \"<string>\",\n \"new_price_dollars\": 123\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/margin/simulate")
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 \"metric_code\": \"<string>\",\n \"new_price_dollars\": 123\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/margin/simulate",
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([
'metric_code' => '<string>',
'new_price_dollars' => 123
]),
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/margin/simulate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"metric_code\": \"<string>\",\n \"new_price_dollars\": 123\n}")
.asString();Base URL:
The simulation covers the date range given by the
All amounts are integer cents.
https://api.nozle.app/engine/api/v1.
Simulate the margin of one metric at a new unit price before you change it. The simulation replays the metric’s recorded usage at the new price and keeps the recorded cost.
Auth: sk_ only. With API key permissions, the key needs analytic:read; without it the call returns 403 with code: permission_denied.
All margin endpoints require a secret key (
sk_). These endpoints expose cost data that should never be visible to your end users.POST /margin/simulate
Authorization: Bearer sk_nozle_...
Content-Type: application/json
{
"metric_code": "agent_execution",
"new_price_dollars": 1
}
string
required
Code of the metric to simulate. A missing or empty value returns
400 with {"code": "invalid_request", "error": "metric_code required"}.number
required
New price per unit of usage, in dollars (a JSON number, not a string). It must be
0 or more. A missing, negative or string value returns 400 with code invalid_request.from and to query parameters, which default to the last month. They take a YYYY-MM-DD date (a plain to includes that whole day) or an RFC3339 timestamp (an exclusive instant), with from_date and to_date as aliases. When you send only one end, the API derives the other: only to covers the month before it, and only from runs until now (one month after from if it is not in the past). An unparseable value, or an end that is not after the start, returns 400 with {"code": "invalid_date_range", "error": "..."}. See Margin Summary for the full rules. The body takes no other fields: an unknown field such as plan_code or new_price_cents returns 400 with code invalid_request. The query string is read only for from, to, from_date and to_date. The body is checked before the range, so a body error is returned first.
Response
{
"metric_code": "agent_execution",
"current_revenue_cents": 14750,
"current_cost_cents": 2360,
"current_margin_cents": 12390,
"new_revenue_cents": 29500,
"new_cost_cents": 2360,
"new_margin_cents": 27140,
"revenue_delta_cents": 14750,
"margin_delta_cents": 14750,
"event_count": 295
}
new_revenue_cents is the total recorded quantity multiplied by new_price_dollars and 100, truncated to a whole cent. new_cost_cents equals current_cost_cents: the simulation changes price only. The deltas are new minus current. A metric with no events in the range returns zeros with event_count 0.