Skip to content

Collect files into another system

Your system opens a file request, Dew emails each person their own upload link, and your system downloads what they send as soon as it arrives. This guide uses a case system collecting documents for a case as the example.

Before you start, create a service account and token with these permissions:

  • File requests: Create and manage to open requests and invite people.
  • File requests: View and download to download what people send.
  • Monitoring: File activity to find out when files arrive.
  • File requests: Delete, if your system cleans up after itself.

Email must be set up in Settings → Email, since Dew invites people by email.

curl -X POST -H "Authorization: Bearer dewsa_<token>" -H "Content-Type: application/json" -d '{"label":"Case 2291 documents","message":"Please send your signed contract and ID.","recipient_emails":["bob@example.com"],"due_at":"2026-11-15T23:59:59Z","domain":"files.example.com"}' https://files.example.com/api/file-requests

label and due_at are required. data.file_request.id is the request’s ID: store it with the case. Bob gets an email with his own upload link. The request closes at due_at, which must be within your domain’s maximum link lifetime if your admin set one.

To have the request belong to the case worker instead of the service account, so they see it in Dew and get its emails, see Act for a user. Every later call for that request then sends the same Dew-Act-As header, including the downloads below.

Read the activity feed and look for file_request.received events whose target.id is your request’s ID. Each event is one upload, with metadata.file_id (the upload’s ID), metadata.file_count and the sender in actor.email.

List the files a request received:

curl -H "Authorization: Bearer dewsa_<token>" "https://files.example.com/api/file-requests/<request_id>/files"

The files are in data.items, and data.total is how many there are. Each item has the upload’s file_id, the file’s name and path, its size, the sender_email and received_at. A person who sends several files at once makes one upload with several files. Up to 500 files come back per call; add ?offset=500 for the next 500.

Download one upload, as the file itself or as a ZIP when it holds several files:

curl -OJ -H "Authorization: Bearer dewsa_<token>" "https://files.example.com/api/file-requests/<request_id>/files/<file_id>"

Or download everything the request received as one ZIP:

curl -OJ -H "Authorization: Bearer dewsa_<token>" "https://files.example.com/api/file-requests/<request_id>/download"

Once your system has an upload, you can delete it from Dew:

curl -X DELETE -H "Authorization: Bearer dewsa_<token>" "https://files.example.com/api/file-requests/<request_id>/files/<file_id>"

To stop accepting files before the deadline, close the request:

curl -X PUT -H "Authorization: Bearer dewsa_<token>" -H "Content-Type: application/json" -d '{"closed":true}' "https://files.example.com/api/file-requests/<request_id>"

DELETE /api/file-requests/<request_id> deletes the request and every file received through it.

This script checks the activity feed every minute and saves each upload to <request_id>/<upload_id>/. It handles only the requests your system opened: when you open one, add a line to requests.txt with the request’s ID and, if you act for a user, their email (aB3dE9kQ maria@example.com). It runs on Linux or macOS, needs curl and jq, reads the token from the DEW_TOKEN environment variable, keeps its place in last_id.txt, and runs until you stop it, for example as a service.

#!/bin/sh
DEW="https://files.example.com"
TOKEN="${DEW_TOKEN:?Set DEW_TOKEN to the service account token}"
cd "$(dirname "$0")" || exit 1
touch requests.txt

while true; do
  after=$(cat last_id.txt 2>/dev/null || echo 0)
  page=$(curl -sf -H "Authorization: Bearer $TOKEN" "$DEW/api/admin/activity/feed?after_id=$after") || { sleep 60; continue; }

  # One line per event: its id, then the request and upload for files received.
  printf '%s\n' "$page" | jq -r '.data.entries[] | [(.id | tostring), (if .event_type == "file_request.received" then .target.id, .metadata.file_id else "-", "-" end)] | join(" ")' > events.txt

  failed=""
  while read -r id request upload; do
    line=$(awk -v r="$request" '$1 == r' requests.txt)
    if [ -n "$line" ]; then
      user=$(echo "$line" | awk '{ print $2 }')
      # Start each download in an empty folder, so a partial file from a failed run is replaced.
      rm -rf "$request/$upload" && mkdir -p "$request/$upload"
      if ! (cd "$request/$upload" && curl -sfOJ -H "Authorization: Bearer $TOKEN" ${user:+-H "Dew-Act-As: $user"} "$DEW/api/file-requests/$request/files/$upload"); then
        failed=yes
        break
      fi
    fi
    echo "$id" > last_id.txt
  done < events.txt

  if [ -n "$failed" ] || [ "$(printf '%s\n' "$page" | jq -r '.data.has_more')" != "true" ]; then
    sleep 60
  fi
done

A download that fails stops the run at that event. A minute later the script downloads that upload again into an empty folder.

Open the upload link from Bob’s email in a private browser window and send a test file. Within a minute the script saves it under a folder named after the request’s ID.

To check the request in Dew itself, get it by its ID, with the same Dew-Act-As header if you act for a user:

curl -H "Authorization: Bearer dewsa_<token>" "https://files.example.com/api/file-requests/<request_id>"

data.uploads lists each upload with its file_id, sender_email, file_count and received_at. When you act for a case worker, they also see the request and the file on their File requests page.

What you see What to do
403 with “This API token doesn’t have permission for this action.” Add the missing permission from the list at the top to the service account.
400 when creating a request with recipient_emails Email must be set up in Settings → Email before Dew can invite people.
The feed never shows file_request.received The request must be on one of the service account’s domains, and the service account needs Monitoring: File activity.
404 when downloading The request or upload was deleted, or belongs to a user the token isn’t acting for.

Every endpoint used here is in the File requests API reference.