Skip to content

Errors

When a request fails, the API returns a JSON response with an error field and an appropriate HTTP status code.

All error responses use the same structure:

{
"error": "Human-readable error message"
}

The error field contains a description of what went wrong. The HTTP status code indicates the error category.

HTTP StatusError TypeDescription
400ValidationErrorThe request is malformed or missing required fields.
401InvalidApiKeyErrorThe API key is missing, malformed, or has been revoked.
404ScanNotFoundErrorNo scan exists with the given ID.
429QuotaExceededErrorMonthly scan quota exhausted (free plan only).
502UpstreamErrorAn internal scan engine failed or timed out.

The request body is missing required fields or contains invalid values.

{
"error": "webhook_url is required"
}
{
"error": "Invalid scan_types"
}
{
"error": "metadata must be a valid JSON object"
}
CauseFix
Missing webhook_url in scan requestAdd the webhook_url field. It is required for all scan submissions.
Invalid scan_types valueUse only "virus" and/or "nsfw" in the array.
Malformed JSON bodyEnsure the request body is valid JSON when using Content-Type: application/json.
metadata too largeKeep metadata under 4 KB.
Missing file field in multipart requestInclude the file field when using multipart form upload.

The API key is not valid.

{
"error": "Invalid or missing API key"
}
CauseFix
No x-api-key headerAdd the x-api-key header to every request.
Typo in the API keyCopy the full key from Settings in the dashboard. Keys are 36 characters starting with fs_live_.
Key was regeneratedIf you regenerated your key, the old one is permanently revoked. Use the new key.
Using the wrong header nameThe header must be x-api-key, not Authorization, api-key, or X-Api-Key. Header names are case-sensitive.

Verify your key works by calling the usage endpoint:

Terminal window
curl -v https://api.filesafety.dev/v1/usage \
-H "x-api-key: YOUR_API_KEY"

If this returns 200, your key is valid. If it returns 401, the key itself is the problem.


The scan ID does not match any existing scan.

{
"error": "Scan not found"
}
CauseFix
Typo in the scan IDScan IDs start with scn_ followed by a ULID. Double-check the full ID.
Using a scan ID from a different accountScan IDs are scoped to your API key. You cannot access scans from other accounts.
Scan ID was never createdEnsure the POST /v1/scan request succeeded before polling.

Your free plan scan quota has been reached for the current billing period.

{
"error": "Quota exceeded"
}

This error only occurs on the free plan, which has a hard limit of 10 scans per month. When the quota is reached, scan submissions are blocked until the billing period resets.

Paid plans do not return 429. Instead, scans beyond the quota are allowed and billed as overage at $0.01 per scan.

OptionHow
Wait for resetYour quota resets on the first of each month (free plan) or your billing date (paid plans).
Upgrade your planGo to the dashboard and select a paid plan. The upgrade takes effect immediately.
Check your usageCall GET /v1/usage to see how many scans remain.

An internal scan engine encountered an error while processing your file.

{
"error": "Scan engine unavailable"
}

This is a server-side error. It means the ClamAV or Rekognition engine failed to return a result for your file. The scan will have a failed verdict.

ActionDetails
Retry the scanSubmit the same file again. Transient failures typically resolve on retry.
Check scan resultPoll GET /v1/scan/{id} — the scan may have partially completed.
Contact supportIf the error persists across multiple retries, contact support with the scan ID.

const res = await fetch("https://api.filesafety.dev/v1/scan", {
method: "POST",
headers: { "x-api-key": process.env.FILESAFETY_API_KEY },
body: formData,
});
if (!res.ok) {
const { error } = await res.json();
switch (res.status) {
case 400:
throw new Error(`Bad request: ${error}`);
case 401:
throw new Error("Invalid API key. Check your FILESAFETY_API_KEY.");
case 429:
throw new Error("Quota exceeded. Upgrade your plan.");
case 502:
console.warn("Upstream error, retrying...");
break;
default:
throw new Error(`Unexpected error (${res.status}): ${error}`);
}
}
response = requests.post(
"https://api.filesafety.dev/v1/scan",
headers={"x-api-key": os.environ["FILESAFETY_API_KEY"]},
files={"file": open("document.pdf", "rb")},
data={"webhook_url": "https://your-app.com/webhooks/filesafety"},
)
if response.status_code != 200:
error = response.json()["error"]
if response.status_code == 401:
raise Exception("Invalid API key")
elif response.status_code == 429:
raise Exception("Quota exceeded — upgrade your plan")
elif response.status_code == 502:
print(f"Upstream error: {error}. Retrying...")
else:
raise Exception(f"API error ({response.status_code}): {error}")