Last updated: 2026-04-12
Error Handling & Fallback
How to handle errors and build resilient integrations with SpendLil.
SpendLil is designed so your AI never goes down because of us. Here's how errors work and how to handle them.
Response Headers
text Successful tracked response
X-SpendLil-Route: governed
X-SpendLil-Request-Id: a1b2c3d4-... Error Scenarios
| Scenario | HTTP Status | What Happens |
|---|---|---|
| Missing X-SpendLil-Key | 400 | MISSING_SPENDLIL_KEY — add the header |
| Missing X-Provider-Key | 400 | MISSING_AUTH — pass your provider key |
| Invalid SpendLil key | 401 | INVALID_SPENDLIL_KEY — check your sl_ key |
| Account inactive | 403 | ACCOUNT_INACTIVE — check billing |
| Provider returns error | Provider's status | Error passed through unmodified |
| Provider unreachable | 502 | PROVIDER_ERROR — retry or fall back |
| SpendLil logging fails | Provider's status | Request succeeds, tracking gap only |
Building a Fallback
To fall back, swap the gateway subdomain back to the provider's direct URL and use the standard Authorization header instead of X-Provider-Key.
javascript Fallback pattern (Node.js)
async function callAI(messages) {
const body = JSON.stringify({ model: 'gpt-4o', messages });
const apiKey = process.env.OPENAI_API_KEY;
try {
// Try via SpendLil
const res = await fetch('https://openai.gateway.spendlil.ai/v1/chat/completions', {
method: 'POST',
headers: {
'X-SpendLil-Key': process.env.SPENDLIL_KEY,
'X-Provider-Key': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body,
signal: AbortSignal.timeout(30000),
});
if (res.ok) return res.json();
if (res.status < 500) throw new Error(`SpendLil: ${res.status}`);
} catch (err) {
if (err.message?.startsWith('SpendLil:')) throw err;
console.warn('SpendLil unavailable, calling OpenAI directly');
}
// Fallback: call OpenAI directly
const res = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body,
});
return res.json();
}