Attach baked blur previews to a drop
Uploads pre-blurred ("baked") JPEG teasers for a drop's media, so the checkout page shows the exact same blur your app showed the buyer elsewhere.
/api/external/drops/{id}/previewsUploads pre-blurred ("baked") JPEG teasers for a drop's media, so the checkout page shows the exact same blur your app showed the buyer elsewhere.
The body is multipart/form-data with one part per media item, named by vault item id: previewBlob_<vaultItemId> (the baked JPEG) and optionally blurMeta_<vaultItemId> (a descriptor like "partial", "pixelated:59" or "full"). Without previews, paid media falls back to a generic gaussian blur.
Parts that are missing, not image/jpeg, over 8MB, or that hit a storage error are skipped without an error. The only signal is the updated count — compare it to how many parts you sent. Repeatable: re-sending overwrites the stored preview.
Authentication
Send the creator's API key as a bearer token: Authorization: Bearer dpfn_…. See Authentication & API keys.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The product (drop) id. |
Request body
Content type: multipart/form-data — Field names embed the vault item id — one previewBlob per media item you want a preview on.
| Name | Type | Required | Description |
|---|---|---|---|
previewBlob_<vaultItemId> | file | Optional | The baked JPEG teaser for that media item. Must be image/jpeg, ≤8MB. |
blurMeta_<vaultItemId> | string | Optional | Optional blur descriptor recorded alongside: "full", "partial" or "pixelated:<intensity>". |
[email protected]
blurMeta_clxv1a2b30001item=partial
[email protected]
blurMeta_clxv1a2b30002item=pixelated:59Responses
| Name | Type | Description |
|---|---|---|
success | boolean | Always true. |
updated | integer | Previews stored on this call. |
{
"success": true,
"updated": 2
}Errors
| Status | Body | When |
|---|---|---|
| 401 | {"error":"Unauthorized","code":"unauthorized"} | Missing or invalid API key. |
| 403 | {"error":"You do not own this drop"} | The drop belongs to another creator. |
| 404 | {"error":"Drop not found"} | No such drop. |
| 500 | {"error":"Failed to attach previews"} | Unexpected failure — 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 -X POST "https://www.dropfans.io/api/external/drops/$PRODUCT_ID/previews" \
-H "Authorization: Bearer $DROPFANS_API_KEY" \
-F "[email protected];type=image/jpeg" \
-F "blurMeta_clxv1a2b30001item=partial" \
-F "[email protected];type=image/jpeg" \
-F "blurMeta_clxv1a2b30002item=pixelated:59"import { readFile } from 'node:fs/promises';
const form = new FormData();
form.append(
'previewBlob_clxv1a2b30001item',
new Blob([await readFile('preview-1.jpg')], { type: 'image/jpeg' }),
'preview-1.jpg',
);
form.append('blurMeta_clxv1a2b30001item', 'partial');
const res = await fetch(
`https://www.dropfans.io/api/external/drops/${productId}/previews`,
{
method: 'POST',
headers: { Authorization: `Bearer ${process.env.DROPFANS_API_KEY}` },
body: form,
},
);
console.log(await res.json()); // { success: true, updated: 1 }import os, requests
res = requests.post(
f"https://www.dropfans.io/api/external/drops/{product_id}/previews",
headers={"Authorization": f"Bearer {os.environ['DROPFANS_API_KEY']}"},
files={
"previewBlob_clxv1a2b30001item": ("preview-1.jpg", open("preview-1.jpg", "rb"), "image/jpeg"),
},
data={"blurMeta_clxv1a2b30001item": "partial"},
)
print(res.json()) # { "success": true, "updated": 1 }Questions? [email protected]
