> ## Documentation Index
> Fetch the complete documentation index at: https://www.dropfans.io/developers/llms.txt
> Use this file to discover all available pages before exploring further.

# GET /api/external/v1/links — The creator’s profile, tip and subscribe links

> The creator's shareable links in one call. Never build Dropfans URLs by hand.

- Source: https://www.dropfans.io/developers/reference/get-links
- Section: API reference
- OpenAPI: https://www.dropfans.io/developers/openapi.json

Also served at `/api/external/links` (the unversioned alias).

The creator's shareable links in one call. Never build Dropfans URLs by hand.

**Link ids (`links`).** Every link is just `https://www.dropfans.io/buy/{id}` on the web and `https://t.me/<bot>/app?startapp={id}` in Telegram. There are no parameters on the link. What it opens, the account and your app are stored with the id. `links.profile`, `links.tip` (the fan picks the amount) and `links.subscribe` (opens the subscribe sheet) are created on the first call and returned unchanged after that. For a drop, a fixed tip amount or a per-fan reference, create a link with [POST /api/external/v1/links](https://www.dropfans.io/developers/reference/create-link.md).

**Commission.** With a key that belongs to an app, a drop bought, a tip sent or a subscription started through your app's links earns your app owner commission **for life**, including every renewal of that subscription, at your app's commission rate. Every call also makes your app the account's connected CRM.

**Templates (`web`, `telegram`), deprecated.** These are unchanged and keep working. Fields ending in `Template` have placeholders to fill in: `{usd}` (whole dollars, web tip), `{cents}` (Telegram tip), `{productId}` and `{externalRef}`. A sale through a template link keeps its `externalRef`. One with an `externalRef` counts for a CRM only if it is the only app that has ever generated links for the account, its own key works the account (directly or through its agency), and the account has no personal key. Use link ids for anything new. The `telegram` block is null when the shared Dropfans bot is not configured, and so is each link's `telegram` URL. Web tip prefill: `?tip=<usd>` between $5 and $750; other amounts open the sheet unfilled.

## Authentication

`Authorization: Bearer dpfn_...` — an API key generated in the dashboard (Vault → API Connect). By default the key acts for the one account it belongs to. Missing or invalid keys return 401 `{"error":"Unauthorized","code":"unauthorized"}`.

**For a creator you manage or onboarded:** `GET /api/external/v1/creators/{creatorId}/links` — with a verified agency's own key for a creator or AI persona it manages, or your app owner's own key for an account your app onboarded (ids from GET /api/external/v1/creators). The response echoes the account acted on in `X-Dropfans-Account`. Sending `X-Dropfans-Account: <account id>` on the plain path still works but is deprecated.

## Responses

### 200

The creator’s links.

| Field | Type | Required | Description |
|---|---|---|---|
| `username` | string | yes | The creator’s @handle the links are built for. |
| `links` | object | yes | Link ids for the account — the same ids on every call. Create buy links and fixed-amount tip links with POST /api/external/v1/links. |
| `links.profile` | Link | yes | Opens the profile. |
| `links.tip` | Link | yes | Opens the tip sheet; the fan picks the amount. |
| `links.subscribe` | Link | yes | Opens the subscribe sheet. |
| `web` | object | yes | Deprecated, still served: web links built from templates with literal placeholders. Prefer `links` / POST /api/external/v1/links. |
| `web.profile` | string | yes | The creator’s public profile. |
| `web.tip` | string | yes | Opens the profile with the tip sheet open. |
| `web.tipTemplate` | string | yes | Tip link with the amount prefilled — replace `{usd}` with whole US dollars. Amounts outside the allowed range open the sheet unfilled. |
| `web.tipWithRefTemplate` | string | yes | Tip link with a per-fan reference — replace `{usd}` (use `1` to let the fan pick the amount) and `{externalRef}` (1–32 of `A-Z a-z 0-9 _ -`). It comes back on the tip (tip.paid webhook, GET /api/external/v1/tips). |
| `web.subscribe` | string | yes | Opens the profile with the subscribe sheet already on screen. |
| `web.buyTemplate` | string | yes | Checkout link for any drop — replace `{productId}` with the id from create-drop. |
| `web.buyWithRefTemplate` | string | yes | The same with a per-fan reference — replace `{externalRef}` (1–32 of `A-Z a-z 0-9 _ -`). It comes back on the order (drop.paid webhook, GET /api/external/v1/orders). |
| `telegram` | object \\| null |  | Deprecated, still served: Telegram Mini App deep links built from templates. **Null when the shared Dropfans bot is not configured.** Prefer `links` / POST /api/external/v1/links. |
| `telegram.bot` | string | yes | The shared bot username, without @. |
| `telegram.profile` | string | yes | Opens the creator’s Mini App profile. |
| `telegram.tip` | string | yes | Opens the Mini App tip sheet. |
| `telegram.tipTemplate` | string | yes | Tip prefilled — replace `{cents}` with the amount in **cents** (the web template takes dollars; this one takes cents). |
| `telegram.tipWithRefTemplate` | string | yes | Mini App tip with a per-fan reference — replace `{cents}` (`0` lets the fan pick the amount) and `{externalRef}`. **Here the reference is 1–20 of `A-Z a-z 0-9 -` (no underscore)**: it sits in front of the username, which may contain underscores, and Telegram caps the start parameter at 64 characters. |
| `telegram.subscribe` | string | yes | Opens the Mini App subscribe flow. |
| `telegram.buyTemplate` | string | yes | Mini App checkout for any drop — replace `{productId}`. |
| `telegram.buyWithRefTemplate` | string | yes | Mini App checkout with a per-fan reference — replace `{productId}` and `{externalRef}` (1–32 of `A-Z a-z 0-9 _ -`). |

```json
{
  "username": "valeria",
  "links": {
    "profile": {
      "id": "k3x9m2qa7d",
      "type": "profile",
      "url": "https://www.dropfans.io/buy/k3x9m2qa7d",
      "telegram": "https://t.me/DropfansBot/app?startapp=k3x9m2qa7d",
      "productId": null,
      "amountUsd": null,
      "externalRef": null,
      "createdAt": "2026-10-29T12:00:00.000Z"
    },
    "tip": {
      "id": "p0w8n4rt2c",
      "type": "tip",
      "url": "https://www.dropfans.io/buy/p0w8n4rt2c",
      "telegram": "https://t.me/DropfansBot/app?startapp=p0w8n4rt2c",
      "productId": null,
      "amountUsd": null,
      "externalRef": null,
      "createdAt": "2026-10-29T12:00:00.000Z"
    },
    "subscribe": {
      "id": "h5j1v9xs3e",
      "type": "subscribe",
      "url": "https://www.dropfans.io/buy/h5j1v9xs3e",
      "telegram": "https://t.me/DropfansBot/app?startapp=h5j1v9xs3e",
      "productId": null,
      "amountUsd": null,
      "externalRef": null,
      "createdAt": "2026-10-29T12:00:00.000Z"
    }
  },
  "web": {
    "profile": "https://www.dropfans.io/u/valeria",
    "tip": "https://www.dropfans.io/u/valeria?tip=1",
    "tipTemplate": "https://www.dropfans.io/u/valeria?tip={usd}",
    "tipWithRefTemplate": "https://www.dropfans.io/u/valeria?tip={usd}&m={externalRef}",
    "subscribe": "https://www.dropfans.io/u/valeria?subscribe=1",
    "buyTemplate": "https://www.dropfans.io/buy/{productId}",
    "buyWithRefTemplate": "https://www.dropfans.io/buy/{productId}?m={externalRef}"
  },
  "telegram": {
    "bot": "DropfansBot",
    "profile": "https://t.me/DropfansBot/app?startapp=p_valeria",
    "tip": "https://t.me/DropfansBot/app?startapp=t_valeria",
    "tipTemplate": "https://t.me/DropfansBot/app?startapp=pt_{cents}_valeria",
    "tipWithRefTemplate": "https://t.me/DropfansBot/app?startapp=tm_{cents}_{externalRef}_valeria",
    "subscribe": "https://t.me/DropfansBot/app?startapp=s_valeria",
    "buyTemplate": "https://t.me/DropfansBot/app?startapp=b_{productId}",
    "buyWithRefTemplate": "https://t.me/DropfansBot/app?startapp=b_{productId}_{externalRef}"
  }
}
```

## Errors

| Status | Body | When |
|---|---|---|
| 401 | `{"error":"Unauthorized","code":"unauthorized"}` | Missing or invalid API key. |
| 409 | `{"error":"Set a username first","code":"username_required"}` | The creator has no username yet. Have the creator pick a handle in their Dropfans settings, then retry. |
| 400 | `{"error":"X-Dropfans-Account must be an account id (from GET /api/external/agency/creators), not a username.","code":"invalid_account_header"}` | `X-Dropfans-Account` is not an account id. |
| 400 | `{"error":"X-Dropfans-Account names a different account than the path — send one or the other.","code":"account_mismatch"}` | Called under /v1/creators/{creatorId}/ with an `X-Dropfans-Account` naming another account. |
| 403 | `{"error":"This key cannot act for that account.","code":"account_not_managed"}` | The creator in the path (or `X-Dropfans-Account`) is one this key cannot act for: no ACCEPTED management by your agency and not an account your app onboarded (or it no longer holds a key bound to your app), a key minted for one creator, or someone is suspended, banned or deleted. An unknown id gets the same answer. |
| 403 | `{"error":"This app does not have the links API category enabled. Contact support to enable it.","code":"api_category_disabled","category":"links"}` | Your app has the Links [API category](https://www.dropfans.io/developers/concepts/api-categories.md) switched off. |

## Rate limiting

Per-key fixed windows by tier (Personal 60/min · 5,000/day; approved apps 300/min · 50,000/day; Dropfans-operated integrations exempt). Read the live values from X-RateLimit-Tier, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and their -Day variants; a 429 carries Retry-After and `{"error":"Rate limit exceeded","code":"rate_limited"}`. See [Rate limits](https://www.dropfans.io/developers/concepts/rate-limits.md).

## Code samples

### curl

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

### Node

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

### Python

```python
import os
import requests

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

## OpenAPI

```json
{
  "method": "GET",
  "path": "/api/external/v1/links",
  "operationId": "getLinks",
  "tags": [
    "links"
  ],
  "summary": "The creator’s profile, tip and subscribe links",
  "description": "The creator's shareable links in one call. Never build Dropfans URLs by hand.\n\n**Link ids (`links`).** Every link is just `https://www.dropfans.io/buy/{id}` on the web and `https://t.me/<bot>/app?startapp={id}` in Telegram. There are no parameters on the link. What it opens, the account and your app are stored with the id. `links.profile`, `links.tip` (the fan picks the amount) and `links.subscribe` (opens the subscribe sheet) are created on the first call and returned unchanged after that. For a drop, a fixed tip amount or a per-fan reference, create a link with [POST /api/external/v1/links](https://www.dropfans.io/developers/reference/create-link.md).\n\n**Commission.** With a key that belongs to an app, a drop bought, a tip sent or a subscription started through your app's links earns your app owner commission **for life**, including every renewal of that subscription, at your app's commission rate. Every call also makes your app the account's connected CRM.\n\n**Templates (`web`, `telegram`), deprecated.** These are unchanged and keep working. Fields ending in `Template` have placeholders to fill in: `{usd}` (whole dollars, web tip), `{cents}` (Telegram tip), `{productId}` and `{externalRef}`. A sale through a template link keeps its `externalRef`. One with an `externalRef` counts for a CRM only if it is the only app that has ever generated links for the account, its own key works the account (directly or through its agency), and the account has no personal key. Use link ids for anything new. The `telegram` block is null when the shared Dropfans bot is not configured, and so is each link's `telegram` URL. Web tip prefill: `?tip=<usd>` between $5 and $750; other amounts open the sheet unfilled.",
  "parameters": [
    {
      "name": "X-Dropfans-Account",
      "in": "header",
      "required": false,
      "deprecated": true,
      "description": "Deprecated: call the …ForCreator operation (/api/external/v1/creators/{creatorId}/…) instead; the header keeps working and such responses carry Deprecation and Link: rel=\"successor-version\". With a verified agency’s own key, the id of a creator or AI persona the agency manages (from GET /api/external/v1/agency/creators): the request then acts as that account, exactly as if it were sent with that account’s own key. Account ids only — usernames are refused (400 invalid_account_header). Checked on every request: the management must be ACCEPTED, nobody may be suspended, banned or deleted (else 403 account_not_managed), and the agency needs the endpoint’s permission on that account (else 403 permission_denied). Omit it to act as the key’s own account.",
      "schema": {
        "type": "string",
        "pattern": "^c[a-z0-9]{20,32}$"
      },
      "example": "cmh4v2q8k0003xy9z7w6v5u4t"
    }
  ],
  "responses": {
    "200": {
      "description": "The creator’s links.",
      "headers": {
        "X-RateLimit-Tier": {
          "description": "Rate-limit tier of the key: personal, app or first_party (first_party is unlimited).",
          "schema": {
            "type": "string",
            "enum": [
              "personal",
              "app",
              "first_party"
            ]
          }
        },
        "X-RateLimit-Limit": {
          "description": "Requests allowed per minute for this key (absent on first_party).",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Remaining": {
          "description": "Requests left in the current minute window.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Reset": {
          "description": "Epoch seconds when the minute window resets.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Limit-Day": {
          "description": "Requests allowed per UTC day for this key (absent on first_party).",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Remaining-Day": {
          "description": "Requests left in the current UTC day window.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Reset-Day": {
          "description": "Epoch seconds when the day window resets.",
          "schema": {
            "type": "integer"
          }
        },
        "X-Dropfans-Account": {
          "description": "The id of the account this request acted on — the key’s own account, or the managed account named in the X-Dropfans-Account request header. Assert it when acting for several accounts.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "username": {
                "type": "string",
                "description": "The creator’s @handle the links are built for.",
                "example": "valeria"
              },
              "links": {
                "type": "object",
                "properties": {
                  "profile": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "The link id (10 of `a-z 0-9`). Comes back as `linkId` on sales through the link.",
                        "example": "q7m2c8zk4w"
                      },
                      "type": {
                        "type": "string",
                        "description": "What the link opens.",
                        "enum": [
                          "buy",
                          "tip",
                          "subscribe",
                          "profile"
                        ],
                        "example": "buy"
                      },
                      "url": {
                        "type": "string",
                        "description": "The web link — `/buy/{id}`, no parameters.",
                        "format": "uri",
                        "example": "https://www.dropfans.io/buy/q7m2c8zk4w"
                      },
                      "telegram": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "The Telegram Mini App link (`startapp={id}`). Null when the shared Dropfans bot is not configured.",
                        "format": "uri",
                        "example": "https://t.me/DropfansBot/app?startapp=q7m2c8zk4w"
                      },
                      "productId": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "The drop of a `buy` link.",
                        "example": "cmv5tmpcm0015h4oucxkgc4ma"
                      },
                      "amountUsd": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "Fixed amount of a `tip` link; null = the fan picks.",
                        "example": null
                      },
                      "externalRef": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "Your per-fan reference, returned on the sale.",
                        "example": "tg_48213377"
                      },
                      "createdAt": {
                        "type": "string",
                        "description": "When the link was created.",
                        "format": "date-time",
                        "example": "2026-10-29T12:00:00.000Z"
                      }
                    },
                    "required": [
                      "id",
                      "type",
                      "url",
                      "createdAt"
                    ]
                  },
                  "tip": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "The link id (10 of `a-z 0-9`). Comes back as `linkId` on sales through the link.",
                        "example": "q7m2c8zk4w"
                      },
                      "type": {
                        "type": "string",
                        "description": "What the link opens.",
                        "enum": [
                          "buy",
                          "tip",
                          "subscribe",
                          "profile"
                        ],
                        "example": "buy"
                      },
                      "url": {
                        "type": "string",
                        "description": "The web link — `/buy/{id}`, no parameters.",
                        "format": "uri",
                        "example": "https://www.dropfans.io/buy/q7m2c8zk4w"
                      },
                      "telegram": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "The Telegram Mini App link (`startapp={id}`). Null when the shared Dropfans bot is not configured.",
                        "format": "uri",
                        "example": "https://t.me/DropfansBot/app?startapp=q7m2c8zk4w"
                      },
                      "productId": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "The drop of a `buy` link.",
                        "example": "cmv5tmpcm0015h4oucxkgc4ma"
                      },
                      "amountUsd": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "Fixed amount of a `tip` link; null = the fan picks.",
                        "example": null
                      },
                      "externalRef": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "Your per-fan reference, returned on the sale.",
                        "example": "tg_48213377"
                      },
                      "createdAt": {
                        "type": "string",
                        "description": "When the link was created.",
                        "format": "date-time",
                        "example": "2026-10-29T12:00:00.000Z"
                      }
                    },
                    "required": [
                      "id",
                      "type",
                      "url",
                      "createdAt"
                    ]
                  },
                  "subscribe": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "The link id (10 of `a-z 0-9`). Comes back as `linkId` on sales through the link.",
                        "example": "q7m2c8zk4w"
                      },
                      "type": {
                        "type": "string",
                        "description": "What the link opens.",
                        "enum": [
                          "buy",
                          "tip",
                          "subscribe",
                          "profile"
                        ],
                        "example": "buy"
                      },
                      "url": {
                        "type": "string",
                        "description": "The web link — `/buy/{id}`, no parameters.",
                        "format": "uri",
                        "example": "https://www.dropfans.io/buy/q7m2c8zk4w"
                      },
                      "telegram": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "The Telegram Mini App link (`startapp={id}`). Null when the shared Dropfans bot is not configured.",
                        "format": "uri",
                        "example": "https://t.me/DropfansBot/app?startapp=q7m2c8zk4w"
                      },
                      "productId": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "The drop of a `buy` link.",
                        "example": "cmv5tmpcm0015h4oucxkgc4ma"
                      },
                      "amountUsd": {
                        "type": [
                          "number",
                          "null"
                        ],
                        "description": "Fixed amount of a `tip` link; null = the fan picks.",
                        "example": null
                      },
                      "externalRef": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "Your per-fan reference, returned on the sale.",
                        "example": "tg_48213377"
                      },
                      "createdAt": {
                        "type": "string",
                        "description": "When the link was created.",
                        "format": "date-time",
                        "example": "2026-10-29T12:00:00.000Z"
                      }
                    },
                    "required": [
                      "id",
                      "type",
                      "url",
                      "createdAt"
                    ]
                  }
                },
                "required": [
                  "profile",
                  "tip",
                  "subscribe"
                ],
                "description": "Link ids for the account — the same ids on every call. Create buy links and fixed-amount tip links with POST /api/external/v1/links."
              },
              "web": {
                "type": "object",
                "properties": {
                  "profile": {
                    "type": "string",
                    "description": "The creator’s public profile.",
                    "format": "uri",
                    "example": "https://www.dropfans.io/u/valeria"
                  },
                  "tip": {
                    "type": "string",
                    "description": "Opens the profile with the tip sheet open.",
                    "format": "uri",
                    "example": "https://www.dropfans.io/u/valeria?tip=1"
                  },
                  "tipTemplate": {
                    "type": "string",
                    "description": "Tip link with the amount prefilled — replace `{usd}` with whole US dollars. Amounts outside the allowed range open the sheet unfilled.",
                    "example": "https://www.dropfans.io/u/valeria?tip={usd}"
                  },
                  "tipWithRefTemplate": {
                    "type": "string",
                    "description": "Tip link with a per-fan reference — replace `{usd}` (use `1` to let the fan pick the amount) and `{externalRef}` (1–32 of `A-Z a-z 0-9 _ -`). It comes back on the tip (tip.paid webhook, GET /api/external/v1/tips).",
                    "example": "https://www.dropfans.io/u/valeria?tip={usd}&m={externalRef}"
                  },
                  "subscribe": {
                    "type": "string",
                    "description": "Opens the profile with the subscribe sheet already on screen.",
                    "format": "uri",
                    "example": "https://www.dropfans.io/u/valeria?subscribe=1"
                  },
                  "buyTemplate": {
                    "type": "string",
                    "description": "Checkout link for any drop — replace `{productId}` with the id from create-drop.",
                    "example": "https://www.dropfans.io/buy/{productId}"
                  },
                  "buyWithRefTemplate": {
                    "type": "string",
                    "description": "The same with a per-fan reference — replace `{externalRef}` (1–32 of `A-Z a-z 0-9 _ -`). It comes back on the order (drop.paid webhook, GET /api/external/v1/orders).",
                    "example": "https://www.dropfans.io/buy/{productId}?m={externalRef}"
                  }
                },
                "required": [
                  "profile",
                  "tip",
                  "tipTemplate",
                  "tipWithRefTemplate",
                  "subscribe",
                  "buyTemplate",
                  "buyWithRefTemplate"
                ],
                "description": "Deprecated, still served: web links built from templates with literal placeholders. Prefer `links` / POST /api/external/v1/links."
              },
              "telegram": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "bot": {
                    "type": "string",
                    "description": "The shared bot username, without @.",
                    "example": "DropfansBot"
                  },
                  "profile": {
                    "type": "string",
                    "description": "Opens the creator’s Mini App profile.",
                    "format": "uri",
                    "example": "https://t.me/DropfansBot/app?startapp=p_valeria"
                  },
                  "tip": {
                    "type": "string",
                    "description": "Opens the Mini App tip sheet.",
                    "format": "uri",
                    "example": "https://t.me/DropfansBot/app?startapp=t_valeria"
                  },
                  "tipTemplate": {
                    "type": "string",
                    "description": "Tip prefilled — replace `{cents}` with the amount in **cents** (the web template takes dollars; this one takes cents).",
                    "example": "https://t.me/DropfansBot/app?startapp=pt_{cents}_valeria"
                  },
                  "tipWithRefTemplate": {
                    "type": "string",
                    "description": "Mini App tip with a per-fan reference — replace `{cents}` (`0` lets the fan pick the amount) and `{externalRef}`. **Here the reference is 1–20 of `A-Z a-z 0-9 -` (no underscore)**: it sits in front of the username, which may contain underscores, and Telegram caps the start parameter at 64 characters.",
                    "example": "https://t.me/DropfansBot/app?startapp=tm_{cents}_{externalRef}_valeria"
                  },
                  "subscribe": {
                    "type": "string",
                    "description": "Opens the Mini App subscribe flow.",
                    "format": "uri",
                    "example": "https://t.me/DropfansBot/app?startapp=s_valeria"
                  },
                  "buyTemplate": {
                    "type": "string",
                    "description": "Mini App checkout for any drop — replace `{productId}`.",
                    "example": "https://t.me/DropfansBot/app?startapp=b_{productId}"
                  },
                  "buyWithRefTemplate": {
                    "type": "string",
                    "description": "Mini App checkout with a per-fan reference — replace `{productId}` and `{externalRef}` (1–32 of `A-Z a-z 0-9 _ -`).",
                    "example": "https://t.me/DropfansBot/app?startapp=b_{productId}_{externalRef}"
                  }
                },
                "required": [
                  "bot",
                  "profile",
                  "tip",
                  "tipTemplate",
                  "tipWithRefTemplate",
                  "subscribe",
                  "buyTemplate",
                  "buyWithRefTemplate"
                ],
                "description": "Deprecated, still served: Telegram Mini App deep links built from templates. **Null when the shared Dropfans bot is not configured.** Prefer `links` / POST /api/external/v1/links."
              }
            },
            "required": [
              "username",
              "links",
              "web"
            ]
          },
          "example": {
            "username": "valeria",
            "links": {
              "profile": {
                "id": "k3x9m2qa7d",
                "type": "profile",
                "url": "https://www.dropfans.io/buy/k3x9m2qa7d",
                "telegram": "https://t.me/DropfansBot/app?startapp=k3x9m2qa7d",
                "productId": null,
                "amountUsd": null,
                "externalRef": null,
                "createdAt": "2026-10-29T12:00:00.000Z"
              },
              "tip": {
                "id": "p0w8n4rt2c",
                "type": "tip",
                "url": "https://www.dropfans.io/buy/p0w8n4rt2c",
                "telegram": "https://t.me/DropfansBot/app?startapp=p0w8n4rt2c",
                "productId": null,
                "amountUsd": null,
                "externalRef": null,
                "createdAt": "2026-10-29T12:00:00.000Z"
              },
              "subscribe": {
                "id": "h5j1v9xs3e",
                "type": "subscribe",
                "url": "https://www.dropfans.io/buy/h5j1v9xs3e",
                "telegram": "https://t.me/DropfansBot/app?startapp=h5j1v9xs3e",
                "productId": null,
                "amountUsd": null,
                "externalRef": null,
                "createdAt": "2026-10-29T12:00:00.000Z"
              }
            },
            "web": {
              "profile": "https://www.dropfans.io/u/valeria",
              "tip": "https://www.dropfans.io/u/valeria?tip=1",
              "tipTemplate": "https://www.dropfans.io/u/valeria?tip={usd}",
              "tipWithRefTemplate": "https://www.dropfans.io/u/valeria?tip={usd}&m={externalRef}",
              "subscribe": "https://www.dropfans.io/u/valeria?subscribe=1",
              "buyTemplate": "https://www.dropfans.io/buy/{productId}",
              "buyWithRefTemplate": "https://www.dropfans.io/buy/{productId}?m={externalRef}"
            },
            "telegram": {
              "bot": "DropfansBot",
              "profile": "https://t.me/DropfansBot/app?startapp=p_valeria",
              "tip": "https://t.me/DropfansBot/app?startapp=t_valeria",
              "tipTemplate": "https://t.me/DropfansBot/app?startapp=pt_{cents}_valeria",
              "tipWithRefTemplate": "https://t.me/DropfansBot/app?startapp=tm_{cents}_{externalRef}_valeria",
              "subscribe": "https://t.me/DropfansBot/app?startapp=s_valeria",
              "buyTemplate": "https://t.me/DropfansBot/app?startapp=b_{productId}",
              "buyWithRefTemplate": "https://t.me/DropfansBot/app?startapp=b_{productId}_{externalRef}"
            }
          }
        }
      }
    },
    "400": {
      "description": "`X-Dropfans-Account` is not an account id. Also: Called under /v1/creators/{creatorId}/ with an `X-Dropfans-Account` naming another account.",
      "headers": {
        "X-RateLimit-Tier": {
          "description": "Rate-limit tier of the key: personal, app or first_party (first_party is unlimited).",
          "schema": {
            "type": "string",
            "enum": [
              "personal",
              "app",
              "first_party"
            ]
          }
        },
        "X-RateLimit-Limit": {
          "description": "Requests allowed per minute for this key (absent on first_party).",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Remaining": {
          "description": "Requests left in the current minute window.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Reset": {
          "description": "Epoch seconds when the minute window resets.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Limit-Day": {
          "description": "Requests allowed per UTC day for this key (absent on first_party).",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Remaining-Day": {
          "description": "Requests left in the current UTC day window.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Reset-Day": {
          "description": "Epoch seconds when the day window resets.",
          "schema": {
            "type": "integer"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "Human-readable message.",
                "example": "Rate limit exceeded"
              },
              "code": {
                "type": "string",
                "description": "Machine-readable code: unauthorized, app_suspended, first_party_only, api_category_disabled, rate_limited, username_required, invalid_account_header, account_not_managed, permission_denied, account_header_not_allowed, agency_key_required — plus endpoint-specific codes listed on each reference page.",
                "example": "rate_limited"
              }
            },
            "required": [
              "error",
              "code"
            ]
          },
          "example": {
            "error": "X-Dropfans-Account must be an account id (from GET /api/external/agency/creators), not a username.",
            "code": "invalid_account_header"
          }
        }
      }
    },
    "401": {
      "description": "Missing or invalid API key.",
      "headers": {
        "X-RateLimit-Tier": {
          "description": "Rate-limit tier of the key: personal, app or first_party (first_party is unlimited).",
          "schema": {
            "type": "string",
            "enum": [
              "personal",
              "app",
              "first_party"
            ]
          }
        },
        "X-RateLimit-Limit": {
          "description": "Requests allowed per minute for this key (absent on first_party).",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Remaining": {
          "description": "Requests left in the current minute window.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Reset": {
          "description": "Epoch seconds when the minute window resets.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Limit-Day": {
          "description": "Requests allowed per UTC day for this key (absent on first_party).",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Remaining-Day": {
          "description": "Requests left in the current UTC day window.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Reset-Day": {
          "description": "Epoch seconds when the day window resets.",
          "schema": {
            "type": "integer"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "Human-readable message.",
                "example": "Rate limit exceeded"
              },
              "code": {
                "type": "string",
                "description": "Machine-readable code: unauthorized, app_suspended, first_party_only, api_category_disabled, rate_limited, username_required, invalid_account_header, account_not_managed, permission_denied, account_header_not_allowed, agency_key_required — plus endpoint-specific codes listed on each reference page.",
                "example": "rate_limited"
              }
            },
            "required": [
              "error",
              "code"
            ]
          },
          "example": {
            "error": "Unauthorized",
            "code": "unauthorized"
          }
        }
      }
    },
    "403": {
      "description": "The creator in the path (or `X-Dropfans-Account`) is one this key cannot act for: no ACCEPTED management by your agency and not an account your app onboarded (or it no longer holds a key bound to your app), a key minted for one creator, or someone is suspended, banned or deleted. An unknown id gets the same answer. Also: Your app has the Links [API category](https://www.dropfans.io/developers/concepts/api-categories.md) switched off.",
      "headers": {
        "X-RateLimit-Tier": {
          "description": "Rate-limit tier of the key: personal, app or first_party (first_party is unlimited).",
          "schema": {
            "type": "string",
            "enum": [
              "personal",
              "app",
              "first_party"
            ]
          }
        },
        "X-RateLimit-Limit": {
          "description": "Requests allowed per minute for this key (absent on first_party).",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Remaining": {
          "description": "Requests left in the current minute window.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Reset": {
          "description": "Epoch seconds when the minute window resets.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Limit-Day": {
          "description": "Requests allowed per UTC day for this key (absent on first_party).",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Remaining-Day": {
          "description": "Requests left in the current UTC day window.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Reset-Day": {
          "description": "Epoch seconds when the day window resets.",
          "schema": {
            "type": "integer"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "Human-readable message.",
                "example": "Rate limit exceeded"
              },
              "code": {
                "type": "string",
                "description": "Machine-readable code: unauthorized, app_suspended, first_party_only, api_category_disabled, rate_limited, username_required, invalid_account_header, account_not_managed, permission_denied, account_header_not_allowed, agency_key_required — plus endpoint-specific codes listed on each reference page.",
                "example": "rate_limited"
              }
            },
            "required": [
              "error",
              "code"
            ]
          },
          "example": {
            "error": "This key cannot act for that account.",
            "code": "account_not_managed"
          }
        }
      }
    },
    "409": {
      "description": "The creator has no username yet. Have the creator pick a handle in their Dropfans settings, then retry.",
      "headers": {
        "X-RateLimit-Tier": {
          "description": "Rate-limit tier of the key: personal, app or first_party (first_party is unlimited).",
          "schema": {
            "type": "string",
            "enum": [
              "personal",
              "app",
              "first_party"
            ]
          }
        },
        "X-RateLimit-Limit": {
          "description": "Requests allowed per minute for this key (absent on first_party).",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Remaining": {
          "description": "Requests left in the current minute window.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Reset": {
          "description": "Epoch seconds when the minute window resets.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Limit-Day": {
          "description": "Requests allowed per UTC day for this key (absent on first_party).",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Remaining-Day": {
          "description": "Requests left in the current UTC day window.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Reset-Day": {
          "description": "Epoch seconds when the day window resets.",
          "schema": {
            "type": "integer"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "Human-readable message.",
                "example": "Rate limit exceeded"
              },
              "code": {
                "type": "string",
                "description": "Machine-readable code: unauthorized, app_suspended, first_party_only, api_category_disabled, rate_limited, username_required, invalid_account_header, account_not_managed, permission_denied, account_header_not_allowed, agency_key_required — plus endpoint-specific codes listed on each reference page.",
                "example": "rate_limited"
              }
            },
            "required": [
              "error",
              "code"
            ]
          },
          "example": {
            "error": "Set a username first",
            "code": "username_required"
          }
        }
      }
    },
    "429": {
      "description": "Rate limit exceeded for the current minute or day window. Wait Retry-After seconds and retry.",
      "headers": {
        "X-RateLimit-Tier": {
          "description": "Rate-limit tier of the key: personal, app or first_party (first_party is unlimited).",
          "schema": {
            "type": "string",
            "enum": [
              "personal",
              "app",
              "first_party"
            ]
          }
        },
        "X-RateLimit-Limit": {
          "description": "Requests allowed per minute for this key (absent on first_party).",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Remaining": {
          "description": "Requests left in the current minute window.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Reset": {
          "description": "Epoch seconds when the minute window resets.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Limit-Day": {
          "description": "Requests allowed per UTC day for this key (absent on first_party).",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Remaining-Day": {
          "description": "Requests left in the current UTC day window.",
          "schema": {
            "type": "integer"
          }
        },
        "X-RateLimit-Reset-Day": {
          "description": "Epoch seconds when the day window resets.",
          "schema": {
            "type": "integer"
          }
        },
        "Retry-After": {
          "description": "Seconds to wait before retrying (sent with 429s).",
          "schema": {
            "type": "integer"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "Human-readable message.",
                "example": "Rate limit exceeded"
              },
              "code": {
                "type": "string",
                "description": "Machine-readable code: unauthorized, app_suspended, first_party_only, api_category_disabled, rate_limited, username_required, invalid_account_header, account_not_managed, permission_denied, account_header_not_allowed, agency_key_required — plus endpoint-specific codes listed on each reference page.",
                "example": "rate_limited"
              }
            },
            "required": [
              "error",
              "code"
            ]
          },
          "example": {
            "error": "Rate limit exceeded",
            "code": "rate_limited"
          }
        }
      }
    }
  },
  "x-codeSamples": [
    {
      "lang": "cURL",
      "label": "curl",
      "source": "curl \"https://www.dropfans.io/api/external/v1/links\" \\\n  -H \"Authorization: Bearer $DROPFANS_API_KEY\""
    },
    {
      "lang": "JavaScript",
      "label": "Node",
      "source": "const res = await fetch(`https://www.dropfans.io/api/external/v1/links`, {\n  headers: {\n    Authorization: `Bearer ${process.env.DROPFANS_API_KEY}`,\n  },\n});\nconsole.log(await res.json());"
    },
    {
      "lang": "Python",
      "source": "import os\nimport requests\n\nres = requests.get(\n    \"https://www.dropfans.io/api/external/v1/links\",\n    headers={\"Authorization\": f\"Bearer {os.environ['DROPFANS_API_KEY']}\"},\n)\nprint(res.json())"
    }
  ],
  "x-dropfans-docs": "https://www.dropfans.io/developers/reference/get-links",
  "x-dropfans-category": "links",
  "x-dropfans-agency-permission": null
}
```

---

Previous: [List paid tips (per-fan references)](https://www.dropfans.io/developers/reference/list-tips.md) · Next: [Create a link for a drop, a tip, a subscription or the profile](https://www.dropfans.io/developers/reference/create-link.md) · All pages: [llms.txt](https://www.dropfans.io/developers/llms.txt)
