Model Pricing API
curl --request GET \
--url https://api.apimart.ai/api/pricing/modelimport requests
url = "https://api.apimart.ai/api/pricing/model"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.apimart.ai/api/pricing/model', 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.apimart.ai/api/pricing/model",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.apimart.ai/api/pricing/model"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.apimart.ai/api/pricing/model")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apimart.ai/api/pricing/model")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyqwen3.8-max
Model Pricing API
- GET /api/pricing/model for display rates
- Read only data.pricing; effective_rates is what users pay
- Tool prices must be multiplied by price_factor
- Contract is generic for TokenPricingV2 models
GET
/
api
/
pricing
/
model
Model Pricing API
curl --request GET \
--url https://api.apimart.ai/api/pricing/modelimport requests
url = "https://api.apimart.ai/api/pricing/model"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.apimart.ai/api/pricing/model', 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.apimart.ai/api/pricing/model",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.apimart.ai/api/pricing/model"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.apimart.ai/api/pricing/model")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apimart.ai/api/pricing/model")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyExamples use
Model behavior and billing rules: qwen3.8-max guide.
Read only
The response may include several overlapping price blocks — frontends should only use
Use
Tool prices:
Asymmetry in the current API:
Respect
Examples:
Multi-tier: only
Tier rule: pick one tier from total input tokens of the request, then price the whole request at that tier (not progressive). Values in
qwen3.8-max, but the data.pricing shape is shared by all TokenPricingV2 models.
GET /api/pricing/model?model=qwen3.8-max
This endpoint does not require authentication. Do not send
Authorization.Request parameters
string
requerido
Model ID, e.g.
qwen3.8-max. Required; omitting it returns 400 Missing model parameter.Read only data.pricing
The response may include several overlapping price blocks — frontends should only use data.pricing:
| Block | Purpose | Frontend |
|---|---|---|
data.pricing | Flat, self-describing display view | ✅ Use this |
data.token_price | Legacy flat copy | ❌ Compatibility only; missing fields |
data.token_pricing | Internal snapshot | ❌ Implementation details |
token_price may omit fields like explicit_cached_input, so estimates run high. New billing dimensions are added only under pricing.
{
"token_price": {
"input": 1.714286,
"cached_input": 0.214286,
"cache_write": 2.142857,
"output": 5.142857
},
"pricing": {
"rates": {
"input": 1.714286,
"cached_input": 0.214286,
"cache_write": 2.142857,
"explicit_cached_input": 0.142857,
"output": 5.142857
}
}
}
rates vs effective_rates
| Field | Meaning |
|---|---|
rates | List / strikethrough price |
effective_rates | What to display as payable (discounts applied) |
discount_rate | Model discount (1 = none) |
group_ratio | Group multiplier |
price_factor | discount_rate × group_ratio |
{
"discount_rate": 1,
"group_ratio": 0.8,
"price_factor": 0.8,
"rates": { "input": 1.714286, "output": 5.142857 },
"effective_rates": { "input": 1.3714288, "output": 4.1142856 }
}
effective_rates for UI prices — do not multiply yourself. Use rates only when showing list price alongside.
group is often default: public pricing pages quote default. A user’s real charge uses their group and may be lower than the displayed price.rates / effective_rates use usd_per_million_tokens (USD per 1M tokens).
Tool prices: extras.tools is list price only
Asymmetry in the current API:
| List | Payable | |
|---|---|---|
| Tokens | rates | effective_rates (precomputed) |
| Built-in tools | extras.tools[x].price | No effective field — multiply by price_factor yourself |
const listed = pricing.extras.tools.web_search.price;
const actual = listed * pricing.price_factor; // display this
unit — do not hardcode “per 1k calls”:
unit | Meaning | Cost |
|---|---|---|
usd_per_1000_queries | Per 1000 calls | price / 1000 × count |
usd_per_page | Per page | price × pages (do not divide by 1000) |
Three-state field semantics
| Case | JSON | Meaning |
|---|---|---|
| Present | "explicit_cached_input": 0.142857 | Bill at this rate |
| Key missing | — | Dimension not applicable (not zero, not free) |
Explicit 0 | "price": 0 | Actually free — show as free |
- Missing
output_thinking→ single output rate; do not render “thinking is free”. Forqwen3.8-max, thinking cannot be disabled and there is one output price. - Missing
extras.google_web_search→ Vertex-only; Bailian-style search is underextras.tools.web_search. - Tool with
price: 0→ explicit free (e.g. promo); show free.
Multi-tier: only tier_count
{
"billing_type": "tiered_token",
"tier_count": 1
}
| Check | Behavior |
|---|---|
tier_count === 1 | Do not render a tier table; use rates / effective_rates |
tier_count > 1 | tiers[] present; up_to_input_tokens is inclusive upper bound; missing key = uncapped (usually last tier) |
tiers are list prices — multiply by price_factor.
Do not use
billing_type === "tiered_token" to detect multi-tier pricing — single-tier models can still use that value. Only trust tier_count.limits (not prices)
{
"limits": {
"max_input_tokens": 983616,
"max_output_tokens": 131072,
"supports_cache_read": true,
"supports_cache_write": true
}
}
supports_cache_*: capability flags; iffalse, do not present cache rates as available even if present inrates.max_output_tokens: pre-charge style cap whenmax_tokensis omitted — not a price.
TypeScript types
type ToolItem = {
unit: "usd_per_1000_queries" | "usd_per_page";
price: number; // list price; × price_factor for display
precharge_queries?: number;
};
type Rates = {
input?: number;
cached_input?: number;
explicit_cached_input?: number;
cache_write?: number;
cache_write_5m?: number;
cache_write_1h?: number;
output?: number;
output_thinking?: number;
text_input?: number;
cached_text_input?: number;
image_input?: number;
cached_image_input?: number;
text_output?: number;
image_output?: number;
};
type ModelPricing = {
billing_type: string;
source: "v1" | "v2";
unit: "usd_per_million_tokens";
pricing_mode: "standard" | "image_modalities";
discount_rate: number;
group: string;
group_ratio: number;
price_factor: number;
resolved_from?: string;
rates?: Rates;
effective_rates?: Rates;
tier_count: number;
tiers?: (Rates & { up_to_input_tokens?: number })[];
limits?: {
max_input_tokens?: number;
max_output_tokens?: number;
supports_cache_read: boolean;
supports_cache_write: boolean;
};
extras?: {
tools?: Record<string, ToolItem>;
google_web_search?: ToolItem;
};
};
Tool row helper
const toolRows = Object.entries(pricing.extras?.tools ?? {}).map(
([tool, item]) => ({
tool,
actual: item.price * pricing.price_factor,
suffix: item.unit === "usd_per_page" ? "/ page" : "/ 1k calls",
free: item.price === 0,
}),
);
Common mistakes
| Wrong | Right |
|---|---|
Read token_price | Read pricing.rates / pricing.effective_rates |
Multiply rates yourself | Use effective_rates |
Show raw extras.tools[x].price | Multiply by price_factor |
| Hardcode “per 1k calls” | Branch on item.unit |
| Treat missing keys as 0 / free | Missing = N/A; only explicit 0 is free |
Use billing_type for tiers | Use tier_count > 1 |
Read tiers for single-tier | Use rates |
Mix pricing_mode fields | standard vs image_modalities are exclusive |
Request examples
curl --request GET \
--url 'https://api.apimart.ai/api/pricing/model?model=qwen3.8-max' \
--header 'Accept: application/json'
import requests
url = "https://api.apimart.ai/api/pricing/model"
params = {"model": "qwen3.8-max"}
headers = {"Accept": "application/json"}
print(requests.get(url, params=params, headers=headers).json())