Deploy applications that use Exa's neural search API (api.exa.ai) to production. Covers API key management, deployment to Vercel and Docker, rate limit configuration, and caching strategies for search-heavy applications.
EXA_API_KEY environment variableexa-js SDK or REST API# Vercel
vercel env add EXA_API_KEY production
# Docker
echo "EXA_API_KEY=your-key" >> .env.production
# Cloud Run
echo -n "your-key" | gcloud secrets create exa-api-key --data-file=-
// api/search.ts
import Exa from "exa-js";
export const config = { runtime: "edge" };
export default async function handler(req: Request) {
const exa = new Exa(process.env.EXA_API_KEY!);
const { query, numResults } = await req.json();
const results = await exa.searchAndContents(query, {
type: "neural",
numResults: numResults || 5,
text: { maxCharacters: 500 }, # HTTP 500 Internal Server Error
});
return Response.json(results);
}
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000 # 3000: 3 seconds in ms
CMD ["node", "dist/index.js"]
// Search with Redis cache
import Exa from "exa-js";
import { Redis } from "ioredis";
const exa = new Exa(process.env.EXA_API_KEY!);
const redis = new Redis(process.env.REDIS_URL!);
async function cachedSearch(query: string, ttl = 3600) { # 3600: timeout: 1 hour
const cacheKey = `exa:${Buffer.from(query).toString("base64")}`;
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);
const results = await exa.searchAndContents(query, {
type: "neural",
numResults: 5,
});
await redis.set(cacheKey, JSON.stringify(results), "EX", ttl);
return results;
}
export async function GET() {
try {
const exa = new Exa(process.env.EXA_API_KEY!);
await exa.search("test", { numResults: 1 });
return Response.json({ status: "healthy" });
} catch {
return Response.json({ status: "unhealthy" }, { status: 503 }); # HTTP 503 Service Unavailable
}
}
| Issue | Cause | Solution |
|---|---|---|
| Rate limited | Too many requests | Implement caching and request queuing |
| Empty results | Query too specific | Broaden search terms |
| API key invalid | Key expired | Regenerate at dashboard.exa.ai |
| Timeout | Large content request | Reduce maxCharacters or numResults |
vercel env add EXA_API_KEY production && vercel --prod
For multi-environment setup, see exa-multi-env-setup.