# Quickstart: your first pay-per-view link

Get a key, check it, pick content from the vault, create a drop and find out when it sells.

A drop is a paid bundle of vault items with its own checkout page. This guide goes from a new account to a pay-per-view link you can send to a buyer. Prefer to let your AI do the typing? Use [AI setup](https://2fans.dev/docs/ai/agent-setup.md).

## 1. Get a key

Sign up at [2fans.io](https://2fans.io/signup) and complete creator verification, since uploads need an approved ID check. Upload at least one item to your vault, then open **Vault → API Connect**, press **Generate new key** and pick **Other** to make a Personal key. There's no approval step. It starts with `dpfn_`.

Keep it in an environment variable, and never paste it into a shared chat.

Shell:

```bash
export DROPFANS_API_KEY="dpfn_..."
```

## 2. Check the key

Call `GET /me`. If `username` is the account you expected, authentication works. `kycStatus` shows where the ID check stands, and `key.tier` shows which rate limit the key runs at.

curl:

```bash
curl "https://www.dropfans.io/api/external/v1/me" \
  -H "Authorization: Bearer $DROPFANS_API_KEY"
```

Node:

```javascript
const res = await fetch('https://www.dropfans.io/api/external/v1/me', {
  headers: { Authorization: 'Bearer ' + process.env.DROPFANS_API_KEY },
});
console.log(await res.json());
```

Python:

```python
import os, requests

HEADERS = {"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"}
res = requests.get("https://www.dropfans.io/api/external/v1/me", headers=HEADERS)
print(res.json()["username"])
```

Response:

```json
{
  "id": "cmawq81x40001lb04xyz12abc",
  "username": "ava",
  "name": "Ava",
  "image": "https://cdn.dropfans.io/ava/avatar.jpg",
  "accountType": "CREATOR",
  "kycStatus": "approved",
  "key": { "name": "Personal", "app": null, "tier": "personal" }
}
```

## 3. Pick content from the vault

`GET /vault` returns approved items by default. Pass `includePending=true` to see items still in review. Uploads take real minutes to clear, so poll instead of assuming they are ready.

curl:

```bash
curl "https://www.dropfans.io/api/external/v1/vault?limit=10" \
  -H "Authorization: Bearer $DROPFANS_API_KEY"
```

Node:

```javascript
const res = await fetch('https://www.dropfans.io/api/external/v1/vault?limit=10', {
  headers: { Authorization: 'Bearer ' + process.env.DROPFANS_API_KEY },
});
const { items } = await res.json();
const ids = items.slice(0, 3).map((i) => i.id);
```

Python:

```python
import os, requests

HEADERS = {"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"}
res = requests.get("https://www.dropfans.io/api/external/v1/vault?limit=10", headers=HEADERS)
ids = [i["id"] for i in res.json()["items"][:3]]
```

## 4. Create the drop

Price is in USD: `0` for free, otherwise $5 to $750. A drop takes up to 10 vault items. Use `0` while testing, because there is no sandbox or test card. A drop built from approved items is approved straight away.

curl:

```bash
curl -X POST "https://www.dropfans.io/api/external/v1/drops" \
  -H "Authorization: Bearer $DROPFANS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "name": "Beach set",
      "price": 15,
      "vaultItemIds": [
        "VAULT_ITEM_A",
        "VAULT_ITEM_B"
      ]
    }'
```

Node:

```javascript
const res = await fetch('https://www.dropfans.io/api/external/v1/drops', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer ' + process.env.DROPFANS_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "Beach set",
    "price": 15,
    "vaultItemIds": [
      "VAULT_ITEM_A",
      "VAULT_ITEM_B"
    ]
  }),
});
console.log(await res.json());
```

Python:

```python
import os, requests

res = requests.post(
    "https://www.dropfans.io/api/external/v1/drops",
    headers={"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"},
    json={
      "name": "Beach set",
      "price": 15,
      "vaultItemIds": [
        "VAULT_ITEM_A",
        "VAULT_ITEM_B"
      ]
    },
)
print(res.json())
```

Response:

```json
{
  "productId": "...",
  "buyUrl": "https://www.dropfans.io/buy/...",
  "mediaCount": 2
}
```

## 5. Send the link

The `buyUrl` works anywhere a URL goes: a DM, a chat, a link in bio. Buyers need no account. To tell buyers apart, add your own reference to the link. See [Sell on Telegram and in chats](https://2fans.dev/docs/build/telegram.md).

Link:

```text
https://www.dropfans.io/buy/{productId}?m={yourReference}
```

## 6. Find out it sold

`POST /drops/check-status` takes up to 200 product ids and returns the ones that sold. Unsold ids are simply missing. A refunded sale still reports `paid: true` here, so use `GET /earnings` for money and approved-app [webhooks](https://2fans.dev/docs/build/webhooks.md) for instant updates.

curl:

```bash
curl -X POST "https://www.dropfans.io/api/external/v1/drops/check-status" \
  -H "Authorization: Bearer $DROPFANS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
      "productIds": [
        "PRODUCT_ID"
      ]
    }'
```

Node:

```javascript
const res = await fetch('https://www.dropfans.io/api/external/v1/drops/check-status', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer ' + process.env.DROPFANS_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "productIds": [
      "PRODUCT_ID"
    ]
  }),
});
console.log(await res.json());
```

Python:

```python
import os, requests

res = requests.post(
    "https://www.dropfans.io/api/external/v1/drops/check-status",
    headers={"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"},
    json={
      "productIds": [
        "PRODUCT_ID"
      ]
    },
)
print(res.json())
```

## Next

- [Sell on Telegram and in chats](https://2fans.dev/docs/build/telegram.md): Create one drop, give each fan a personal pay-per-view link and match every sale back to the right chat.
- [Webhooks](https://2fans.dev/docs/build/webhooks.md): Set one signed endpoint for your app and react to sales, refunds, subscriptions, payouts and ID-check results.
- [Connect other people’s creators](https://2fans.dev/docs/build/connect-creators.md): Get your app approved, send creators a connect link, then validate and store the key they give you.

2fans was called Dropfans until October 2026, so the API host is still www.dropfans.io and keys still start with dpfn_.

Last updated 2026-11-02. All pages: https://2fans.dev/llms.txt.