"Run code when a file is uploaded" usually means a watcher process, an inotify hack, or a cron job scanning a directory. All of them add lag and moving parts. FTPasHTTPS flips it around: the upload itself is the trigger. Because the server is virtualized, the bytes are already in flight over HTTP by the time the transfer completes — your webhook is the event, not an afterthought. This guide shows how to wire it up and handle the event reliably.
How upload-triggered webhooks work
There is no directory being watched. The trigger is the upload stream itself, which maps onto an outbound HTTPS request.
- A client uploads a file over FTP, FTPS, or SFTP to a user on your FTPasHTTPS server.
- As the bytes arrive, FTPasHTTPS opens a signed HTTPS
POSTto your webhook URL and streams them into the body. - Your handler runs immediately — index the file, kick off a job, notify a queue, whatever you need.
- Return HTTP 200 and the client sees
226 Transfer complete; return 5xx and it sees451 Action abortedand retries. - Failed deliveries retry with exponential backoff, then land in a dead-letter queue, all captured in the audit log.
Config & example event payload
One webhook covers every protocol. You can also fan out to a storage destination at the same time:
server.config# Fire a webhook on every upload, any protocol protocols: [FTP, FTPS, SFTP] # one server, all three on_upload: webhook: url: https://hooks.example.com/file-uploaded sign_with: hmac-sha256 retries: 5 # exponential backoff + DLQ forward_to: s3://bucket/inbound # optional: also archive idempotency_key: file.sha256 # dedupe on retries
When any client finishes an upload, your endpoint receives this event — the raw file is the request body, the JSON below describes it:
POST https://hooks.example.com/file-uploadedContent-Type: application/octet-stream X-FTPasHTTPS-Signature: sha256=7c1e0b9a44d2... X-FTPasHTTPS-Event-Id: evt_01J9Q2K7M3 X-FTPasHTTPS-Event: file.uploaded { "event": "file.uploaded", "event_id": "evt_01J9Q2K7M3", "protocol": "SFTP", "user": "supplier-42", "file": { "name": "inventory.xml", "size_bytes": 19874, "sha256": "a1b2c3d4e5f6..." }, "forwarded_to": "s3://bucket/inbound/inventory.xml", "received_at": "2026-06-20T10:31:44Z" }
Use event_id (or file.sha256) as your idempotency key so a retried delivery is processed exactly once. Verify the HMAC signature, do your work, return 200.
FTPasHTTPS vs the DIY way
The do-it-yourself version is an SFTP server, a directory watcher or cron job, and a script that calls your code. The differences add up:
| DIY: SFTP box + cron/watcher + script | FTPasHTTPS | |
|---|---|---|
| Trigger speed | Polling delay, or fragile inotify | Fires as the upload streams |
| Partial-file races | Watcher can fire mid-write | Event fires on completed transfer |
| Idempotency | You design it | Event id + SHA-256 provided |
| Failure handling | Custom retry logic | Backoff + dead-letter queue |
| Fan-out | More scripts | Webhook + forward to S3/GCS/Azure/SFTP |
| Security | Patch SSH, secure inbox | Signed webhooks, nothing at rest |
When to use upload-triggered webhooks
- You need to run code the instant a file lands, not minutes later.
- You are replacing a directory watcher or cron job that fires on partial files.
- You accept uploads over a mix of FTP, FTPS, and SFTP and want one consistent event.
- You want to both notify your app and archive the file to object storage in one step.
- You need safe retries with idempotency keys and a dead-letter queue out of the box.
If you specifically want raw FTP uploads delivered to a single endpoint, see FTP to Webhook. For SSH-key SFTP into a REST API with inline transforms, see SFTP to API.
Handling the event reliably
Treat your webhook handler like any other event consumer. First, verify the X-FTPasHTTPS-Signature HMAC-SHA256
header against your shared secret and reject anything that fails. Second, key your processing on the event_id or
file.sha256 so that an automatic retry — triggered when your handler returns a 5xx — is deduplicated rather than
double-processed. Third, do the slow work asynchronously: acknowledge with a fast HTTP 200 to complete the FTP transfer, then
hand the file to a queue or background job so a long-running task never holds the client's connection open.
Upload-triggered webhooks are available from the Starter plan (€19/server/month) upward, and the same event fires identically across FTP, FTPS, and SFTP — with SFTP itself unlocking on Professional (€49). The Free tier (€0, no credit card, FTP-only, 100 transfers/month) is ideal for wiring up and testing your handler before you point real partners at it. As volume grows, higher tiers raise the transfer and storage limits and add transformations, PGP, dedicated IPs, and SSO.