> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agent-drop.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent-to-Human Transfers: Files for Non-Agent Recipients

> Send files from your agent to a human's email. Includes email verification, receive password protection, and end-to-end encryption with browser-side decryption.

<Note>
  **Audience: AI agent / developer.** This guide is written for agents sending files to a human recipient's email address.
</Note>

Send files directly to a recipient's email address. The recipient receives an email notification, follows the link to a download page, and retrieves the files. If the recipient has set a receive password, files are end-to-end encrypted and decrypted entirely in their browser.

***

## How It Works

<Steps>
  <Step title="Agent sends files">
    Your agent calls `send()` with the human's email address and `mode: 'agent-to-human'`. AgentDrop stores the files and sends an email notification.
  </Step>

  <Step title="Human receives email">
    The human gets an email from AgentDrop with the sender name, file list, message, and a "Download Files" button.
  </Step>

  <Step title="Human clicks the link">
    Clicking the link opens the download page at `/d/[transfer_id]`. This also verifies the human's email address automatically.
  </Step>

  <Step title="Password prompt (if encrypted)">
    If the human has set a receive password in their dashboard settings, they enter it to unlock decryption. Without a receive password, files download directly (unencrypted).
  </Step>

  <Step title="Browser-side decryption and download">
    The human's browser decrypts the files locally using the receive password. The server never sees the plaintext. Files download to the human's device.
  </Step>
</Steps>

***

## Sending Files to a Human

Use the human's email address as the recipient. The SDK and MCP server auto-detect agent-to-human mode when the recipient is an email address.

<CodeGroup>
  ```javascript Node.js theme={null}
  import { AgentDrop } from 'agentdrop-sdk';

  const client = new AgentDrop({ apiKey: 'agd_your_api_key' });

  // Send files to a human by email
  const result = await client.send('user@example.com', ['report.pdf', 'data.csv'], {
    message: 'Here are the Q1 results you requested',
    mode: 'agent-to-human',
    expiresIn: '7d',
  });

  console.log(`Transfer ID: ${result.id}`);
  console.log(`Encrypted: ${result.is_encrypted}`);
  ```

  ```python Python theme={null}
  from agentdrop import AgentDrop

  client = AgentDrop(api_key="agd_your_api_key")

  # Send files to a human by email
  result = client.send("user@example.com", ["report.pdf", "data.csv"],
      message="Here are the Q1 results you requested",
      mode="agent-to-human",
      expires_in="7d",
  )

  print(f"Transfer ID: {result['id']}")
  print(f"Encrypted: {result['is_encrypted']}")
  ```
</CodeGroup>

### MCP Server

When using the MCP server, use `send_file` with the human's email address as the recipient. The MCP server auto-detects agent-to-human mode.

```
Send report.pdf and data.csv to user@example.com with message "Here are the Q1 results"
```

The `send_file` MCP tool accepts `mode: 'agent-to-human'` explicitly, but auto-detection works when the recipient is a valid email address.

<Warning>
  **Bundle files into a single transfer.** Each transfer counts against your monthly allowance. Pass all files in one call instead of sending them one at a time.
</Warning>

***

## What the Human Receives

The human receives an email from AgentDrop containing:

* **Sender name**: your agent's name and account
* **File list**: names and sizes of all files in the transfer
* **Message**: the optional message you attached
* **Expiry**: when the transfer expires
* **"Download Files" button**: links to the download page

The email is sent immediately after the transfer is created.

***

## Email Verification

When the human clicks the "Download Files" link in the email, their email address is verified automatically. This happens transparently, no extra steps required.

If the human navigates directly to the download page URL without clicking through the email, they see an "Email Verification Required" prompt. They need to click the link in their email to verify first.

<Note>
  Email verification is per-transfer. It confirms that the person downloading the files is the intended recipient.
</Note>

***

## Receive Password

The receive password is the key to encrypted agent-to-human transfers. Without it, files transfer unencrypted.

### What it does

When a human sets a receive password in their dashboard:

1. AgentDrop generates a **receive keypair** (X25519) for the human
2. The private key is encrypted with the receive password (AES-256-GCM derived via PBKDF2)
3. The public key is stored on the server
4. When an agent sends files to that human, the server encrypts files using the human's public key
5. On download, the human's browser uses the receive password to unlock the private key and decrypt files locally

### How to set it

**Tell the account holder:** "Go to your AgentDrop dashboard settings and set a receive password before I send you files."

The human sets it at: **Dashboard -> Settings -> Receive Password**

### What happens without it

If the human has NOT set a receive password:

* Transfers go through **unencrypted**
* Files are stored as plaintext on AgentDrop servers
* Downloads work normally, but there is no end-to-end encryption

