API

Webhooks and automation

Trigger downstream processing the moment a file arrives in TrueFTP using webhooks instead of polling.

Instead of polling directories on a timer, let TrueFTP notify your systems when something happens. Webhooks turn file events into real-time triggers for your pipelines. Webhooks are available on paid plans — configure them in the dashboard under Webhooks or via the REST API.

Events

Webhooks fire on these events:

  • file.uploaded
  • file.downloaded
  • file.deleted
  • dir.created
  • dir.deleted
  • ftp_user.created

Payload

Each delivery is a JSON POST:

{
  "event": "file.uploaded",
  "delivery_id": "f1e2…",
  "timestamp": "2026-06-08T12:00:00Z",
  "account_id": "…",
  "data": {
    "path": "/incoming/order.csv",
    "size": 20480,
    "username": "pipeline",
    "client_ip": "203.0.113.5"
  }
}

Headers

HeaderDescription
X-TrueFTP-EventEvent type
X-TrueFTP-DeliveryUnique delivery id
X-TrueFTP-TimestampUnix seconds (signed)
X-TrueFTP-Signaturesha256= HMAC of the payload

Verifying the signature

The signature is HMAC-SHA256(secret, timestamp + "." + rawBody) — verify it over the raw request body before parsing:

import crypto from "crypto"
 
app.post("/hooks/trueftp", express.raw({ type: "application/json" }), (req, res) => {
  const ts = req.header("X-TrueFTP-Timestamp")
  const signed = `${ts}.` + req.body // req.body is a Buffer (raw)
  const expected =
    "sha256=" + crypto.createHmac("sha256", process.env.TRUEFTP_WEBHOOK_SECRET)
      .update(signed).digest("hex")
 
  const got = req.header("X-TrueFTP-Signature") || ""
  if (got.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected))) {
    return res.sendStatus(401)
  }
 
  const { event, data } = JSON.parse(req.body)
  if (event === "file.uploaded" && data.path.startsWith("/incoming/")) {
    enqueueProcessing(data.path)
  }
  res.sendStatus(200)
})

Delivery, retries & logs

  • Deliveries retry with exponential backoff (default 3 attempts) on non-2xx or timeout.
  • Each attempt is recorded — view recent deliveries (status, attempt, error) in the dashboard or via GET /api/ext/v1/webhooks/{id}/deliveries.
  • Respond 2xx quickly and do heavy work asynchronously.

Patterns

  • EDI translation: kick off your translator when a partner drops a file.
  • Media ingest: start transcoding the instant a master lands.
  • Backup verification: alert when an expected nightly backup doesn't arrive.

Reliability tips

  • Respond 2xx quickly and do heavy work asynchronously.
  • Make handlers idempotent — process the same file path safely more than once.
  • Combine with the audit log to reconcile what was delivered.