Errors & Rate Limits
HTTP status codes, error shapes, rate limiting, and credit error handling for the NexGate API.
Error format
All NexGate API errors follow the OpenAI-compatible error shape so any existing error-handling code works without changes. code is the HTTP status as a string.
{
"error": {
"message": "Insufficient credits. Available: $0.0020. Estimated cost: $0.0050. Top up at https://dashboard.nexgate.app/topup",
"type": "insufficient_credits",
"code": "402"
}
}HTTP status codes
| Code | error.type | Meaning |
|---|---|---|
200 | — | Request succeeded |
400 | invalid_request_error | Bad JSON, non-object body, schema validation failure, unknown or disabled model |
401 | authentication_error | Missing bearer token, invalid API key, or account record not found |
402 | insufficient_credits | Balance cannot cover the estimated request ceiling |
403 | permission_error | Account is banned or deleted |
405 | invalid_request_error | Method not allowed — only POST is accepted |
413 | invalid_request_error | Request body exceeds 64KB |
429 | rate_limit_error | Hourly spend safety limit or a per-key limit was reached |
502 | provider_error | Upstream model request failed |
Credit errors
These occur on the /v1/chat/completions endpoint when your credit balance is too low to complete the request.
error.type | When |
|---|---|
insufficient_credits | Balance is too low to cover the estimated request ceiling before the call starts |
insufficient_credits | Balance dropped below the streaming ceiling mid-request |
Note
NexGate reserves the estimated maximum cost before the call and checks the balance again during streaming. A request that starts successfully can still stop mid-stream if your balance is exhausted; the unused reservation is then released.
Rate limits
NexGate does not impose a fixed requests-per-minute cap. Instead, throughput is bounded by spend-based limits you control:
| Limit | Scope | Default |
|---|---|---|
| Hourly spend safety limit | Account-wide ($/hour) | Configurable in Settings; -1 = unlimited |
| Per-key hourly spend limit | Individual API key ($/hour) | Optional, off unless set |
| Per-key hourly request limit | Individual API key (requests/hour) | Optional, off unless set |
When any limit is reached, completions return 429:
{
"error": {
"message": "Spend safety limit reached ($10/hr). Used: $10.0100 in the last hour. Adjust your limit in the dashboard.",
"type": "rate_limit_error",
"code": "429"
}
}Spend safety limit
You can configure an hourly spend cap from the dashboard under Settings → Spend Safety Limit. When the cap is reached, completions return 429 with type rate_limit_error. Set the limit to -1 to disable it (unlimited spend). Per-key spend and request limits can be set when creating or editing a key.
Model not found
If you request a model that NexGate does not serve (or that is currently disabled), the API returns 400:
{
"error": {
"message": "Model \"some-model\" is not available",
"type": "invalid_request_error",
"code": "400"
}
}Check the full list of available models at Models.
Handling errors in code
Python
import openai
client = openai.OpenAI(
api_key="ng-...",
base_url="https://api.nexgate.app/v1"
)
try:
response = client.chat.completions.create(
model="gpt-4.1-mini",
messages=[{"role": "user", "content": "Hello"}]
)
except openai.APIStatusError as e:
if e.status_code == 402:
print("Out of credits — top up at dashboard.nexgate.app")
elif e.status_code == 429:
print("Spend safety limit or per-key limit reached")
else:
print(f"API error {e.status_code}: {e.message}")TypeScript
import OpenAI, { APIError } from "openai";
const client = new OpenAI({
apiKey: "ng-...",
baseURL: "https://api.nexgate.app/v1",
});
try {
const response = await client.chat.completions.create({
model: "gpt-4.1-mini",
messages: [{ role: "user", content: "Hello" }],
});
} catch (e) {
if (e instanceof APIError) {
if (e.status === 402) {
console.error("Out of credits — top up at dashboard.nexgate.app");
} else if (e.status === 429) {
console.error("Spend safety limit or per-key limit reached");
} else {
console.error(`API error ${e.status}: ${e.message}`);
}
}
}