Skip to Content
API ReferenceEstimate Cost

Estimate Cost

Estimate the cost of a chat completion request before making payment. No payment required.

Endpoint

POST /v1/estimate

Request

Headers

Content-Type: application/json

Body Parameters

FieldTypeRequiredDefaultDescription
messagesArrayYes-Array of message objects
modelStringNoanthropic/claude-3.5-sonnetAI model to use
max_tokensNumberNo4096Maximum 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_tokens value
  • 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