List your vault items — the source of media for posts
Returns APPROVED items by default. Use an item's `id` as `vaultItemId` when creating a MEDIA post. Pass includePending=true to also see items still in moderation (their media is stripped).
/api/external/vaultReturns APPROVED items by default. Use an item's id as vaultItemId when creating a MEDIA post. Pass includePending=true to also see items still in moderation (their media is stripped).
Every drop and every MEDIA post is built from vault item ids, so this list is the starting point of almost every flow. Items are newest first. The response also carries all of the creator's folders — but note the folders' itemCount here respects the moderation filter, while GET /api/external/vault/folders counts every non-hidden item, so the two can disagree for the same folder.
Authentication
Send the creator's API key as a bearer token: Authorization: Bearer dpfn_…. See Authentication & API keys.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
page | integer | Optional | Page number, 1-based. Default: 1 |
limit | integer | Optional | Items per page. Hard cap 50 — larger values are clamped, not rejected. Default: 50Max: 50 |
folderId | string | Optional | "all" (default), "unfiled", or a folder id from the folders list. |
includePending | boolean | Optional | Pass the literal string true to also get PENDING and FLAGGED items (REJECTED never appears). Those items come back with filePath: "" and downloadUrl: null — thumbnail only — and each item gains a moderationStatus field.Default: false |
Responses
| Name | Type | Description | |||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
items | VaultItem[] | The requested page, newest first.Show child attributes
| |||||||||||||||||||||||||||||||||||||||
folders | Folder[] | All of the creator’s folders (unpaginated), with counts under the current moderation filter.Show child attributes
| |||||||||||||||||||||||||||||||||||||||
hasMore | boolean | True when more pages exist for the current filter. | |||||||||||||||||||||||||||||||||||||||
total | integer | Total items matching the filter. | |||||||||||||||||||||||||||||||||||||||
page | integer | Echoed page number (1-based). | |||||||||||||||||||||||||||||||||||||||
limit | integer | Echoed page size. |
{
"items": [
{
"id": "clxv1a2b30001item",
"fileName": "beach-set-01.jpg",
"filePath": "https://cdn.dropfans.io/valeria/vault/1721990000-ab12cd.jpg",
"thumbnailPath": "https://cdn.dropfans.io/valeria/thumbnails/1721990000-ab12cd.jpg",
"fileType": "image",
"fileSize": 482113,
"durationSeconds": null,
"bunnyStreamId": null,
"createdAt": "2026-08-01T10:15:00.000Z",
"folderId": "clxf0ld3r0001abcd",
"contentTags": [
"beach",
"bikini"
],
"downloadUrl": null
}
],
"folders": [
{
"id": "clxf0ld3r0001abcd",
"name": "Beach set",
"itemCount": 12
}
],
"hasMore": true,
"total": 128,
"page": 1,
"limit": 50
}Errors
| Status | Body | When |
|---|---|---|
| 401 | {"error":"Unauthorized","code":"unauthorized"} | Missing or invalid API key. |
| 500 | {"error":"Failed to fetch vault items"} | Query failed — retry later. |
Rate limiting
Every response carries the X-RateLimit-Tier header and, on limited tiers, the per-minute and per-day trios — read X-RateLimit-Remaining and X-RateLimit-Reset instead of hardcoding limits. Details in Rate limits.
Code samples
curl "https://www.dropfans.io/api/external/vault?page=1&folderId=all" \
-H "Authorization: Bearer $DROPFANS_API_KEY"const res = await fetch(`https://www.dropfans.io/api/external/vault?page=1&folderId=all`, {
headers: {
Authorization: `Bearer ${process.env.DROPFANS_API_KEY}`,
},
});
console.log(await res.json());import os
import requests
res = requests.get(
"https://www.dropfans.io/api/external/vault",
headers={"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"},
params={"page": 1, "folderId": "all"},
)
print(res.json())Notes
Signed URLs in the response (downloadUrl, audio filePath) are valid ~12 hours — re-list rather than caching them longer. downloadUrl is the only fetchable video source (the Stream filePath is DRM-locked); it is null for videos uploaded before dual-store existed. filePath is the empty string "" for any non-APPROVED item.
Questions? [email protected]
