Error Handling
All API errors return a consistent JSON format with an HTTP status code, a success: false flag, and a human-readable error message.
Response Format
{
"success": false,
"error": "Human-readable error message"
}Always check the success field before processing the response data.
Error Codes
The request is malformed or missing required parameters.
{
"success": false,
"error": "Invalid FIPS code format. Must be 5 digits."
}Fix: Check the request body and query parameters match the API specification.
Missing or invalid API key.
{
"success": false,
"error": "Invalid or missing API key"
}Fix: Ensure your X-API-Key header contains a valid API key. Keys start with wfc_.
Your plan does not include access to this endpoint or feature.
{
"success": false,
"error": "Upgrade required. Full ROI analysis requires a paid plan."
}Fix: Upgrade your plan at /pricing to access premium features.
The requested resource does not exist.
{
"success": false,
"error": "No data found for FIPS code 99999"
}Fix: Verify the FIPS code or ZIP code is valid and exists in our dataset.
You have exceeded your rate limit for the current window.
{
"success": false,
"error": "Rate limit exceeded. Try again in 60 seconds."
}Fix: Check X-RateLimit-Reset header for when your window resets. Consider upgrading your plan for higher limits.
An unexpected error occurred on the server.
{
"success": false,
"error": "Internal server error"
}Fix: Retry with exponential backoff. If persistent, contact support.
Retry Strategy
For 429 and 500 errors, use exponential backoff:
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const res = await fetch(url, options);
if (res.ok) return res.json();
if (res.status === 429) {
const reset = res.headers.get('X-RateLimit-Reset');
const waitMs = reset
? Math.max(0, new Date(reset).getTime() - Date.now())
: Math.pow(2, i) * 1000;
await new Promise(r => setTimeout(r, waitMs));
continue;
}
if (res.status >= 500) {
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
continue;
}
// 4xx errors (except 429) are not retryable
const error = await res.json();
throw new Error(error.error || 'Request failed');
}
throw new Error('Max retries exceeded');
}Best Practices
- •Always check the
successfield before accessing response data. - •Monitor
X-RateLimit-Remainingheaders to avoid hitting rate limits. - •Use exponential backoff for retries -- never retry in a tight loop.
- •Log error responses for debugging. Include the request URL and status code.
- •Handle
403errors by checking your plan tier -- some endpoints require a paid plan.