API reference
Three endpoints: a fast synchronous scan, an async deep-analysis queue, and a polling endpoint. Responses follow a versioned JSON contract.
Authentication
X-API-Key (production only)
In production, direct API calls require an X-API-Key header (configured via the comma-separated API_KEYS environment variable); requests without a valid key get 401. Same-origin requests from the hosted form are exempt, and development mode is permissive.
curl -X POST https://prompt-defenders.vercel.app/api/scan \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key-here" \
-d '{"input":"test"}'Endpoint
POST /api/scan
Fast regex scan against the versioned rule pack. Input is HMAC-hashed in memory and never stored; maximum input size is 100KB (400 above it).
{
"input": "Your text to scan here",
"deepAnalysis": false
}{
"success": true,
"analysis": {
"score": 50,
"severity": "high",
"categories": ["Direct instruction override attempts"],
"advisories": [
{
"ruleId": "PI-001",
"description": "Direct instruction override attempts",
"severity": "high",
"rationale": "Common pattern in prompt injection attacks..."
}
]
},
"meta": {
"inputHash": "abc123...",
"inputLength": 45,
"rulesVersion": "1.0.2",
"timestamp": "2026-06-09T20:00:00.000Z"
}
}With "deepAnalysis": true the response also carries a queue reference:
{
"success": true,
"analysis": { "...": "same as above" },
"meta": { "...": "same as above" },
"deepAnalysis": {
"queueId": "uuid-here",
"status": "pending",
"pollEndpoint": "/api/scan/result?id=uuid-here"
}
}- Rate limit: 10 requests/minute per IP —
429when exceeded, with anX-RateLimit-Remainingheader on every response. If the rate-limit backend is unavailable, requests fail open to preserve availability. - The response shape is governed by the versioned contract at /api/scanner/schema.json, and
tests/apiScan.test.tsvalidates responses against that file in CI.
Endpoint
POST /api/scan/deep
Enqueues async deep analysis for a previously scanned input. Only the input hash and length are submitted — never raw text. Same rate limits as /api/scan.
Honest caveat: the deep-analysis worker currently uses a placeholder LLM stub; real LLM integration is a roadmap item. Treat deep results as illustrative until then.
Endpoint
GET /api/scan/result?id=<queueId>
Polls a queued deep analysis. Jobs expire after 24 hours. Response states:
202 Accepted { "success": true, "status": "pending" | "processing", ... }
200 OK { "success": true, "status": "completed", "result": { "deepScore": 75, ... } }
200 OK { "success": false, "status": "failed", "error": "Analysis failed: reason" }
404 Not Found { "success": false, "error": "Job not found. It may have expired (24 hour TTL)." }