> ## 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/vault — 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).

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

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

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).

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/v1/vault/folders](https://www.dropfans.io/developers/reference/list-folders.md) counts every non-hidden item, so the two can disagree for the same folder.

## 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}/vault` — 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); for a managed creator the agency needs `canManageVault`. 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.

## Query parameters

| Field | Type | Required | Description |
|---|---|---|---|
| `page` | integer |  | Page number, 1-based. |
| `limit` | integer |  | Items per page. Hard cap 50 — larger values are clamped, not rejected. |
| `folderId` | string |  | `"all"` (default), `"unfiled"`, or a folder id from the folders list. |
| `includePending` | boolean |  | 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. |

## Responses

### 200

Vault items, folders and pagination.

| Field | Type | Required | Description |
|---|---|---|---|
| `items` | VaultItem[] | yes | The requested page, newest first. |
| `folders` | Folder[] | yes | All of the creator’s folders (unpaginated), with counts under the current moderation filter. |
| `hasMore` | boolean | yes | True when more pages exist for the current filter. |
| `total` | integer | yes | Total items matching the filter. |
| `page` | integer | yes | Echoed page number (1-based). |
| `limit` | integer | yes | Echoed page size. |

```json
{
  "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. |
| 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":"The agency does not have permission for this on that account.","code":"permission_denied","permission":"canManageVault"}` | For a managed creator: the agency lacks `canManageVault` on that account. |
| 403 | `{"error":"This app does not have the vault API category enabled. Contact support to enable it.","code":"api_category_disabled","category":"vault"}` | Your app has the Vault [API category](https://www.dropfans.io/developers/concepts/api-categories.md) switched off. |

## 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.

## 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/vault?page=1&folderId=all" \
  -H "Authorization: Bearer $DROPFANS_API_KEY"
```

### Node

```javascript
const res = await fetch(`https://www.dropfans.io/api/external/v1/vault?page=1&folderId=all`, {
  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/vault",
    headers={"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"},
    params={"page": 1, "folderId": "all"},
)
print(res.json())
```

## OpenAPI

```json
{
  "method": "GET",
  "path": "/api/external/v1/vault",
  "operationId": "listVault",
  "tags": [
    "vault"
  ],
  "summary": "List your vault items — the source of media for posts",
  "description": "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).\n\nEvery 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/v1/vault/folders](https://www.dropfans.io/developers/reference/list-folders.md) counts every non-hidden item, so the two can disagree for the same folder.",
  "parameters": [
    {
      "name": "page",
      "in": "query",
      "required": false,
      "description": "Page number, 1-based.",
      "schema": {
        "type": "integer",
        "default": 1
      },
      "example": 1
    },
    {
      "name": "limit",
      "in": "query",
      "required": false,
      "description": "Items per page. Hard cap 50 — larger values are clamped, not rejected.",
      "schema": {
        "type": "integer",
        "default": 50,
        "maximum": 50
      }
    },
    {
      "name": "folderId",
      "in": "query",
      "required": false,
      "description": "`\"all\"` (default), `\"unfiled\"`, or a folder id from the folders list.",
      "schema": {
        "type": "string"
      },
      "example": "all"
    },
    {
      "name": "includePending",
      "in": "query",
      "required": false,
      "description": "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.",
      "schema": {
        "type": "boolean",
        "default": false
      }
    },
    {
      "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": "Vault items, folders and pagination.",
      "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": {
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Vault item id — use as `vaultItemId` when creating drops and MEDIA posts.",
                      "example": "clxv1a2b30001item"
                    },
                    "fileName": {
                      "type": "string",
                      "description": "Original file name as uploaded.",
                      "example": "beach-set-01.jpg"
                    },
                    "filePath": {
                      "type": "string",
                      "description": "Display asset URL. Images: the CDN display copy. Audio: a token-signed URL valid ~12 hours, directly fetchable. Videos: the Bunny Stream playback URL (DRM-locked — use `downloadUrl` to fetch bytes). **Empty string `\"\"` for items that are not APPROVED** (visible only with includePending=true): unapproved content may never be forwarded."
                    },
                    "thumbnailPath": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Thumbnail URL. For videos this is always rebuilt as an absolute Bunny Stream thumbnail from the current CDN host. Null for audio (voice messages have no visual)."
                    },
                    "fileType": {
                      "type": "string",
                      "description": "Media kind.",
                      "enum": [
                        "image",
                        "video",
                        "audio"
                      ]
                    },
                    "fileSize": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Size in bytes of the stored display asset.",
                      "example": 482113
                    },
                    "durationSeconds": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "Audio (voice message) length in seconds. Null for images and videos.",
                      "example": 42
                    },
                    "bunnyStreamId": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Bunny Stream GUID for videos — the id you poll with POST /api/external/v1/vault/video-status. Null for images and audio."
                    },
                    "createdAt": {
                      "type": "string",
                      "description": "Upload time.",
                      "format": "date-time"
                    },
                    "folderId": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Containing folder id, or null for unfiled (\"All\")."
                    },
                    "contentTags": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "description": "A content tag (≤64 chars)."
                      },
                      "description": "The item’s content tags (set via PATCH /api/external/v1/vault/{id}/tags)."
                    },
                    "downloadUrl": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Token-signed, directly fetchable original — valid ~12 hours. Videos: the DRM-free Bunny Storage original (null for videos uploaded before dual-store existed — those cannot be fetched). Audio: the same signed voice file as `filePath`. **Always null for images** (fetch `filePath` instead) and for non-APPROVED items."
                    },
                    "moderationStatus": {
                      "type": "string",
                      "description": "**Only present when the request had includePending=true.** Default responses contain APPROVED items only and omit this field entirely, keeping the shape byte-identical for older consumers.",
                      "enum": [
                        "PENDING",
                        "APPROVED",
                        "REJECTED",
                        "FLAGGED"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "fileName",
                    "filePath",
                    "fileType",
                    "createdAt",
                    "contentTags"
                  ]
                },
                "description": "The requested page, newest first."
              },
              "folders": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Folder id.",
                      "example": "clxf0ld3r0001abcd"
                    },
                    "name": {
                      "type": "string",
                      "description": "Folder name — unique per creator.",
                      "example": "Beach set"
                    },
                    "itemCount": {
                      "type": "integer",
                      "description": "Items in the folder. NOTE: GET /api/external/v1/vault counts only items visible at that call’s moderation filter, while GET /api/external/v1/vault/folders counts every non-hidden item regardless of moderation status — the same folder can report two different counts.",
                      "example": 12
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "itemCount"
                  ]
                },
                "description": "All of the creator’s folders (unpaginated), with counts under the current moderation filter."
              },
              "hasMore": {
                "type": "boolean",
                "description": "True when more pages exist for the current filter."
              },
              "total": {
                "type": "integer",
                "description": "Total items matching the filter.",
                "example": 128
              },
              "page": {
                "type": "integer",
                "description": "Echoed page number (1-based).",
                "example": 1
              },
              "limit": {
                "type": "integer",
                "description": "Echoed page size.",
                "example": 50
              }
            },
            "required": [
              "items",
              "folders",
              "hasMore",
              "total",
              "page",
              "limit"
            ]
          },
          "example": {
            "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
          }
        }
      }
    },
    "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: For a managed creator: the agency lacks `canManageVault` on that account. Also: Your app has the Vault [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"
          }
        }
      }
    },
    "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"
          }
        }
      }
    },
    "500": {
      "description": "Query failed — retry later.",
      "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 describing what went wrong.",
                "example": "Vault item not found"
              }
            },
            "required": [
              "error"
            ]
          },
          "example": {
            "error": "Failed to fetch vault items"
          }
        }
      }
    }
  },
  "x-codeSamples": [
    {
      "lang": "cURL",
      "label": "curl",
      "source": "curl \"https://www.dropfans.io/api/external/v1/vault?page=1&folderId=all\" \\\n  -H \"Authorization: Bearer $DROPFANS_API_KEY\""
    },
    {
      "lang": "JavaScript",
      "label": "Node",
      "source": "const res = await fetch(`https://www.dropfans.io/api/external/v1/vault?page=1&folderId=all`, {\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/vault\",\n    headers={\"Authorization\": f\"Bearer {os.environ['DROPFANS_API_KEY']}\"},\n    params={\"page\": 1, \"folderId\": \"all\"},\n)\nprint(res.json())"
    }
  ],
  "x-dropfans-docs": "https://www.dropfans.io/developers/reference/list-vault",
  "x-dropfans-category": "vault",
  "x-dropfans-agency-permission": "canManageVault"
}
```

---

Previous: [Get one creator you can act for](https://www.dropfans.io/developers/reference/get-creator.md) · Next: [Upload an image, small video or voice message](https://www.dropfans.io/developers/reference/upload-vault-item.md) · All pages: [llms.txt](https://www.dropfans.io/developers/llms.txt)
