BetterFans Link SDK — OnlyFans APIBetterFans Link SDK
Core Capabilities

Media

Upload photos and videos to OnlyFans programmatically via the BetterFans Link SDK — the infrastructure behind OFManager. One call per upload, deduplication built in, ready to attach to messages and posts.

Attach a photo or video to a message or post in a single call. You pass in a source, you get back a reference. The SDK handles deduplication and processing end-to-end.

Setup

import { OfApiClient } from "@betterfans/link-sdk"
import { media } from "@betterfans/link-sdk/plugins/media"

const client = new OfApiClient({
  apiKey: process.env.BFL_API_KEY,
  plugins: [media()],
})

const account = client.for("123456789")

Upload and attach

const result = await account.plugin.media.upload({
  source: "https://cdn.example/photo.jpg",
})

await account.request("POST /chats/:id/messages", {
  pathParams: { id: "98765" },
  body: {
    text: "here you go",
    mediaFiles: result.kind === "existing" ? [result.mediaId] : [result.ref],
  },
})

source accepts any of:

  • a URL string (fetched on your behalf),
  • a Blob,
  • an ArrayBuffer or Uint8Array.

The result discriminates on kind:

  • existing — a byte-identical file already lived in the account's library; mediaId is ready to attach.
  • new — a freshly-processed upload; attach the whole ref object as a single mediaFiles entry.

Mixed attachments

mediaFiles accepts a mix of both shapes in one request:

const a = await account.plugin.media.upload({ source: videoUrl })
const b = await account.plugin.media.upload({ source: photoUrl, avoidWatermark: true })

await account.request("POST /posts", {
  body: {
    text: "new drop",
    mediaFiles: [
      ...(a.kind === "existing" ? [a.mediaId] : [a.ref]),
      ...(b.kind === "existing" ? [b.mediaId] : [b.ref]),
      11111, // existing vault id you already know about
    ],
    price: 15,
  },
})

Options

Prop

Type

Result

Prop

Type

Refreshing cached account state

The plugin caches a small amount of per-account state to keep repeat uploads fast. If an account's profile settings change out of band and you want the next upload to pick them up immediately rather than waiting for the internal TTL:

client.plugin.media.invalidateCache("123456789")

On this page