Skip to content

POST /v1/scan

Submit a file or URL for scanning. Uploaded files are automatically deleted immediately after scanning completes. No file content is retained.

FileSafety offers two scan modes and multiple input methods:

  • Sync (POST /v1/scan) — Upload a file or send a URL, get the result in one request.
  • Async (POST /v1/scan/async) — Upload a file or send a URL, get a scan_id immediately, then poll or receive a webhook.

Requires x-api-key header. See Authentication.


FileSafety automatically determines which scans to run based on the uploaded file’s size and type. There is no scan_types parameter — all applicable scans run automatically.

File SizeMaximum Scans Applied
Up to 10 MBMalware detection + Content analysis (images) + Content analysis (text)
10 MB – 100 MBMalware detection + Content analysis (text)
100 MB – 1 GBMalware detection only
Over 1 GBRejected (file too large)

Within the size limits above, scans are further filtered by file extension to avoid unnecessary processing:

ScanFile Types
Malware detectionAll files (always runs)
Content analysis (images).jpg, .jpeg, .png, .gif, .bmp, .webp, .tiff, .tif
Content analysis (text).txt, .csv, .json, .xml, .html, .htm, .md, .log, .yaml, .yml, .pdf, .png, .jpg, .jpeg, .tiff, .tif

Files with no extension or an unrecognized extension receive all scans applicable to their size. For example, a 2 MB .zip file receives only malware detection, while a 2 MB .jpg receives malware detection, image content analysis, and text extraction (via OCR).

All scan types are included in every plan at no extra cost.


POST https://api.filesafety.dev/v1/scan

Send a file or URL and receive the full scan result in the response. The API waits for the scan to complete (typically 10–25 seconds). Best for files under ~100 MB. May timeout for very large files — use async mode if you expect long scan times.

Content-Type: multipart/form-data

FieldTypeRequiredDescription
filebinaryYesThe file to scan (up to 1 GB).
webhook_urlstringNoHTTPS URL where scan results will also be POSTed.
metadataJSON stringNoArbitrary key-value object (max 4 KB) returned with results.
Terminal window
curl -X POST https://api.filesafety.dev/v1/scan \
-H "x-api-key: fs_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345" \
-F "file=@./document.pdf"

With optional webhook and metadata:

Terminal window
curl -X POST https://api.filesafety.dev/v1/scan \
-H "x-api-key: fs_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345" \
-F "file=@./document.pdf" \
-F "webhook_url=https://your-app.com/webhooks/filesafety" \
-F 'metadata={"user_id":"usr_123"}'

Content-Type: application/json

Instead of uploading a file, send a URL. FileSafety fetches and scans the content at that URL.

FieldTypeRequiredDescription
urlstringYesThe URL to fetch and scan. Must be HTTPS.
webhook_urlstringNoHTTPS URL where scan results will also be POSTed.
metadataobjectNoArbitrary key-value object (max 4 KB) returned with results.
Terminal window
curl -X POST https://api.filesafety.dev/v1/scan \
-H "x-api-key: fs_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/files/report.pdf"}'
{
"scan_id": "scn_01HX7Z9K3M2N4P5Q6R7S8T9U0V",
"status": "complete",
"verdict": "clean",
"virus": {
"clean": true,
"signature": null
},
"nsfw": {
"clean": true,
"categories": [],
"confidence": 0.01
},
"text": {
"clean": true,
"toxic": { "labels": [], "maxScore": 0.0 },
"pii": { "entities": [], "count": 0 },
"sentiment": { "dominant": "NEUTRAL", "scores": {} }
},
"file_hash": "sha256:e3b0c44298fc1c149afbf4c8...",
"completed_at": "2025-01-15T10:30:45.123Z"
}

If the scan takes longer than ~25 seconds, the sync endpoint returns "status": "scanning" with a scan_id for polling via GET /v1/scan/{id}.

If the file was previously scanned (matched by hash), the cached result returns instantly.


POST https://api.filesafety.dev/v1/scan/async

Submit a file or URL and receive a scan_id immediately. Retrieve results by polling GET /v1/scan/{id} or providing a webhook_url. Best for large files or batch processing. Supports files up to 1 GB via direct upload or presigned URL.

Content-Type: multipart/form-data

