Fansly API LogoFansly API
Guides

Downloading Media

Learn how to download media files from the Fansly CDN using the Fansly API.

Downloading media files (photos and videos) from Fansly requires retrieving authenticated CDN URLs from resources such as messages or posts and passing them to the download endpoint.

This guide walks you through the flow of retrieving media locations and downloading files using the Download Media endpoint.

The Workflow Overview

To download media programmatically, you will follow these general steps:

Retrieve the CDN URL

Query a resource (like a post, message, or vault item) that contains the media attachments to find its CDN locations.

Extract the Authenticated URL

Identify the correct CDN link from the media locations object, ensuring it includes required query parameters (Policy, Signature, etc.).

Make the Download Request

Send the URL to the download endpoint to retrieve the raw file binary.

Save/Stream the File

Write the returned binary stream to your disk or cloud storage.


Step 1: Retrieve the CDN URL

Media objects in Fansly API responses typically contain a list of media details, including a locations array. Here is an example structure returned by posts or messages:

{
  "id": "media_987654321",
  "type": 1, // Photo/Video
  "locations": [
    {
      "locationId": "loc_112233",
      "location": "https://cdn3.fansly.com/865407923461840896/874741462745509891.jpeg?ngsw-bypass=true&Policy=eyJTdGF0...",
      "type": 1
    }
  ]
}

Copy the full location string. This is your target cdnUrl.

Link Expiration

Fansly CDN URLs are time-signed. The query parameters (Policy, Signature, Key-Pair-Id) allow authenticated access to the file. Ensure you download the media shortly after retrieving the URL, as these signatures will eventually expire.


Step 2: Make the Download Request

Use the Download Media endpoint to fetch the binary payload.

POST /api/fansly/media/download

Request Payload

Send the full CDN URL in the JSON body:

{
  "cdnUrl": "https://cdn3.fansly.com/865407923461840896/874741462745509891.jpeg?ngsw-bypass=true&Policy=eyJTdGF0..."
}

Step 3: Stream & Save the Response

The API will respond with 200 OK and stream the raw file data back.

Implementation Examples

import requests

url = "https://v1.apifansly.com/api/fansly/media/download"
headers = {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json"
}
payload = {
    "cdnUrl": "https://cdn3.fansly.com/..."
}

# Stream the file content to prevent high memory usage
with requests.post(url, json=payload, headers=headers, stream=True) as r:
    r.raise_for_status()
    with open("downloaded_media.jpg", "wb") as f:
        for chunk in r.iter_content(chunk_size=8192):
            f.write(chunk)
            
print("Download completed successfully.")
const fs = require('fs');

const downloadMedia = async () => {
  const response = await fetch("https://v1.apifansly.com/api/fansly/media/download", {
    method: "POST",
    headers: {
      "x-api-key": "YOUR_API_KEY",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      cdnUrl: "https://cdn3.fansly.com/..."
    })
  });

  if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);

  // Pipe the stream directly to a file
  const fileStream = fs.createWriteStream('downloaded_media.jpg');
  const readableStream = response.body;
  
  // Node.js streaming or response.arrayBuffer()
  const buffer = await response.arrayBuffer();
  fs.writeFileSync('downloaded_media.jpg', Buffer.from(buffer));
  console.log("Download completed.");
};

downloadMedia();

Best Practices

  • Handle Large Files (Videos): Videos can be hundreds of megabytes. Always stream the response body to your storage rather than reading the entire file into memory.
  • Timeout Configurations: Implement generous timeouts (e.g., 60–120 seconds) for large video downloads to prevent premature connection drops.
  • Rate Limits: If downloading multiple attachments in a loop, introduce short pauses (e.g., 500ms) between requests to avoid triggering rate limit errors.

On this page