Guides
Scan results
Understand the statuses and verdicts returned by the Safeput scanning pipeline.
Safeput processes uploads asynchronously. After a file reaches quarantine, its record moves through a small set of statuses that describe whether the file can be trusted by your application.
Statuses
| Status | Meaning | Recommended action |
|---|---|---|
waiting | The upload has been created or is awaiting processing. | Poll again later. |
scanning | Safeput is inspecting the quarantined object. | Keep the file unavailable. |
clean | The upload passed its configured policy at scan time. | Retrieve it while it is available. |
rejected | The file failed a security or policy check. | Show a safe, generic error. |
failed | The pipeline could not complete the scan. | Retry or ask the user to upload again. |
expired | Clean retention ended and the retained bytes were deleted. | Create a new upload if the file is needed again. |
Example response
{ "id": "7cc816f4-0e2e-4be0-9eaa-b9615a27ee52", "status": "clean", "filename": "quarterly-report.pdf", "content_type": "application/pdf", "size": "842193", "actual_size": "842193", "expires_at": "2026-08-22T14:32:08.000Z", "download_available": true, "created_at": "2026-08-19T14:32:08.000Z"}Only treat a file as available when the API reports clean and
download_available is true. A successful upload alone does not indicate
that inspection has finished, and no scanner can guarantee harmless content.
Polling guidance
For early integrations, poll the upload endpoint with a short delay and stop when the record reaches a final status. Webhooks are planned for applications that need event-driven updates.
const response = await fetch(`https://dev.safeput.dev/v1/uploads/${uploadId}`, { headers: { Authorization: `Bearer ${process.env.SAFEPUT_API_KEY}` },});const { upload } = await response.json();
if (upload.status === "clean" && upload.download_available) { // Request a temporary retrieval URL from your trusted backend.}Last updated Aug 19, 2026