FieldTypeRequiredDescription
filebinaryYesThe file to scan (up to 1 GB).
webhook_urlstringNoHTTPS URL where scan results will be POSTed on completion.
metadataJSON stringNoArbitrary key-value object (max 4 KB) returned with results.
Terminal window
curl -X POST https://api.filesafety.dev/v1/scan/async \
-H "x-api-key: fs_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345" \
-F "file=@./large-archive.zip" \
-F "webhook_url=https://your-app.com/webhooks/filesafety"
{
"scan_id": "scn_01HX8A1B2C3D4E5F6G7H8I9J0K",
"status": "pending",
"eta_seconds": 15
}

Content-Type: application/json

Terminal window
curl -X POST https://api.filesafety.dev/v1/scan/async \
-H "x-api-key: fs_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/files/report.pdf", "webhook_url": "https://your-app.com/webhooks/filesafety"}'
FieldTypeRequiredDescription
urlstringYesThe URL to fetch and scan. Must be HTTPS.
webhook_urlstringNoHTTPS URL where scan results will be POSTed on completion.
metadataobjectNoArbitrary key-value object (max 4 KB) returned with results.
{
"scan_id": "scn_01HX8A1B2C3D4E5F6G7H8I9J0K",
"status": "pending",
"eta_seconds": 15
}

Presigned URL (for browser or deferred uploads)

Section titled “Presigned URL (for browser or deferred uploads)”

Request a presigned upload URL without sending a file. Upload later via PUT. Best for browser-based uploads or when you need to decouple the upload from the scan request.

Content-Type: application/json

FieldTypeRequiredDescription
webhook_urlstringNoHTTPS URL where scan results will be POSTed on completion.
metadataobjectNoArbitrary key-value object (max 4 KB) returned with results.
Terminal window
curl -X POST https://api.filesafety.dev/v1/scan/async \
-H "x-api-key: fs_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345" \
-H "Content-Type: application/json" \
-d '{"webhook_url": "https://your-app.com/webhooks/filesafety"}'
{
"scan_id": "scn_01HX8A1B2C3D4E5F6G7H8I9J0K",
"status": "awaiting_upload",
"upload_url": "https://upload.filesafety.dev/scn_01HX8A1B2C3D4E5F6G7H8I9J0K?..."
}
FieldTypeDescription
scan_idstringUnique scan identifier.
statusstring"awaiting_upload" — waiting for the file.
upload_urlstringPresigned URL. PUT the file here to begin scanning. Expires in 15 minutes.
Terminal window
curl -X PUT "UPLOAD_URL_FROM_RESPONSE" \
-H "Content-Type: application/octet-stream" \
--data-binary @./document.pdf

Once the upload succeeds, scanning begins automatically. Poll GET /v1/scan/{id} for results.


FieldTypeDescription
scan_idstringUnique scan identifier.
statusstring"complete", "failed", "scanning", "pending", or "awaiting_upload".
verdictstringOne of: clean, infected, nsfw, toxic, mixed, failed.
virusobjectVirus scan result. clean: true if no threats found. signature contains the threat name if infected.
nsfwobjectContent analysis (images) result. clean: true if safe. categories lists flagged content types.
textobjectContent analysis (text) result. Includes toxicity detection, PII detection, and sentiment analysis.
file_hashstringCryptographic hash of the scanned file.
completed_atstringISO 8601 timestamp of scan completion.

StatusErrorCause
400"Invalid JSON body"Malformed JSON in request body.
400"Invalid URL"The provided URL is not a valid HTTPS URL.
401"Invalid or missing API key"Missing or invalid x-api-key header.
413"File too large"File exceeds 1 GB maximum size.
429"Monthly scan quota exceeded"Free plan quota reached. Upgrade to continue scanning.

VerdictMeaning
cleanNo threats detected.
infectedVirus or malware detected. Check virus.signature for the threat name.
nsfwExplicit or suggestive content detected. Check nsfw.categories for details.
toxicToxic or harmful text content detected. Check text.toxic for details.
mixedMultiple types of issues detected.
failedScan could not be completed. Retry the request.

Scan types are applied automatically based on file size and type. You do not need to specify them.

TypeWhat it detectsApplicable files
Malware detectionViruses, malware, trojans, ransomware, adware.All files
Content analysis (images)Explicit nudity, suggestive content, graphic violence.Images only (.jpg, .png, .gif, .bmp, .webp, .tiff)
Content analysis (text)Toxic language, PII (personal information), and sentiment.Text and document files (.txt, .csv, .json, .xml, .html, .md, .pdf, and images via OCR)

All scan types are included in every plan at no extra cost.