exa-common-errors
Installation
SKILL.md
Exa Common Errors
Overview
Quick reference for Exa API errors by HTTP status code and error tag. All error responses include a requestId field — include it when contacting Exa support at hello@exa.ai.
Error Reference
400 — Bad Request
| Error Tag | Cause | Solution |
|---|---|---|
INVALID_REQUEST_BODY |
Malformed JSON or missing required fields | Validate JSON structure and required query field |
INVALID_REQUEST |
Conflicting parameters | Remove contradictory options (e.g., date filters with company category) |
INVALID_URLS |
Malformed URLs in getContents |
Ensure URLs have https:// protocol |
INVALID_NUM_RESULTS |
numResults > 100 with highlights | Reduce to <= 100 or remove highlights |
INVALID_JSON_SCHEMA |
Bad schema in summary.schema |
Validate JSON schema syntax |
NUM_RESULTS_EXCEEDED |
Exceeds plan limit | Check your plan's max results |
NO_CONTENT_FOUND |
No content at provided URLs | Verify URLs are accessible |
401 — Unauthorized
# Verify your API key is set and valid
echo "Key set: ${EXA_API_KEY:+yes}"
# Test with curl
curl -s -o /dev/null -w "%{http_code}" \
-X POST https://api.exa.ai/search \
-H "x-api-key: $EXA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"test","numResults":1}'
Fix: Regenerate API key at dashboard.exa.ai.
402 — Payment Required
| Error Tag | Cause | Solution |
|---|---|---|
NO_MORE_CREDITS |
Account balance exhausted | Top up at dashboard.exa.ai |
API_KEY_BUDGET_EXCEEDED |
Spending limit reached | Increase budget in API key settings |
403 — Forbidden
| Error Tag | Cause | Solution |
|---|---|---|
ACCESS_DENIED |
Feature not available on plan | Upgrade plan or contact Exa |
FEATURE_DISABLED |
Endpoint not enabled | Check plan capabilities |
ROBOTS_FILTER_FAILED |
URL blocked by robots.txt | Use a different URL |
PROHIBITED_CONTENT |
Content blocked by moderation | Review query for policy violations |
429 — Rate Limited
// Default rate limit: 10 QPS (queries per second)
// Error response format: { "error": "rate limit exceeded" }
// Fix: implement exponential backoff
async function searchWithBackoff(exa: Exa, query: string, opts: any) {
for (let attempt = 0; attempt < 5; attempt++) {
try {
return await exa.search(query, opts);
} catch (err: any) {
if (err.status !== 429) throw err;
const delay = 1000 * Math.pow(2, attempt) + Math.random() * 500;
console.log(`Rate limited. Waiting ${delay.toFixed(0)}ms...`);
await new Promise(r => setTimeout(r, delay));
}
}
throw new Error("Rate limit retries exhausted");
}
422 — Unprocessable Entity
| Error Tag | Cause | Solution |
|---|---|---|
FETCH_DOCUMENT_ERROR |
URL could not be crawled | Verify URL is accessible and not paywalled |
5xx — Server Errors
| Code | Tag | Action |
|---|---|---|
| 500 | DEFAULT_ERROR / INTERNAL_ERROR |
Retry after 1-2 seconds |
| 501 | UNABLE_TO_GENERATE_RESPONSE |
Rephrase query (answer endpoint) |
| 502 | Bad Gateway | Retry with delay |
| 503 | Service Unavailable | Check status page, retry later |
Content Fetch Errors (per-URL status in getContents)
| Tag | Cause | Resolution |
|---|---|---|
CRAWL_NOT_FOUND |
Content unavailable at URL | Verify URL correctness |
CRAWL_TIMEOUT |
Fetch timed out | Retry or increase livecrawlTimeout |
CRAWL_LIVECRAWL_TIMEOUT |
Live crawl exceeded timeout | Set livecrawlTimeout: 15000 or use livecrawl: "fallback" |
SOURCE_NOT_AVAILABLE |
Paywalled or blocked | Try cached content with livecrawl: "never" |
UNSUPPORTED_URL |
Non-HTTP URL scheme | Use standard HTTPS URLs |
Quick Diagnostic Script
set -euo pipefail
echo "=== Exa Diagnostics ==="
echo "API Key: ${EXA_API_KEY:+SET (${#EXA_API_KEY} chars)}"
# Test basic connectivity
echo -n "API connectivity: "
HTTP_CODE=$(curl -s -o /tmp/exa-test.json -w "%{http_code}" \
-X POST https://api.exa.ai/search \
-H "x-api-key: $EXA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"connectivity test","numResults":1}')
echo "$HTTP_CODE"
if [ "$HTTP_CODE" != "200" ]; then
echo "Error response:"
cat /tmp/exa-test.json | python3 -m json.tool 2>/dev/null || cat /tmp/exa-test.json
fi
Instructions
- Check the HTTP status code from the error response
- Match the error tag to the tables above
- Apply the documented solution
- Include
requestIdfrom error responses when contacting support
Resources
Next Steps
For comprehensive debugging, see exa-debug-bundle. For rate limit patterns, see exa-rate-limits.
Weekly Installs
23
Repository
jeremylongshore…s-skillsGitHub Stars
2.1K
First Seen
Feb 18, 2026
Security Audits