# A drop box for your team

> One route on your own domain, a token per person, and a code instead of a chat upload. How to build it with s3nd, what to watch, and the full guide.

Canonical: https://www.s3nd.sh/use-cases/team-drop-box · Markdown: https://www.s3nd.sh/use-cases/team-drop-box.md · Français: https://www.s3nd.sh/fr/use-cases/team-drop-box

One route on your own domain, a token per person, and a code instead of a chat upload.

```ts
import { createBucket, createTransferHandler } from '@s3nd/core'

const tokens = new Set(process.env.DROP_TOKENS!.split(','))

export const { GET, POST, DELETE } = createTransferHandler({
  bucket: createBucket({ bucket: 'drop' }),
  expiresIn: 24 * 3600,
  raw: 'redirect', // downloads go straight from the bucket, presigned
  authorize: (request) => tokens.has(request.headers.get('authorization')?.replace('Bearer ', '') ?? ''),
})

// $ s3nd --remote https://drop.example.com/api/transfers --token $TOKEN put ./deck.pdf
```

## What is actually going on.
### The problem
Files move around a team as chat uploads and email attachments, each one a copy on somebody else’s servers. Handing everyone the bucket keys is not an option, and a shared drive is a different kind of mess.

### What s3nd does about it
Mount the transfer handler on a domain you own and pass an authorize function that checks a bearer token. Each person has a token, not a key. The CLI points at it with --remote, a browser uses the same four routes through the React hooks, and curl works too. Files land in your bucket under a code and expire on their own.

## The things that are easy to get wrong.
- **Rate-limit the lookup** — A code is a bearer token and forty bits is the whole secret. A rate limit on GET /:code is what makes guessing pointless.
- **raw: redirect for big files** — With it, a download answers 302 with a presigned URL, so the bytes never transit your server twice. Without it they stream through, which is fine for small files and expensive for large ones.
- **doctor --remote as the smoke test** — It round-trips a real transfer against the deployment and exits non-zero on failure. Put it in the deploy pipeline.

Packages: s3nd, @s3nd/cli. [Setting up a server, in full](https://doc.s3nd.sh/docs/server)
