Estimate Cost
Estimate the cost of a chat completion request before making payment. No payment required.
Endpoint
POST /v1/estimateRequest
Headers
Content-Type: application/jsonBody Parameters
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
messages | Array | Yes | - | Array of message objects |
model | String | No | anthropic/claude-3.5-sonnet | AI model to use |
max_tokens | Number | No | 4096 | Maximum tokens to generate |
Response
Success (200 OK)
{
model: string; // Model that will be used
estimatedInputTokens: number; // Estimated input token count
estimatedOutputTokens: number; // Estimated output token count
estimatedCost: {
usd: string; // Maximum estimated cost in USD (actual may be lower)
note: string; // Information about refunds
};
message: string; // Additional information
}Examples
Basic Estimate
curl -X POST https://api.x-router.ai/v1/estimate \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"role": "user",
"content": "Explain quantum computing in simple terms"
}
],
"model": "anthropic/claude-3.5-sonnet",
"max_tokens": 500
}'With TypeScript
const estimateResponse = await fetch('https://api.x-router.ai/v1/estimate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
messages: [
{ role: 'user', content: 'Explain quantum computing in simple terms' }
],
model: 'anthropic/claude-3.5-sonnet',
max_tokens: 500
})
});
const estimate = await estimateResponse.json();
console.log(`Estimated cost: $${estimate.estimatedCost.usd}`);
console.log(`Input tokens: ${estimate.estimatedInputTokens}`);
console.log(`Output tokens: ${estimate.estimatedOutputTokens}`);Check Before Proceeding
import { wrapFetchWithPayment } from 'x402-fetch';
import { privateKeyToAccount } from 'viem/accounts';
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const fetchWithPayment = wrapFetchWithPayment(fetch, account);
const requestBody = {
messages: [
{ role: 'user', content: 'Write a haiku about coding' }
],
model: 'anthropic/claude-3.5-sonnet',
max_tokens: 100
};
// 1. Get cost estimate (free)
const estimateResponse = await fetch('https://api.x-router.ai/v1/estimate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestBody)
});
const estimate = await estimateResponse.json();
console.log(`Estimated cost: $${estimate.estimatedCost.usd}`);
// 2. Proceed only if cost is acceptable
if (parseFloat(estimate.estimatedCost.usd) < 0.01) {
const response = await fetchWithPayment('https://api.x-router.ai/v1/chat/completions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestBody)
});
const data = await response.json();
console.log(data.content);
} else {
console.log('Cost too high, skipping request');
}Compare Model Costs
const messages = [
{ role: 'user', content: 'Explain machine learning' }
];
const models = [
'anthropic/claude-3.5-sonnet',
'openai/gpt-4o',
'google/gemini-pro'
];
console.log('Cost comparison:');
for (const model of models) {
const response = await fetch('https://api.x-router.ai/v1/estimate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
messages,
model,
max_tokens: 500
})
});
const estimate = await response.json();
console.log(`${model}: $${estimate.estimatedCost.usd}`);
}Example Response
{
"model": "anthropic/claude-3.5-sonnet",
"estimatedInputTokens": 18,
"estimatedOutputTokens": 500,
"estimatedCost": {
"usd": "0.007632",
"note": "Maximum upfront charge. Any difference from actual cost is automatically refunded."
},
"message": "Price is calculated based on prompt length and requested output tokens"
}Important Notes
Maximum Cost Guarantee
The estimate represents the maximum you’ll be charged upfront. After your request completes, the actual cost is calculated and any overpayment is automatically refunded to your wallet.
Price Components
The estimated cost is calculated from:
- Input tokens: Counted from your messages using the model’s tokenizer
- Output tokens: Set to your
max_tokensvalue - Model rates: Retrieved from the model’s pricing configuration
Payment and Refunds
You pay the estimated maximum amount upfront:
- Payment is based on
max_tokens, not actual tokens generated - This ensures predictable costs and allows payment before generation
- Automatic refunds: After completion, any difference between the estimate and actual cost is automatically refunded to your wallet
- No action needed - refunds are processed automatically
Use Cases
- Budget control: Check if a request fits your budget before making it
- Model comparison: Compare costs across different models
- Optimization: Find the cheapest model for your use case
- Monitoring: Track estimated costs for analytics
Best Practices
Always Estimate Expensive Requests
For large requests, always estimate first:
// Good: Estimate first for large requests
const estimate = await fetch('/v1/estimate', { /* ... */ });
if (parseFloat(estimate.estimatedCost.usd) < maxCost) {
// Proceed with actual request
}
// Bad: Make expensive requests without checking
const response = await fetchWithPayment('/v1/chat/completions', {
// Large request without checking cost
});Cache Estimates
If you’re making similar requests, cache the estimates:
const estimateCache = new Map();
async function getEstimate(messages, model, maxTokens) {
const key = JSON.stringify({ messages, model, maxTokens });
if (!estimateCache.has(key)) {
const response = await fetch('/v1/estimate', { /* ... */ });
const estimate = await response.json();
estimateCache.set(key, estimate);
}
return estimateCache.get(key);
}Set Cost Limits
Implement cost limits in your application:
const MAX_COST_PER_REQUEST = 0.10; // $0.10
const MAX_COST_PER_DAY = 10.00; // $10.00
async function safeChatCompletion(messages, options) {
// Estimate cost
const estimate = await fetch('/v1/estimate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ messages, ...options })
}).then(r => r.json());
const cost = parseFloat(estimate.estimatedCost.usd);
// Check per-request limit
if (cost > MAX_COST_PER_REQUEST) {
throw new Error(`Cost $${cost} exceeds per-request limit`);
}
// Check daily limit
if (getDailyCost() + cost > MAX_COST_PER_DAY) {
throw new Error('Daily cost limit exceeded');
}
// Proceed with request
return fetchWithPayment('/v1/chat/completions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ messages, ...options })
});
}Last updated on