Which‑LLM: Outcome‑Driven Decision Optimizer
Overview
Use this skill when you need to pick a recommended LLM model under clear constraints like budget and minimum quality, based on a natural-language goal.
You’ll get a single recommended model plus an ordered fallback plan you can follow if the first choice fails.
How it works
Ask for a decision: send
goal+ constraints toPOST /decision/optimize.Get an answer: receive
recommended_modeland (when available) afallback_plan.Earn discounts: after you execute the choice, report the outcome to
POST /decision/outcometo receive a credit token you can apply to future paid calls.
Quick Reference
API Base URL: https://api.which-llm.com
Homepage: https://which-llm.com
Skill Files: skills/decision-economic-optimizer/SKILL.md, skills/decision-economic-optimizer/skill.json
Supported Chains: Base (8453), Ethereum (1), Arbitrum (42161), Optimism (10), Avalanche (43114)
Single-line Use Cases:
Pick the cheapest LLM that meets quality requirements
Get a fallback plan when your first choice fails
Optimize model selection for specific tasks (summarize, extract, classify, coding)
Earn discounts by reporting actual execution outcomes
Prerequisites
Before using this skill, you must provide the agent with:
Dedicated EVM-compatible wallet for autonomous payments (separate from your main wallet)
Limited USDC balance on at least one supported chain (Base recommended for lower fees) - recommended $2-10 USDC
Native gas token for transaction fees (ETH on Base/Ethereum/Arbitrum/Optimism, AVAX on Avalanche) - recommended $3-5
Payment address verification - you must verify payment addresses from multiple independent sources before giving the agent wallet access
Important: Both USDC and gas tokens must be in the same dedicated wallet
The agent requires these credentials to autonomously:
Sign USDC transfer transactions
Query wallet balance
Send transactions to blockchain
Credential Type Options & Risk Assessment
This skill supports multiple credential formats for wallet access. Choose the option that matches your security requirements:
Option 1: Raw Private Key
Format: 64-character hex string with 0x prefix
export WALLET_PRIVATE_KEY="0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
Risk Profile:
✅ Simplest implementation - Direct signing capability
⚠️ High risk if main wallet - Full control of wallet
✅ Acceptable risk with dedicated wallet - Limited funds isolation
⚠️ Requires secure storage - Environment variable or secrets manager
Use when: You create a dedicated wallet with limited USDC + gas token specifically for this skill
Security mitigation:
MUST be a dedicated wallet (not your main wallet)
MUST contain limited funds only ($2-10 USDC + $3-5 gas token)
Gas tokens needed: ETH on Base/Ethereum/Arbitrum/Optimism, or AVAX on Avalanche
SHOULD rotate periodically (create new wallet, transfer remaining balance)
MUST NOT be committed to git or shared
Option 2: Mnemonic Phrase
Format: 12 or 24-word BIP-39 seed phrase
export WALLET_MNEMONIC="word1 word2 word3 ... word12"
Risk Profile:
⚠️ Same risk as private key - Derives private key from phrase
⚠️ Potentially higher risk - Can derive multiple accounts
✅ User-friendly backup - Easier to write down securely
Use when: You prefer mnemonic-based wallet management
Security mitigation: Same as private key + ensure only first derived account (m/44'/60'/0'/0/0) is used
Option 3: Keystore File + Password
Format: Encrypted JSON keystore file (Ethereum standard) + password
export WALLET_KEYSTORE_PATH="/path/to/keystore.json"
export WALLET_KEYSTORE_PASSWORD="your-secure-password"
Risk Profile:
✅ Encrypted at rest - Private key stored encrypted
✅ Two-factor security - Requires file AND password
⚠️ Still grants full signing - Once decrypted, same as private key
⚠️ File management overhead - Must securely store keystore file
Use when: You want encrypted private key storage with password protection
Security mitigation: Strong password + secure keystore file permissions (chmod 600)
Credential Setup
Generate a new wallet specifically for this skill (never reuse existing wallets)
Fund with limited USDC + gas token ($2-10 USDC + $3-5 gas recommended for normal usage)
- USDC amounts:
- $1 = 100 requests at $0.01 each (or ~199 with 50% credits)
- $2 = 200 requests (or ~399 with 50% credits)
- $5 = 500 requests (or ~999 with 50% credits)
- $10 = 1,000 requests (or ~1,999 with 50% credits)
- Gas token amounts: $3-5 in ETH (Base/Ethereum/Arbitrum/Optimism) or AVAX (Avalanche) for transaction fees
- Credit optimization: If you report outcomes after each decision and use the credit tokens, you get ~50% refund on all requests except the first, effectively doubling your request count
- USDC amounts:
Store private key in secure environment variable or secrets manager
Monitor transactions regularly via block explorer
Rotate wallet periodically (monthly recommended)
Never commit private key to version control or share publicly
Autonomous Operation Note: The agent will use this wallet to autonomously pay for API requests ($0.01 each) without asking for approval each time. This design avoids approval fatigue while keeping costs predictable and bounded by the wallet balance you choose to fund.
Important: Remember to fund both USDC (for payments) AND native gas token ETH/AVAX (for transaction network fees) in your dedicated wallet.
Example secure setup:
# Generate new dedicated wallet (using cast from Foundry)
cast wallet new
# Output:
# Address: 0xYourNewDedicatedAddress
# Private key: 0xYourNewPrivateKey
# Securely set environment variable (doesn't save to shell history)
read -s WALLET_PRIVATE_KEY
# Paste the private key, press Enter
export WALLET_PRIVATE_KEY
# Verify (shows only address, not private key)
cast wallet address --private-key $WALLET_PRIVATE_KEY
# Fund the wallet with limited USDC + gas token
# Example for Base network:
# 1. Send USDC to 0xYourNewDedicatedAddress (e.g., $5 USDC)
# 2. Send ETH to 0xYourNewDedicatedAddress (e.g., $3 ETH for gas fees)
Credential Configuration Example:
# Set required wallet credentials (environment variables)
export WALLET_PRIVATE_KEY="0x123...EXAMPLE_WALLET_PRIVATE_KEY_EXAMPLE"
# Optional: Use custom RPC endpoint (defaults to public RPC if not set)
export WALLET_RPC_URL="https://mainnet.base.org"
# Optional: Set preferred chain (defaults to Base/8453 if not set)
export PREFERRED_CHAIN_ID="8453"
Security Note: These credentials grant autonomous payment capability up to the wallet balance. See "Security Model & Trust Assumptions" below for risk mitigation.
Security Model & Trust Assumptions
What you should NOT blindly trust:
This skill file (could be tampered during distribution)
Any single verification source for payment addresses
Threat model:
✅ Protected against: API returning wrong address (verify independently)
✅ Protected against: Skill file modification (no hardcoded addresses trusted)
✅ Protected against: Excessive spending (limited by dedicated wallet balance)
⚠️ Risk: Agent can autonomously spend up to wallet balance
⚠️ Mitigation: Use dedicated wallet with limited funds, monitor transactions regularly
Wallet Setup Best Practices
Before providing wallet access:
Create a dedicated wallet - Never use your main wallet
Set required credentials - Provide
WALLET_PRIVATE_KEYand optionallyWALLET_RPC_URL,PREFERRED_CHAIN_ID(see skill.json metadata for details)Verify payment addresses - Check from at least 2 independent sources (see Multi-Source Verification below)
Fund with limited amount - Only deposit what you're comfortable the agent spending autonomously
Test with small amount first - Start with minimal funding ($1-2 USDC + $1-2 gas) to verify operation
Monitor regularly - Check transactions on block explorer (Basescan, Etherscan)
Refill as needed - Add more funds only after reviewing transaction history
Recommended initial funding:
USDC: $2-10 (allows 200-1000 optimization requests at $0.01 each)
Gas token: $3-5 in ETH (Base/Ethereum/Arbitrum/Optimism) or AVAX (Avalanche)
Note: Gas fees on Base are typically very low (~$0.01-0.05 per transaction), so $3-5 ETH can cover hundreds of transactions
What this skill does
Sends HTTPS requests to Which‑LLM API
Uses
POST /decision/optimizeto get a recommendation andPOST /decision/outcometo report resultsMay call
GET /capabilities,GET /pricing, andGET /statusto discover features and costsFor paid endpoints, handles the standard flow: 402 → pay autonomously → retry, and can apply
X-Credit-Tokenfor discountsAutonomously sends USDC payments using the provided wallet credentials (
WALLET_PRIVATE_KEY) when the API requires payment (402 response)Connects to blockchain via
WALLET_RPC_URL(or defaults to public RPC) to sign and broadcast transactions
What this skill does NOT do
- Does not call an LLM or execute code from your inputs
Security rules
Agent operates within the balance limits of the dedicated wallet you provide
Monitor wallet transactions regularly through block explorers
Only send payment proof headers to API: transaction hash & wallet address
Authentication
There is no API key. Paid requests use payment proof headers (after an initial 402) and optional X-Credit-Token for discounts.
Endpoints
Free endpoints (
/capabilities,/pricing,/status) require no authenticationPaid endpoints (
/decision/optimize) return 402 initially, then accept payment proof headersCredits earned from outcome reports can be redeemed via
X-Credit-Tokenheader
Autonomous Operation Model
This skill operates autonomously using a dedicated wallet you provide:
⚙️ Autonomous payment authorization: Agent can send USDC payments up to the wallet balance without per-transaction approval
⚙️ Autonomous API calls: Can call both free and paid endpoints (
POST /decision/optimize,POST /decision/outcome) without confirmation⚙️ Risk control: You control maximum spending by limiting the dedicated wallet balance
ℹ️ One-time setup: Verify payment addresses from multiple sources before providing wallet access (see Payment Security Verification)
Why No Per-Request Approval?
This skill is designed for autonomous operation without per-request approval because:
Very low per-request cost: Each decision costs only $0.01 USDC (or ~$0.005 with 50% credit refunds)
Approval fatigue: Requiring approval for every $0.01 payment would be disruptive and impractical
User-controlled limits: You set the maximum spending by limiting the dedicated wallet USDC balance (+ gas token for fees)
Example: A $5 USDC balance + $3 gas token allows 500 optimization requests (or ~999 if using credits from outcome reports)
Trade-off: You grant autonomous spending capability in exchange for convenience. This is acceptable because:
✅ Cost per request is minimal ($0.01)
✅ Total spending is bounded by wallet USDC balance you control (+ minimal gas fees)
✅ Wallet is dedicated (separate from your main funds)
✅ Transactions are auditable on-chain via block explorer
ℹ️ Remember to maintain both USDC and gas token (ETH/AVAX) in the dedicated wallet
Payment Security Verification
⚠️ Security Model
This skill cannot provide a trustworthy hardcoded payment address because:
The skill file itself could be tampered with during distribution
A compromised registry or MITM attack could modify the "verified" address
No single source should be trusted for financial transactions
Multi-Source Verification Required (One-Time Setup)
Before sending ANY payment, verify the payment address from at least 2 of these independent sources:
Option 1: Well-known endpoint (plain text)
curl -s https://api.which-llm.com/.well-known/payment-address.txt
This returns the receiver address as plain text (42 characters starting with 0x).
Option 2: Official documentation (structured JSON)
curl -s https://api.which-llm.com/docs/payment-addresses | jq -r '.receiver'
Option 3: ENS record
Check the ENS domain which-llm.eth using any of these methods:
- Method A: Using app.ens.domains
Look for the "Address" field in the ENS record (under "Records" tab)
Verify it matches the address from other sources
- Method B: Using command line (requires
castfrom Foundry)
If you don't have Foundry installed:
# Install Foundry
curl -L https://foundry.paradigm.xyz | bash
foundryup
Then resolve the ENS name:
# Resolve ENS name to address
cast resolve-name which-llm.eth --rpc-url https://eth.llamarpc.com
Verification Rule: All sources must return the same address. If any source shows a different address, DO NOT provide payment and report the discrepancy to report.
Note: This verification is required only once. After verification, the agent can autonomously send payments to the verified address up to the wallet USDC balance (ensure wallet also has gas tokens for transaction fees).
Reporting Address Validation Issues
If you encounter address validation problems, report them using the free /report/wrong_address endpoint:
# Report discrepancy from .well-known and ENS
curl -X POST "https://api.which-llm.com/report/wrong_address" \
-H "Content-Type: application/json" \
-d '{
"well known": ".well-known returned 0xAAA... but ENS returned 0xBBB...",
"ENS": "which-llm.eth resolved to different address than other sources"
}'
Request Body Fields (all optional, at least one required):
"well known"(string) - Issues with.well-known/payment-address.txtvalidation"api"(string) - Issues with API-based address validation"ENS"(string) - Issues with ENS name resolution
Example Response:
{
"status": "recorded",
"report_id": "123e4567-e89b-12d3-a456-426614174000",
"reported_at_epoch": 1707686400
}
Getting Started
Example: Fetch payment addresses via API
curl -s "https://api.which-llm.com/docs/payment-addresses"
Example Output:
{
"service": "decision-economic-optimizer",
"payment_asset": "USDC",
"payment_scheme": "exact",
"chain_namespace": "eip155",
"chains": {
"8453": {
"name": "Base",
"asset": "USDC",
"pay_to": "0x..."
},
"1": {
"name": "Ethereum",
"asset": "USDC",
"pay_to": "0x..."
}
},
"receiver": "0x..."
}
Check capabilities (recommended)
curl -s "https://api.which-llm.com/capabilities"
Example Output:
{
"service": "decision-economic-optimizer",
"deterministic": true,
"decision_version": "v1",
"supported_constraints": ["cost", "quality"],
"supported_decision_types": ["llm_model_selection"],
"endpoints": ["/decision/optimize", "/decision/outcome", "/status"],
"payment_model": "http_402",
"payment_asset": "USDC",
"payment_scheme": "exact",
"networks": [
"eip155:8453",
"eip155:1",
"eip155:42161",
"eip155:10",
"eip155:43114"
]
}
Check pricing
curl -s "https://api.which-llm.com/pricing"
Example Output:
{
"currency": "USDC",
"payment_asset": "USDC",
"payment_scheme": "exact",
"chain_namespace": "eip155",
"chains": {
"8453": "Base",
"1": "Ethereum",
"42161": "Arbitrum",
"10": "Optimism",
"43114": "Avalanche"
},
"pricing": {
"/decision/optimize": {
"price": 0.01,
"unit": "per_request"
}
}
}
Optimize a decision (paid)
The optimize endpoint uses HTTP 402 payment gating. Here's the detailed flow:
Step 1: Initial Request (Expects 402)
IDEMPOTENCY_KEY="request_$(date +%s)_001"
curl -sS -i -X POST "https://api.which-llm.com/decision/optimize" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
-d '{
"goal": "Summarize customer feedback emails into a 5-bullet executive summary",
"constraints": {
"min_quality_score": 0.8,
"max_cost_usd": 0.01
},
"workload": {
"input_tokens": 1200,
"output_tokens": 300,
"requests": 1
},
"task_type": "summarize"
}'
Request Fields:
goal(required): Natural language description of what you want to accomplishconstraints(required):min_quality_score: Minimum quality threshold (0-1)max_cost_usd: Maximum cost in USD
workload(optional): Token/pricing dimensions for accurate cost estimationinput_tokens,output_tokens(required if workload provided)requests,images,web_searches,internal_reasoning_tokens,input_cache_read_tokens,input_cache_write_tokens(optional)
task_type(optional):"summarize" | "extract" | "classify" | "coding" | "general"- helps route to task-appropriate models
Example Response (402 Payment Required):
HTTP/2 402 Payment Required
Content-Type: application/json
{
"error_code": "PAYMENT_REQUIRED",
"required_amount": "0.01",
"currency": "USDC",
"accepts": [
{
"chain": "eip155:8453",
"asset": "USDC",
"pay_to": "0x...PAY_TO_ADDRESS...123xyz",
"scheme": "exact"
},
{
"chain": "eip155:1",
"asset": "USDC",
"pay_to": "0x...PAY_TO_ADDRESS...123xyz",
"scheme": "exact"
}
],
"payment_reference": "decision_optimize_abc123",
"idempotency_key": "request_1770809000_001"
}
Step 2: Pay USDC On-Chain
⚠️ SECURITY: Payment address must be verified during initial setup (see "Payment Security Verification" section)
The agent will autonomously send an exact USDC transfer to accepts[].pay_to on the chosen chain:
Amount: exactly
required_amount(e.g.,0.01USDC)Chain: choose from
accepts[].chain(e.g.,eip155:8453for Base)Asset: USDC
The agent uses the provided wallet to sign and send the transaction
After confirmation, the transaction hash (
tx_hash) is obtained
Note: The agent autonomously signs and sends the transaction using the dedicated wallet you provided. Only the transaction hash and wallet address are sent to the API as public proof of payment.
Step 3: Retry with Payment Proof
The agent automatically retries the request with payment proof headers:
# Example of the retry request (automated by agent)
TX_HASH="0x...TRANSACTION_HASH_FROM_STEP_2"
PAYER_ADDRESS="0x...WALLET_ADDRESS_PROVIDED"
PAYMENT_CHAIN="eip155:8453"
PAYMENT_AMOUNT="0.01"
curl -sS -i -X POST "https://api.which-llm.com/decision/optimize" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
-H "X-Payment-Chain: $PAYMENT_CHAIN" \
-H "X-Payment-Tx: $TX_HASH" \
-H "X-Payer: $PAYER_ADDRESS" \
-H "X-Payment-Amount: $PAYMENT_AMOUNT" \
-H "X-Payment-Asset: USDC" \
-d '{
"goal": "Summarize customer feedback emails into a 5-bullet executive summary",
"constraints": {
"min_quality_score": 0.8,
"max_cost_usd": 0.01
}
}'
Payment Headers:
X-Payment-Chain: CAIP-2 chain ID (e.g.,eip155:8453for Base)X-Payment-Tx: Transaction hash (32 bytes, hex with0xprefix)X-Payer: Your wallet address (hex with0xprefix) - public address onlyX-Payment-Amount: Exact decimal amount matchingrequired_amountX-Payment-Asset:USDC
Security Note: These headers contain only public information (transaction hash and wallet address). The API verifies the payment by checking the on-chain transaction.
Example Response (200 Success):
HTTP/2 200 OK
Content-Type: application/json
X-Decision-Version: v1
X-Decision-Hash: 0xdef456...
{
"decision_id": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
"decision_version": "v1",
"deterministic": true,
"scoring_version": "v1.0",
"recommended_model": "openai/gpt-4o-mini",
"expected_cost": 0.008,
"expected_quality": 0.85,
"safe_to_execute": true,
"human_review_required": false,
"task_type": "summarize",
"model_metadata": {
"provider": "openai",
"model_id": "openai/gpt-4o-mini",
"name": "GPT-4o Mini",
"context_length": 128000,
"pricing": {
"prompt": 0.15,
"completion": 0.6
},
"signals": {
"is_small": true,
"is_coder": false,
"is_reasoning": false
}
},
"fallback_plan": [
{
"option_id": "anthropic/claude-3-haiku",
"reason": "NEXT_BEST"
}
],
"explainability": {
"score": 0.92,
"components": {
"cost_penalty": 0.15,
"quality_penalty": 0.05,
"goal_penalty": 0.02,
"pricing_dimensions_used": ["prompt", "completion"]
},
"discarded": false
},
"payment": {
"status": "verified",
"chain": "eip155:8453",
"tx_hash": "0x...EXAMPLE_TX_HASH",
"payer": "0x...EXAMPLE_PAYER_ADDRESS",
"amount_usdc": "0.01",
"asset": "USDC",
"receiver": "0x...PAY_TO_ADDRESS...123xyz"
},
"job_receipt": {
"receipt_version": "v1",
"receipt_id": "0xabc123...",
"eip712": {
"types": {},
"domain": {},
"message": {},
"signature": "0x..."
}
}
}
Using Credit Token (Discount):
If you have a credit token from a previous outcome, include it to reduce the required payment:
# Example token structure (base64 JWT): {"credit_id":"...","decision_id":"...","payer":"0x...","amount_usdc":"..."}
CREDIT_TOKEN="eyJ...EXAMPLE_CREDIT_TOKEN_FROM_OUTCOME_RESPONSE...xyz"
curl -sS -i -X POST "https://api.which-llm.com/decision/optimize" \
-H "Content-Type: application/json" \
-H "X-Credit-Token: $CREDIT_TOKEN" \
-d '{
"goal": "Classify customer inquiries by priority",
"constraints": {
"min_quality_score": 0.7,
"max_cost_usd": 0.015
}
}'
Possible Responses:
If credit fully covers cost → 200 response (no payment needed)
If credit partially covers → 402 with reduced
required_amount
Example Response (402 with Partial Credit):
HTTP/2 402 Payment Required
Content-Type: application/json
{
"error_code": "PAYMENT_REQUIRED",
"required_amount": "0.005",
"currency": "USDC",
"accepts": [...],
"diagnostic": {
"price_usdc": "0.01",
"credit_applied_usdc": "0.005",
"remaining_usdc": "0.005"
}
}
4. Report outcome (earn a discount)
After executing the recommended model, report what actually happened to earn a credit token (discount) for future calls.
Request:
DECISION_ID="d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90"
OUTCOME_KEY="outcome_$(date +%s)_001"
curl -sS -i -X POST "https://api.which-llm.com/decision/outcome" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $OUTCOME_KEY" \
-d '{
"decision_id": "'"$DECISION_ID"'",
"option_used": "openai/gpt-4o-mini",
"actual_cost": 0.008,
"actual_latency": 650,
"quality_score": 0.86,
"success": true
}'
Request Fields:
decision_id(required): Thedecision_idfrom the optimize responseoption_used(required): The model ID that was actually used (should matchrecommended_modelor a fallback)actual_cost(required): Actual cost in USD (≥ 0)actual_latency(required): Actual latency in milliseconds (≥ 0)quality_score(required): Quality score 0-1success(required): Boolean indicating if the task succeeded
Example Response (200 Success):
HTTP/2 200 OK
Content-Type: application/json
{
"status": "recorded",
"decision_id": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
"outcome_hash": "0xdef456789abcdef456789abcdef456789abcdef456789abcdef456789abcdef",
"refund_credit": {
"status": "issued",
"credit_id": "credit_abc123def456",
"credit_amount_usdc": 0.005,
"credit_token": "eyJ...SIGNED_JWT_TOKEN_USE_THIS_IN_X_CREDIT_TOKEN_HEADER...xyz"
}
}
Credit Token Details:
credit_token: A signed token you can use on future paid callscredit_amount_usdc: The discount amount (typically 50% of original payment, with decay over time)credit_id: Unique identifier for this credit
Using the Credit Token:
Save the credit_token and include it in future optimize requests:
# Use the credit_token value from your /decision/outcome response
CREDIT_TOKEN="eyJ...YOUR_CREDIT_TOKEN_FROM_OUTCOME_RESPONSE...xyz"
curl -sS -i -X POST "https://api.which-llm.com/decision/optimize" \
-H "Content-Type: application/json" \
-H "X-Credit-Token: $CREDIT_TOKEN" \
-d '{
"goal": "Extract key entities from support tickets",
"constraints": {
"min_quality_score": 0.75,
"max_cost_usd": 0.02
}
}'
Example Response (200 Success with Credit):
HTTP/2 200 OK
Content-Type: application/json
{
"decision_id": "f7g8h9i0-j1k2-l3m4-n5o6-p7q8r9s0t1u2",
"decision_version": "v1",
"deterministic": true,
"recommended_model": "anthropic/claude-3-haiku",
"expected_cost": 0.012,
"expected_quality": 0.78,
"safe_to_execute": true,
"human_review_required": false
}
Note: No payment was required because the credit token covered the full cost.
Credit Behavior:
Credits reduce the
required_amounton the next paid callIf credit fully covers cost → 200 response (no payment needed)
If credit partially covers → 402 with reduced
required_amountCredits decay over time (50% decay after 30 days, expires after 90 days)
Credits are single-use (redeemed after successful payment)
Credits are bound to the payer address from the original decision
Important Notes:
Credits are only issued for paid/verified decisions
Each decision can only issue one credit per payer
Troubleshooting
Common Error Codes
PAYMENT_REQUIRED (402)
Cause: Endpoint requires payment but no valid payment proof was provided.
Resolution:
Check the
required_amountandacceptsarray in the responseSend exact USDC amount to the
pay_toaddress on your chosen chainWait for transaction confirmation (1-3 blocks)
Retry request with payment proof headers
Example Error Response:
{
"error_code": "PAYMENT_REQUIRED",
"required_amount": "0.01",
"currency": "USDC",
"accepts": [
{
"chain": "eip155:8453",
"asset": "USDC",
"pay_to": "0x...PAY_TO_ADDRESS...123xyz",
"scheme": "exact"
}
],
"payment_reference": "decision_optimize_abc123"
}
PAYMENT_INVALID (402)
Cause: Payment amount doesn't match required amount, or payment verification failed.
Resolution:
Verify you sent exactly
required_amount(not more, not less)Check transaction was confirmed on-chain
Ensure you're using the correct chain (CAIP-2 format in
X-Payment-Chain)Verify payment headers match actual transaction details
PAYMENT_ALREADY_USED (402)
Cause: This transaction hash was already used for a different request.
Resolution:
Each payment transaction can only be used once
Send a new payment transaction for this request
Use
Idempotency-Keyheader to retry the same request with same payment
NO_FEASIBLE_OPTIONS (400)
Cause: No models satisfy both cost and quality constraints.
Resolution:
Check
constraint_analysisin error response for which constraint was violated moreRelax constraints: increase
max_cost_usdor decreasemin_quality_scoreReview
discarded_modelsto see which models were close to meeting requirements
Example Error Response:
{
"error_code": "NO_FEASIBLE_OPTIONS",
"constraint_analysis": {
"cost_violations": 12,
"quality_violations": 3,
"total_models_evaluated": 15
},
"discarded_models": [
{
"option_id": "openai/gpt-4",
"discard_reason": "MAX_COST"
}
],
"suggestions": {
"relax_cost": true,
"relax_quality": false
}
}
DECISION_NOT_FOUND (400)
Cause: The decision_id doesn't exist in the system.
Resolution:
Verify the
decision_idfrom your optimize responseOnly paid/verified decisions can have outcomes reported
Check for typos in the decision ID
Payment Verification Failures
Transaction not found on-chain
Symptoms: PAYMENT_INVALID error even though transaction was sent.
Resolution:
Wait longer - blockchain confirmation can take 30-60 seconds
Verify transaction was sent to correct network (Base = 8453, not Ethereum = 1)
Check transaction status on block explorer (Basescan, Etherscan)
Ensure RPC nodes are synced (occasional issue during high network congestion)
Wrong payment amount
Symptoms: PAYMENT_INVALID with diagnostic showing amount mismatch.
Resolution:
Must send exactly the
required_amountin USDC (6 decimals)Do not round or approximate - use exact value from 402 response
Check USDC balance and allowances in your wallet
Ensure wallet has sufficient gas token (ETH/AVAX) for transaction fees
Wrong recipient address
Symptoms: Transaction confirmed but API returns PAYMENT_INVALID.
Resolution:
CRITICAL: Verify you sent to the correct address from multiple sources
Check
pay_tofield in 402 responseacceptsarrayVerify address matches what's shown at
/docs/payment-addressesIf addresses don't match, DO NOT PROCEED - contact support
Credit Token Issues
CREDIT_INVALID (402)
Cause: Credit token is malformed, expired, or verification failed.
Resolution:
Check token wasn't truncated when copying
Verify token matches exactly what was returned from
/decision/outcomeCredits expire after 90 days - check
issued_at_epochin original responseEnsure you're using the token on the same payer address
CREDIT_ALREADY_USED (402)
Cause: This credit was already redeemed in a previous request.
Resolution:
Credits are single-use only
Check
redeemed_at_epochin error responseRequest new credit by reporting another outcome
Credit doesn't reduce payment amount
Symptoms: 402 response shows same required_amount even with valid credit.
Resolution:
Verify credit token is included in
X-Credit-TokenheaderCheck credit
amount_usdc- may be smaller than expected due to time decayCredits only apply to the next paid call after issuance
Ensure payer address matches the address that received the credit
Rate Limiting
RATE_LIMIT_EXCEEDED (429)
Symptoms: 429 Too Many Requests response with X-RateLimit-* headers.
Resolution:
Check
X-RateLimit-Resetheader for when limit resets (epoch timestamp)Implement exponential backoff: wait 1s, 2s, 4s, 8s between retries
Use
Idempotency-Keyto safely retry the same requestConsider using paid endpoints which have higher rate limits
Rate Limits (per minute):
/decision/optimizeunpaid: 5 requests/decision/optimizepaid: 20 requests/decision/outcome: 60 requestsPublic GET endpoints: 600 requests
Example Error Response:
{
"error_code": "RATE_LIMIT_EXCEEDED",
"retry_after_seconds": 45
}
Response Headers:
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1770809760