Tiers & Margins
Tiers define pricing plans for your customers. Each tier specifies which AI models are available, their pricing, and monthly spend limits. Configure margins by setting model prices above provider costs.
What Are Tiers?
A tier is a pricing plan that controls:
- Model access: Which AI models customers can use
- Model pricing: Per-token costs for input and output
- Spend limits: Monthly credit allowance
- Subscription price: Optional Stripe billing (for paid tiers)
flowchart LR
subgraph project["Your Project"]
subgraph free["Free Tier"]
f1["$0/month • $5 credits"]
f2["Claude Haiku"]
f3["Margin: 20%"]
end
subgraph pro["Pro Tier"]
p1["$29/month • $29 credits"]
p2["Claude Sonnet, Haiku"]
p3["Margin: 15%"]
end
subgraph enterprise["Enterprise Tier"]
e1["$299/month • unlimited"]
e2["Claude Opus, Sonnet, Haiku"]
e3["Margin: 10%"]
end
end
Tier Structure
Core Fields
| Field | Type | Description |
|---|---|---|
tier_code |
string | Unique identifier (e.g., “free”, “pro”) |
display_name |
string | Human-readable name |
spend_limit_cents |
number | Monthly credit limit in cents |
models |
array | Allowed models with per-model pricing |
Billing Fields (Paid Tiers)
| Field | Type | Description |
|---|---|---|
billing_price_ref |
string | Billing provider price reference |
price_amount_cents |
number | Subscription price in cents |
price_currency |
string | Currency code (e.g., “usd”) |
price_interval |
string | “month” or “year” |
trial_days |
number | Optional trial period |
Creating Tiers
Dashboard
Create and configure tiers in the ModelRelay dashboard under Project Settings > Tiers. The dashboard provides a visual interface for:
- Setting tier codes and display names
- Configuring spend limits
- Adding models with custom pricing
- Setting up Stripe subscription billing
SDK
Create tiers programmatically using the SDK:
// List available tiers
const tiers = await mr.tiers.list();
for (const tier of tiers) {
console.log(`${tier.tier_code}: ${tier.display_name}`);
console.log(` Spend limit: $${tier.spend_limit_cents / 100}`);
console.log(` Models: ${tier.models.length}`);
if (tier.price_amount_cents) {
console.log(` Price: $${tier.price_amount_cents / 100}/${tier.price_interval}`);
}
}
tiers, err := client.Tiers.List(ctx)
if err != nil {
return err
}
for _, tier := range tiers {
fmt.Printf("%s: %s\n", tier.TierCode, tier.DisplayName)
fmt.Printf(" Spend limit: $%.2f\n", float64(tier.SpendLimitCents)/100)
fmt.Printf(" Models: %d\n", len(tier.Models))
if tier.PriceAmountCents > 0 {
fmt.Printf(" Price: $%.2f/%s\n", float64(tier.PriceAmountCents)/100, tier.PriceInterval)
}
}
// List available tiers
let tiers = client.tiers().list().await?;
for tier in tiers {
println!("{}: {}", tier.tier_code, tier.display_name);
println!(" Spend limit: ${:.2}", tier.spend_limit_cents as f64 / 100.0);
println!(" Models: {}", tier.models.len());
if let Some(price) = tier.price_amount_cents {
println!(" Price: ${:.2}/{}", price as f64 / 100.0, tier.price_interval.unwrap_or_default());
}
}
Model Pricing
Each tier contains a list of allowed models with per-model pricing. This is where you configure margins.
TierModel Fields
| Field | Type | Description |
|---|---|---|
model_id |
string | Model identifier (e.g., “claude-sonnet-4-20250514”) |
model_display_name |
string | Human-readable model name |
input_price_per_million_cents |
number | Input token price per million |
output_price_per_million_cents |
number | Output token price per million |
is_default |
boolean | Default model for this tier |
context_window |
number | Maximum context length |
max_output_tokens |
number | Maximum output tokens |
Viewing Model Pricing
const tier = await mr.tiers.get("tier_uuid");
for (const model of tier.models) {
const inputPer1M = model.input_price_per_million_cents / 100;
const outputPer1M = model.output_price_per_million_cents / 100;
console.log(`${model.model_display_name}${model.is_default ? " (default)" : ""}`);
console.log(` Input: $${inputPer1M.toFixed(2)} / 1M tokens`);
console.log(` Output: $${outputPer1M.toFixed(2)} / 1M tokens`);
}
tier, err := client.Tiers.Get(ctx, tierUUID)
if err != nil {
return err
}
for _, model := range tier.Models {
inputPer1M := float64(model.InputPricePerMillionCents) / 100
outputPer1M := float64(model.OutputPricePerMillionCents) / 100
defaultMarker := ""
if model.IsDefault {
defaultMarker = " (default)"
}
fmt.Printf("%s%s\n", model.ModelDisplayName, defaultMarker)
fmt.Printf(" Input: $%.2f / 1M tokens\n", inputPer1M)
fmt.Printf(" Output: $%.2f / 1M tokens\n", outputPer1M)
}
let tier = client.tiers().get(&tier_uuid).await?;
for model in &tier.models {
let input_per_1m = model.input_price_per_million_cents as f64 / 100.0;
let output_per_1m = model.output_price_per_million_cents as f64 / 100.0;
let default_marker = if model.is_default { " (default)" } else { "" };
println!("{}{}", model.model_display_name, default_marker);
println!(" Input: ${:.2} / 1M tokens", input_per_1m);
println!(" Output: ${:.2} / 1M tokens", output_per_1m);
}
Configuring Margins
Margins are the difference between what you charge customers and what providers charge you. Set per-model prices in your tier higher than provider costs to earn margin on each request.
Margin Calculation
Margin = Customer Price - Provider Cost - Platform Fee (4.5%)
Example: 20% Margin Strategy
If Claude Sonnet costs:
- Provider: $3.00 / 1M input, $15.00 / 1M output
Set your tier pricing at +20%:
- Your price: $3.60 / 1M input, $18.00 / 1M output
Your margin per million output tokens:
$18.00 - $15.00 - ($18.00 × 4.5%) = $2.19
Pricing Strategies
| Strategy | Description | Use Case |
|---|---|---|
| Cost-plus | Provider cost + fixed percentage | Simple, predictable margins |
| Value-based | Price based on customer value | Premium features or support |
| Tiered markup | Lower margins for higher tiers | Volume incentives |
| Subsidized | Price below cost | Customer acquisition |
Spend Limits
The spend_limit_cents field controls how much a customer can spend per billing period.
How Limits Work
- Per-request tracking: Each API request calculates token cost using tier pricing
- Cumulative usage: Costs accumulate throughout the billing period
- Quota enforcement: Requests fail with HTTP 402 when limit is reached
- Period reset: Usage resets at the start of each billing period
Unlimited Tiers
Set spend_limit_cents to 0 for unlimited usage:
// Enterprise tier with no spend limit
const enterpriseTier = tiers.find(t => t.spend_limit_cents === 0);
Credit Relationship
For paid tiers, the spend limit typically equals the subscription price:
| Tier | Price | Credits |
|---|---|---|
| Pro | $29/month | $29 |
| Business | $99/month | $99 |
| Enterprise | $299/month | Unlimited |
Customers get credits equal to what they pay. Usage above the limit is blocked (not billed extra).
Common Tier Patterns
Free Tier
A limited free tier for evaluation:
tier_code: "free"
display_name: "Free"
spend_limit_cents: 500 // $5.00
models:
- model_id: "claude-3-5-haiku-20241022"
is_default: true
input_price_per_million_cents: 100 // $1.00
output_price_per_million_cents: 500 // $5.00
Pro Tier
A paid tier with better models and higher limits:
tier_code: "pro"
display_name: "Pro"
price_amount_cents: 2900
price_interval: "month"
spend_limit_cents: 2900 // $29.00
models:
- model_id: "claude-sonnet-4-20250514"
is_default: true
input_price_per_million_cents: 360 // $3.60 (20% markup)
output_price_per_million_cents: 1800 // $18.00
- model_id: "claude-3-5-haiku-20241022"
input_price_per_million_cents: 100
output_price_per_million_cents: 500
Enterprise Tier
Unlimited access with premium models:
tier_code: "enterprise"
display_name: "Enterprise"
price_amount_cents: 29900
price_interval: "month"
spend_limit_cents: 0 // Unlimited
trial_days: 14
models:
- model_id: "claude-opus-4-20250514"
is_default: true
input_price_per_million_cents: 1800 // $18.00
output_price_per_million_cents: 9000 // $90.00
- model_id: "claude-sonnet-4-20250514"
input_price_per_million_cents: 360
output_price_per_million_cents: 1800
- model_id: "claude-3-5-haiku-20241022"
input_price_per_million_cents: 100
output_price_per_million_cents: 500
Upgrading Customers
To move a customer to a different tier, create a new checkout session for the target tier (or update the subscription in Stripe):
// Upgrade customer to pro tier
const customer = await mr.customers.get("cust_uuid");
const session = await mr.customers.subscribe(customer.customer.id, {
tier_id: proTierUUID,
success_url: "https://myapp.com/success",
cancel_url: "https://myapp.com/cancel",
});
// Redirect user to Stripe checkout
window.location.href = session.url;
// Upgrade customer to pro tier
customer, err := client.Customers.Get(ctx, customerUUID)
if err != nil {
return err
}
session, err := client.Customers.Subscribe(ctx, customer.Customer.ID, sdk.CustomerSubscribeRequest{
TierID: proTierUUID,
SuccessURL: "https://myapp.com/success",
CancelURL: "https://myapp.com/cancel",
})
if err != nil {
return err
}
// Redirect user to Stripe checkout
http.Redirect(w, r, session.URL, http.StatusSeeOther)
// Upgrade customer to pro tier
let customer = client.customers().get(&customer_uuid).await?;
let session = client.customers().subscribe(
customer.customer.id,
CustomerSubscribeRequest {
tier_id: pro_tier_uuid,
success_url: "https://myapp.com/success".to_string(),
cancel_url: "https://myapp.com/cancel".to_string(),
},
).await?;
// Redirect user to Stripe checkout
// Return session.url to your frontend for redirect
For paid tier upgrades with Stripe, create a new checkout session for the target tier. See Customer Billing for checkout flow details.
Best Practices
1. Start Simple
Begin with 2-3 tiers (free, pro, enterprise). Add complexity as you learn customer needs.
2. Include One Default Model
Every tier must have exactly one default model. This is used when customers don’t specify a model.
3. Consider Model Overlap
Pro tiers typically include all free tier models plus additional ones. This lets customers upgrade without changing their code.
4. Set Realistic Limits
Match spend limits to subscription prices. A $29/month tier should provide ~$29 of credits.
5. Monitor Margins
Track usage costs vs. revenue. Adjust pricing if margins are too thin or you’re subsidizing too much.
Next Steps
- Customer Billing — Manage customers and subscriptions
- Streaming — Real-time response streaming
- First Request — Make your first API call