Safeput
Type to search documentation.

Guides

Webhooks

Receive signed, retried upload verdict events from Safeput.

Safeput can deliver a terminal upload verdict to one HTTPS endpoint per project:

text
upload.clean
upload.rejected
upload.failed

Configure the URL and subscribed events from the dashboard. The signing secret is displayed only when the endpoint is created or its secret is rotated.

Event envelope

Each request is a JSON POST with an immutable event ID:

json
{
"id": "12c09ac1-dc57-4e4f-8b43-35f7a5fdf229",
"type": "upload.clean",
"api_version": "v1",
"created_at": "2026-08-22T12:00:00.000Z",
"data": {
"upload": {
"id": "7cc816f4-0e2e-4be0-9eaa-b9615a27ee52",
"project_id": "47db67f6-8fbc-4c59-95eb-f5150e18d820",
"status": "clean",
"filename": "invoice.pdf",
"verdict": { "result": "clean", "reason_code": null, "detected_type": "application/pdf" }
}
}
}

Use the event id as an idempotency key. Safeput uses at-least-once delivery, so the same event can be received more than once.

Verify the signature

Webhook requests include:

http
Safeput-Event-Id: ...
Safeput-Event-Type: upload.clean
Safeput-Timestamp: 1787400000
Safeput-Signature: v1=<base64url-hmac>

Calculate HMAC-SHA256 with the webhook signing secret over the exact string <Safeput-Timestamp>.<raw request body>. Base64url-encode the digest without padding, prepend v1=, and compare it in constant time. Reject stale timestamps before processing the event.

Delivery behavior

Safeput accepts any 2xx response. Network errors, timeouts, 408, 429, and 5xx responses retry with increasing delays for up to eight attempts. Redirects are not followed. Other 3xx and 4xx responses fail permanently and can be retried manually from the dashboard.

The receiver must answer within 10 seconds. Return success only after your application has durably recorded the event.

Last updated Aug 22, 2026