Sending a transfer

POST /api/transfers/:id/send

Turns a draft into a real transfer: makes the link work, starts the retention clock, and notifies everyone involved.

{
  "data": {
    "id": 12,
    "token": "3f9a…",
    "status": "sent",
    "expiresAt": "2026-09-01T10:00:00.000Z",
    "downloadUrl": "https://transfer.example.com/d/3f9a…",
    "recipientCount": 2,
    "notified": 2
  }
}

The retention clock starts here

Not at creation. An upload that took an hour should not eat an hour of the recipient's download window, so the expiry is rewritten when the transfer actually goes out.

Mail is best-effort

Once the row says sent, the files are live and downloadable. If an SMTP server refuses a message, that is reported rather than rolled back — undoing a completed upload because a mail server hiccuped would be the worse failure.

Compare notified against recipientCount. If it is lower, some recipients did not get their e-mail and you should pass the downloadUrl on yourself.

Idempotent

A second call answers 409 TRANSFER_ALREADY_SENT rather than mailing everyone twice. A double-clicked button, or a retrying script, cannot spam your recipients.

Requirements

  • The transfer must have at least one file, or 400 NO_FILES.
  • It must be yours, or 404.

A transfer with no recipients sends normally: nothing is e-mailed, not even a receipt, and the response hands you the link to pass on yourself.