Fansly API LogoFansly API
Media

Media Permissions

A comprehensive guide on how to attach and restrict media access across the API (Posts, Messages, Automated Messages).

Several endpoints across our Fansly API (such as creating posts, sending DMs, mass messaging, and automated messages) support attaching Fansly media. You can restrict access to this media using powerful permission models, from simple paywalls (PPV) to complex multi-condition locks.

This guide covers the standard media permission structure used throughout the API.


Attaching Media

Media is attached by providing an array of media IDs using the mediaIds property.

{
  "mediaIds": ["media_id_1", "media_id_2"]
}

Media Previews

If you want to include a "preview" (like a free teaser image or short video) for locked media, you can pass an object containing both the mediaId and previewId instead of just a raw string. Fansly will display the preview to users who haven't unlocked the main media yet.

{
  "mediaIds": [
    {
      "mediaId": "media_id",
      "previewId": "preview_media_id"
    }
  ]
}

You can seamlessly mix media items that have previews and those that don't within the same array (for instance, when creating a bundle). To do this, simply use objects for media with previews, and either raw strings or objects with previewId: null for media without previews:

{
  "mediaIds": [
    // 1. Media WITH a free preview
    {
      "mediaId": "media_id_1",
      "previewId": "preview_media_id"
    },
    // 2. Media WITHOUT a preview (using a simple string)
    "media_id_1", 
    // 3. Media WITHOUT a preview (using an object)
    {
      "mediaId": "media_id_1"
    }
  ],
  "access_type": ["ppv"],
  "price": 5.99
}

By default, if no access rules are provided, the media is considered unlocked (free for anyone who can see the post or message).


Simple (Root-Level) Permissions

If you only need a single condition for your media (e.g., "Pay $5 to unlock" OR "Must be a subscriber"), you can pass the permission fields directly at the root of your payload alongside the mediaIds.

Available Fields

FieldTypeDescription
access_typearray of stringRequired to lock media. Can include: "ppv", "subscription", "follow", "list", "limited_time".
pricenumberPrice in dollars (e.g., 5.00). Required if access_type includes "ppv".
subscriptionTierIdstringOptional if access_type includes "subscription". Omit to lock for all subscription tiers.
subscriptionTierNamestringOptional if access_type includes "subscription". Omit to lock for all subscription tiers.
listIdstringRequired if access_type includes "list".
listLabelstringRequired if access_type includes "list".
validBeforenumberTimestamp. Required if access_type includes "limited_time".
validAfternumberTimestamp. Required if access_type includes "limited_time".

Example: Simple PPV Paywall

{
  "mediaIds": ["media_id"],
  "access_type": ["ppv"],
  "price": 4.99
}

Example: Simple Subscription Lock

{
  "mediaIds": ["media_id"],
  "access_type": ["subscription"],
  "subscriptionTierId": "subscription_tier_id",
  "subscriptionTierName": "Gold VIP"
}

Advanced (Multi-Rule) Permissions

If you want media to be unlockable via multiple different conditions (an "OR" relationship), you must use the permissions array instead of the root-level fields.

When the permissions array is provided in your payload, any root-level permission fields (like a root-level price or access_type) are ignored, and the API strictly uses the rules defined in the array.

Each object within the permissions array accepts the exact same fields listed in the table above.

Example: Multiple Unlock Options

In this payload, a user can unlock the attached video if they meet any of the following conditions:

  1. They are subscribed to the "Gold VIP" tier.
  2. OR they pay a $5.00 PPV fee.
  3. OR they are on a specific custom list.
{
  "content": "Check out my new exclusive video!",
  "mediaIds": ["media_id"],
  "permissions": [
    {
      "access_type": ["subscription"],
      "subscriptionTierId": "subscription_tier_id",
      "subscriptionTierName": "Gold VIP"
    },
    {
      "access_type": ["ppv"],
      "price": 5.00
    },
    {
      "access_type": ["list"],
      "listId": "list_id",
      "listLabel": "Close Friends"
    }
  ]
}

Example: Combined Access Types

You can also combine access types within a single rule if you want to require both conditions to be true (an "AND" relationship within a single rule block, though this is less common).

{
  "mediaIds": ["media_id"],
  "permissions": [
    {
      "access_type": ["subscription", "limited_time"],
      "subscriptionTierId": "subscription_tier_id",
      "subscriptionTierName": "Gold VIP",
      "validBefore": 1729483920
    }
  ]
}

In the above example, the media can only be unlocked by a Gold VIP subscriber, AND only before the specified Unix timestamp.


Comprehensive Example

The following payload uses all available access_type values and their corresponding fields in a single root-level permission rule:

{
  "content": "Check out this exclusive media!",
  "mediaIds": [
    "media_id_1",
    "media_id_2"
  ],
  "access_type": [
    "ppv",
    "subscription",
    "follow",
    "list",
    "limited_time"
  ],
  "price": 10.00,
  "subscriptionTierId": "subscription_tier_id",
  "subscriptionTierName": "Sugar Daddy",
  "subscriptionTierBefore": 1782485820000,
  "subscriptionTierAfter": 1781708220000,
  "listId": "list_id",
  "listLabel": "VIP Fans",
  "validBefore": 1782399840000,
  "validAfter": 1781708661247
}

On this page