Errors
yfin errors use HTTP status codes plus a JSON body with a stable machine-readable
error.code and human-readable error.message.
Error Shape
{
"ok": false,
"error": {
"code": "bad_request",
"message": "history requires symbol=, ticker=, or a /v1/ticker/{symbol}/... route."
}
}
Rate-limit responses also include rate_limit details:
{
"ok": false,
"error": {
"code": "rate_limited",
"message": "Request limit exceeded."
},
"rate_limit": {
"tier": "anonymous",
"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. |
| 404 | not_found | No | The route was not found. |
| 404 | endpoint_not_found | No | A raw endpoint ID is not in the endpoint catalog. |
| 405 | method_not_allowed | No | The route does not support the HTTP method used. |
| 410 | endpoint_not_shipped | No | The endpoint exists in catalog history but is not currently available. |
| 429 | rate_limited | Yes, after Retry-After | The request exceeded the current tier limit. |
| 502 | data_request_failed | Yes | The data request could not be completed. |
| 503 | service_busy | Yes | The service is temporarily busy. |
| 503 | data_service_unavailable | Yes | The data service is temporarily unavailable. |
Retry Guidance
Retry only errors that are explicitly temporary:
rate_limiteddata_request_failedservice_busydata_service_unavailable
For 429, wait for Retry-After or rate_limit.retry_after_seconds. For 502
and 503 errors, use exponential backoff with jitter and a small retry budget.
Do not retry malformed requests. Fix the request parameters instead.
SDK Behavior
Python:
import yfin
from yfin import YfinError, YfinRateLimitError
try:
client.history("AAPL", period="1mo", interval="1d")
except YfinRateLimitError:
print("retry after the rate-limit window")
except YfinError as exc:
print("request failed", exc)
TypeScript:
import { Client, YfinError, YfinRateLimitError } from "@yfin/sdk";
try {
await client.history("AAPL", { period: "1mo", interval: "1d" });
} catch (error) {
if (error instanceof YfinRateLimitError) {
console.log("retry after", error.retryAfterSeconds);
} else if (error instanceof YfinError) {
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.