<Warning>
  Without a receive password, agent-to-human transfers are NOT end-to-end encrypted. The server can see file contents. Always recommend the account holder sets a receive password before you send sensitive files.
</Warning>

***

## Download Page

When the human clicks the email link, they land on the download page at `/d/[transfer_id]`.

### What the page shows

* **Sender**: which agent sent the files
* **File list**: names, sizes, and content types
* **Message**: the optional message from the agent
* **Expiry**: when the transfer expires and files are deleted

### Page states

| State                        | What the human sees                                                          |
| ---------------------------- | ---------------------------------------------------------------------------- |
| Email not verified           | "Email Verification Required", prompts them to click the link in their email |
| Verified + password required | Password input field + "Unlock & Download" button                            |
| Verified + no password       | Direct "Download" button for each file                                       |
| Transfer expired             | "This transfer has expired" message                                          |
| Transfer deleted             | "Transfer not found" message                                                 |

### Encrypted download flow

When the human enters their receive password:

1. Browser derives the decryption key from the password (PBKDF2)
2. Browser unlocks the private key stored in the transfer metadata
3. Browser performs ECDH key exchange with the ephemeral public key
4. Browser derives the AES-256-GCM key via HKDF-SHA256
5. Browser decrypts each file
6. Decrypted files download to the human's device

The server never sees the plaintext or the receive password. All decryption happens in the browser.

***

## Dashboard Inbox

Humans can also view and download agent-to-human transfers from their dashboard, not just from the email link.

**Dashboard -> Inbox -> My Inbox** shows:

* All agent-to-human transfers sent to their email
* Transfer status (active, expired, downloaded)
* File list, sizes, and sender info
* Same password prompt for encrypted transfers
* Verified/Unverified badges per transfer

This is useful when the human wants to re-download files or manage multiple transfers.

***

## Encryption Details

For agents that want to understand the cryptographic flow.

### How agent-to-human encryption works

| Step                        | What happens                                                                            | Where               |
| --------------------------- | --------------------------------------------------------------------------------------- | ------------------- |
| Human sets receive password | Keypair generated, private key encrypted with password                                  | Dashboard (browser) |
| Agent sends files           | Server generates ephemeral X25519 keypair                                               | Server              |
| ECDH key exchange           | Ephemeral private key + human's receive public key -> shared secret                     | Server              |
| Key derivation              | HKDF-SHA256 with random salt -> AES-256-GCM key                                         | Server              |
| File encryption             | Each file encrypted with AES-256-GCM using unique IV                                    | Server              |
| Storage                     | Encrypted blobs stored; ephemeral private key discarded                                 | Server              |
| Human downloads             | Password -> unlock private key -> ECDH with ephemeral public key -> HKDF -> AES decrypt | Browser             |

### Key points

* **Server generates an ephemeral keypair per transfer**: the private half is used only during encryption, then discarded
* **The human's receive private key never leaves their browser**: it is stored encrypted and only unlocked with the password
* **HKDF-SHA256 with a random salt** ensures each transfer gets a unique encryption key, even with the same participants
* **AES-256-GCM** provides both confidentiality and authenticity for each file
* **The server sees plaintext only during the encryption step**: after encryption, only the human can decrypt

<Note>
  This is different from agent-to-agent encryption, where both sides have SDK keys and the server never sees plaintext at all. Agent-to-human encryption is a hybrid model: the server encrypts on behalf of the agent, and the human's browser decrypts.
</Note>

***

## Error Codes

| Code                 | Meaning                                             |
| -------------------- | --------------------------------------------------- |
| `INVALID_RECIPIENT`  | The email address is not valid                      |
| `TRANSFER_EXPIRED`   | The transfer has passed its expiry time             |
| `EMAIL_NOT_VERIFIED` | The human hasn't clicked through the email link yet |
| `DECRYPTION_FAILED`  | Wrong receive password or corrupted transfer data   |
| `PLAN_LIMIT_REACHED` | Monthly transfer limit exceeded                     |

***

## Checklist for Agents

Before sending files to a human, verify:

1. You have the human's correct email address
2. Ask the human to set a **receive password** in Dashboard -> Settings (for encryption)
3. Bundle all files into a single transfer
4. Set an appropriate expiry (`expiresIn`), default is 24 hours
5. Include a descriptive message so the human knows what the files are

After sending:

1. Share the transfer ID with the human for reference
2. Let them know to check their email for the download link
3. If they don't see the email, suggest checking spam/junk folders

***

## Related Pages

* [Node.js SDK](/guides/node-sdk), Full SDK reference with send examples
* [Python SDK](/guides/python-sdk), Python SDK reference
* [MCP Server](/guides/mcp-server), Using AgentDrop as native MCP tools
* [Encryption Reference](/guides/encryption), Agent-to-agent encryption internals
* [Connections & Pairings](/guides/connections), Cross-account trust model
