Skip to content

Commit 6763e6f

Browse files
authored
Justin/ga credits (#5079)
1 parent 00bae48 commit 6763e6f

File tree

40 files changed

+1839
-715
lines changed

40 files changed

+1839
-715
lines changed

.claude/settings.local.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@
5555
"Bash(timeout:*)",
5656
"Bash(npx supabase:*)",
5757
"Bash(docker exec:*)",
58-
"WebFetch(domain:ui.shadcn.com)"
58+
"WebFetch(domain:ui.shadcn.com)",
59+
"mcp__playwright__browser_tabs",
60+
"mcp__playwright__browser_close",
61+
"Bash(psql:*)"
5962
],
6063
"deny": []
6164
},

bifrost/lib/clients/jawnTypes/private.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ export interface components {
815815
CreateCloudGatewayCheckoutSessionRequest: {
816816
/** Format: double */
817817
amount: number;
818+
returnUrl?: string;
818819
};
819820
UpgradeToProRequest: {
820821
addons?: {
@@ -16799,9 +16800,11 @@ export interface operations {
1679916800
};
1680016801
MigrateToPro: {
1680116802
responses: {
16802-
/** @description No content */
16803-
204: {
16804-
content: never;
16803+
/** @description Ok */
16804+
200: {
16805+
content: {
16806+
"application/json": unknown;
16807+
};
1680516808
};
1680616809
};
1680716810
};

bifrost/lib/clients/jawnTypes/public.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,9 @@ export interface paths {
395395
"/v1/trace/log-python": {
396396
post: operations["LogPythonTrace"];
397397
};
398+
"/v1/test/gateway-request": {
399+
post: operations["SendTestRequest"];
400+
};
398401
"/v1/session/has-session": {
399402
get: operations["HasSession"];
400403
};
@@ -2212,6 +2215,7 @@ Json: JsonObject;
22122215
CreateCloudGatewayCheckoutSessionRequest: {
22132216
/** Format: double */
22142217
amount: number;
2218+
returnUrl?: string;
22152219
};
22162220
UpgradeToProRequest: {
22172221
addons?: {
@@ -2400,6 +2404,15 @@ Json: JsonObject;
24002404
};
24012405
}[];
24022406
};
2407+
SendTestRequestResponse: {
2408+
success: boolean;
2409+
response?: string;
2410+
requestId?: string;
2411+
error?: string;
2412+
};
2413+
SendTestRequestRequest: {
2414+
apiKey: string;
2415+
};
24032416
SessionResult: {
24042417
created_at: string;
24052418
latest_request_created_at: string;
@@ -6269,9 +6282,11 @@ export interface operations {
62696282
};
62706283
MigrateToPro: {
62716284
responses: {
6272-
/** @description No content */
6273-
204: {
6274-
content: never;
6285+
/** @description Ok */
6286+
200: {
6287+
content: {
6288+
"application/json": unknown;
6289+
};
62756290
};
62766291
};
62776292
};
@@ -6503,6 +6518,21 @@ export interface operations {
65036518
};
65046519
};
65056520
};
6521+
SendTestRequest: {
6522+
requestBody: {
6523+
content: {
6524+
"application/json": components["schemas"]["SendTestRequestRequest"];
6525+
};
6526+
};
6527+
responses: {
6528+
/** @description Ok */
6529+
200: {
6530+
content: {
6531+
"application/json": components["schemas"]["SendTestRequestResponse"];
6532+
};
6533+
};
6534+
};
6535+
};
65066536
HasSession: {
65076537
responses: {
65086538
/** @description Ok */

docs/docs.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
},
2424
{
2525
"group": "AI Gateway",
26-
"tag": "EARLY ACCESS",
2726
"pages": [
2827
"gateway/overview",
2928
"gateway/provider-routing",
@@ -43,7 +42,8 @@
4342
"group": "Concepts",
4443
"pages": [
4544
"gateway/concepts/prompt-caching",
46-
"gateway/web-search"
45+
"gateway/web-search",
46+
"gateway/concepts/error-handling"
4747
]
4848
},
4949
{
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
---
2+
title: "Error Handling & Fallback"
3+
description: "How Helicone AI Gateway handles errors and automatically falls back between billing methods"
4+
---
5+
6+
Helicone AI Gateway automatically tries multiple billing methods to ensure your requests succeed. When one method fails, it falls back to alternatives and returns the most actionable error to help you fix issues quickly.
7+
8+
## How Fallback Works
9+
10+
The AI Gateway supports two billing methods:
11+
12+
<CardGroup cols={2}>
13+
<Card title="Pass-Through Billing (PTB)" icon="credit-card">
14+
Pay-as-you-go with Helicone credits. Simple, no provider account needed.
15+
</Card>
16+
<Card title="Bring Your Own Keys (BYOK)" icon="key">
17+
Use your own provider API keys. You're billed directly by the provider.
18+
</Card>
19+
</CardGroup>
20+
21+
**Automatic Fallback**: When you configure both methods, the gateway tries PTB first. If it fails (e.g., insufficient credits), it automatically falls back to BYOK.
22+
23+
---
24+
25+
## Error Priority Logic
26+
27+
When both billing methods fail, the gateway returns the **most actionable error** to help you resolve the issue:
28+
29+
### Priority Order
30+
31+
1. **403 Forbidden** → Critical access issue, contact support
32+
2. **401 Unauthorized** → Fix your provider API key
33+
3. **400 Bad Request** → Fix your request format
34+
4. **500 Server Error** → Provider issue or configuration problem
35+
5. **429 Rate Limit** → Only shown if all attempts hit rate limits
36+
37+
<Note>
38+
**Why this order?** If you configured BYOK, errors from your provider keys (401, 500) are more actionable than PTB's "insufficient credits" (429). You chose BYOK for a reason!
39+
</Note>
40+
41+
---
42+
43+
## Common Error Scenarios
44+
45+
| Error Code | What It Means | Action Required | Example |
46+
|------------|---------------|-----------------|---------|
47+
| **401** | Authentication failed | Check your provider API key in settings | Invalid OpenAI API key |
48+
| **403** | Access forbidden | Contact support@helicone.ai | Wallet suspended, model blocked |
49+
| **400** | Invalid request format | Fix your request body or parameters | Missing required field |
50+
| **429** | Insufficient credits | Add credits OR configure provider keys | No Helicone credits, no BYOK |
51+
| **500** | Upstream provider error | Check provider status or retry | Provider API timeout |
52+
| **503** | Service unavailable | Provider temporarily down, retry later | Provider maintenance |
53+
54+
---
55+
56+
## Fallback Scenarios
57+
58+
<AccordionGroup>
59+
<Accordion title="Scenario 1: PTB Succeeds">
60+
**Setup**: You have Helicone credits
61+
62+
**Result**: ✅ Request completes using Pass-Through Billing
63+
64+
**Error**: None - successful response
65+
</Accordion>
66+
67+
<Accordion title="Scenario 2: PTB Fails, BYOK Succeeds">
68+
**Setup**: No Helicone credits, but valid provider API key configured
69+
70+
**Result**: ✅ Request completes using your provider key
71+
72+
**Error**: None - successful response (PTB's 429 is hidden since BYOK succeeded)
73+
</Accordion>
74+
75+
<Accordion title="Scenario 3: PTB Fails, BYOK Fails">
76+
**Setup**: No Helicone credits, invalid/failing provider key
77+
78+
**Result**: ❌ Request fails
79+
80+
**Error Returned**: BYOK's error (401, 500, etc.) - NOT PTB's 429
81+
82+
**Why**: You configured BYOK, so we show what's wrong with your provider key rather than "insufficient credits"
83+
84+
**Example**:
85+
```json
86+
{
87+
"error": {
88+
"message": "Authentication failed",
89+
"type": "invalid_api_key",
90+
"code": 401
91+
}
92+
}
93+
```
94+
</Accordion>
95+
96+
<Accordion title="Scenario 4: No BYOK Configured, PTB Fails">
97+
**Setup**: No Helicone credits, no provider keys configured
98+
99+
**Result**: ❌ Request fails
100+
101+
**Error Returned**: 429 Insufficient credits
102+
103+
**Why**: No alternative billing method available
104+
105+
**Example**:
106+
```json
107+
{
108+
"error": {
109+
"message": "Insufficient credits",
110+
"type": "request_failed",
111+
"code": 429
112+
}
113+
}
114+
```
115+
116+
**Solutions**:
117+
1. Add Helicone credits at `/credits`
118+
2. Configure provider keys in `/settings/providers`
119+
3. Enable [automatic retries](/features/advanced-usage/retries) with `Helicone-Retry-Enabled: true` to handle transient failures
120+
121+
<Info>
122+
**Retries can help!** If you're experiencing temporary rate limits or server errors, use [Helicone retry headers](/features/advanced-usage/retries) to automatically retry failed requests with exponential backoff.
123+
</Info>
124+
</Accordion>
125+
</AccordionGroup>
126+
127+
---
128+
129+
## Understanding Error Sources
130+
131+
When you see an error, you can determine which billing method it came from:
132+
133+
**PTB Errors**:
134+
- 429: "Insufficient credits" → Add credits at `/credits`
135+
- 403: "Wallet suspended" → Contact support
136+
137+
**BYOK Errors**:
138+
- 401: "Invalid API key" → Check provider keys in `/settings/providers`
139+
- 500: "Provider error" → Check provider status
140+
- 503: "Service unavailable" → Provider having issues
141+
142+
---
143+
144+
## Best Practices
145+
146+
<CardGroup cols={2}>
147+
<Card title="Configure Both Methods" icon="shield-check">
148+
Set up both PTB and BYOK for maximum reliability. If one fails, the other serves as backup.
149+
</Card>
150+
<Card title="Monitor Credit Balance" icon="chart-line">
151+
Keep track of your Helicone credits to avoid 429 errors during critical requests.
152+
</Card>
153+
<Card title="Enable Automatic Retries" icon="rotate-cw">
154+
Use [Helicone retry headers](/features/advanced-usage/retries) to automatically retry transient errors (429, 500, 503) with exponential backoff.
155+
</Card>
156+
<Card title="Log Error Details" icon="file-text">
157+
Log the full error response to debug provider-specific issues quickly.
158+
</Card>
159+
</CardGroup>
160+
161+
---
162+
163+
## Error Handling in Code
164+
165+
<Tip>
166+
**Prefer built-in retries**: Instead of implementing your own retry logic, use [Helicone's automatic retry headers](/features/advanced-usage/retries) by adding `Helicone-Retry-Enabled: true` to your requests. This handles exponential backoff automatically.
167+
</Tip>
168+
169+
### Retry Logic Example
170+
171+
```typescript
172+
import OpenAI from "openai";
173+
174+
const client = new OpenAI({
175+
baseURL: "https://ai-gateway.helicone.ai",
176+
apiKey: process.env.HELICONE_API_KEY,
177+
});
178+
179+
async function callWithRetry(maxRetries = 3) {
180+
for (let i = 0; i < maxRetries; i++) {
181+
try {
182+
const response = await client.chat.completions.create({
183+
model: "gpt-4o-mini",
184+
messages: [{ role: "user", content: "Hello!" }],
185+
});
186+
return response;
187+
} catch (error: any) {
188+
const status = error?.status || 500;
189+
190+
// Don't retry auth errors or bad requests
191+
if (status === 401 || status === 403 || status === 400) {
192+
throw error;
193+
}
194+
195+
// Don't retry insufficient credits unless it's the last attempt
196+
if (status === 429 && i === maxRetries - 1) {
197+
throw error;
198+
}
199+
200+
// Retry transient errors (500, 503) with exponential backoff
201+
if (status >= 500 || status === 429) {
202+
await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
203+
continue;
204+
}
205+
206+
throw error;
207+
}
208+
}
209+
}
210+
```
211+
212+
### Error Classification
213+
214+
```typescript
215+
function classifyError(error: any) {
216+
const status = error?.status || 500;
217+
218+
if (status === 401) {
219+
return {
220+
type: "authentication",
221+
action: "Check your API keys in settings",
222+
retryable: false
223+
};
224+
}
225+
226+
if (status === 429) {
227+
return {
228+
type: "rate_limit",
229+
action: "Add credits or wait before retrying",
230+
retryable: true
231+
};
232+
}
233+
234+
if (status >= 500) {
235+
return {
236+
type: "server_error",
237+
action: "Retry with exponential backoff",
238+
retryable: true
239+
};
240+
}
241+
242+
return {
243+
type: "unknown",
244+
action: "Check error message for details",
245+
retryable: false
246+
};
247+
}
248+
```
249+
250+
---
251+
252+
## Related Resources
253+
254+
- [Automatic Retries](/features/advanced-usage/retries) - Configure retry headers for handling transient failures
255+
- [Provider Routing](/gateway/provider-routing) - Learn how to configure fallback providers
256+
- [Settings: Provider Keys](/settings/providers) - Add your provider API keys
257+
- [Credits](/credits) - Add Helicone credits for Pass-Through Billing
258+
259+
<Info>
260+
**Need Help?** If you're seeing unexpected errors or need assistance configuring fallback, contact us at support@helicone.ai or join our [Discord community](https://discord.com/invite/zsSTcH2qhG).
261+
</Info>

0 commit comments

Comments
 (0)