Errors
gfin errors use HTTP status codes plus a JSON body with a stable
machine-readable error.code and human-readable error.message.
Error Shape
{
"error": {
"code": "bad_request",
"message": "research requires q=, query=, or term=.",
"next_action": "fix_request",
"request_id": "..."
}
}
Rate-limit responses also include rate_limit details:
{
"error": {
"code": "rate_limited",
"message": "Request limit exceeded."
},
"rate_limit": {
"tier": "anonymous",
"scope": "request",
"retry_after_seconds": 42
}
}
429 responses include a Retry-After header.
Common Error Codes
| HTTP status | error.code | Retry? | Meaning |
|---|---|---|---|
| 400 | bad_request | No | The request is missing a required parameter or uses an invalid shape. |
| 401 | invalid_api_key | No | The supplied API key is invalid. |
| 404 | not_found | No | The public route was not found. |
| 405 | method_not_allowed | No | The route does not support the HTTP method used. |
| 429 | rate_limited | Yes, after Retry-After | The request exceeded the current tier limit. |
| 429 | request_coalesced | Yes, after Retry-After | Another request is already refreshing the same cache key. |
| 502 | origin_response_error | Yes | The data provider returned an unusable response. |
| 502 | response_too_large | No | The response exceeded gfin's configured response-size cap. |
| 504 | origin_transport_error | Yes | gfin could not reach the data provider in time. |
Retry Guidance
Retry only errors that are explicitly temporary:
rate_limitedrequest_coalescedorigin_response_errororigin_transport_error
For 429, wait for Retry-After or rate_limit.retry_after_seconds. For 502
and 504 errors, use exponential backoff with jitter and a small retry budget.
Do not retry malformed requests. Fix request parameters instead.
SDK Behavior
Python:
from gfin import Client, GfinError, GfinRateLimitError
client = Client(contact="you@example.com")
try:
client.quote_summary("AAPL", exchange="NASDAQ")
except GfinRateLimitError:
print("retry after the rate-limit window")
except GfinError as exc:
print("request failed", exc)
TypeScript:
import { Client, GfinError, GfinRateLimitError } from "@gfin/sdk";
const client = new Client({ contact: "you@example.com" });
try {
await client.quoteSummary("AAPL", { exchange: "NASDAQ" });
} catch (error) {
if (error instanceof GfinRateLimitError) {
console.log("retry after", error.retryAfterSeconds);
} else if (error instanceof GfinError) {
console.log(error.status, error.code);
}
}
Practical Rules
- Branch on
error.code, not the text oferror.message. - Use
Retry-Afterfor 429 handling. - Treat 400-level errors as caller bugs unless the user supplied bad input.
- Show unavailable states for missing financial data instead of converting missing values to errors in your app.