The Only API docs
Content

Create a new post

Create a new post on your profile. Supports text, media attachments, PPV pricing, polls, scheduled publishing (isScheduled + scheduledDate), and expiration dates.

POST
/api2/v2/posts

Create a new post on your profile. Supports text, media attachments, PPV pricing, polls, scheduled publishing (isScheduled + scheduledDate), and expiration dates.

Attaching a freshly uploaded file — use mediaFiles, not media. POST /accounts/{of_user_id}/media returns a media object; put it in a mediaFiles array here, unchanged and complete.

Verified live 2026-08-06, and the failure mode is silent — OnlyFans returns 200 and simply attaches nothing if you get this wrong:

bodyresult
mediaFiles: [{processId, host, thumbId, name, extra}]media attached ✅
media: [{…same object…}]post created, 0 media
mediaFiles: [{processId}] onlypost created, 0 media

So pass the whole object through — dropping thumbId or name silently loses the attachment.

The vault row for the media is created by this call and appears in GET /api2/v2/vault/media roughly 10–15 seconds later. It survives deletion of the post.

Media already in the vault is referenced by its integer ID from GET /api2/v2/vault/media.

OnlyFans only. Requests made with a user-id belonging to a Fansly account are rejected — use the platform-neutral CRM data routes (/notifications, /balances, /chats, /purchases, /subscribers/cached, ...) which are Fansly-aware.

Guide: The two surfaces

X-API-Key<token>

Your CRM panel API key

In: header

Header Parameters

user-id*string

Creator account ID of the account to act as (e.g. 509955039). Required — omitting it returns 400 user-id header is required. Use GET /accounts to list your connected accounts. On /api2/v2/* the account must be an OnlyFans account; Fansly accounts are rejected there.

X-Proxy?string

Proxy URL — HTTP or SOCKS5 (e.g. http://user:pass@host:port or socks5://user:pass@host:port). Optional on post-connection routes, where it overrides the proxy saved at login time. Required on the connection routes (POST /accounts/login, POST /accounts/login/cookies, POST /accounts/login/verify-otp) for OnlyFans accounts; optional for Fansly.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

curl -X POST "https://example.com/api2/v2/posts" \  -H "user-id: 509955039" \  -H "Content-Type: application/json" \  -d '{    "text": "Happy Monday everyone! ❤️"  }'
{  "id": 0,  "text": "string",  "rawText": "string",  "price": 0,  "isOpened": true,  "isPinned": true,  "postedAt": "2019-08-24T14:15:22Z",  "postedAtPrecise": "string",  "expiredAt": "2019-08-24T14:15:22Z",  "commentsCount": 0,  "favoritesCount": 0,  "tipsAmount": 0,  "media": [    {      "id": 0,      "type": "photo",      "createdAt": "2019-08-24T14:15:22Z",      "duration": 0,      "convertedToVideo": true,      "canView": true,      "isReady": true,      "hasError": true,      "hasPosts": true,      "hasCustomPreview": true,      "counters": {        "buyersCount": 0,        "likesCount": 0,        "tipsSumm": 0      },      "listStates": [        {          "id": 0,          "name": "string",          "hasMedia": true,          "canAddMedia": true        }      ],      "files": {        "full": {          "url": "string",          "width": 0,          "height": 0,          "size": 0        },        "preview": {          "url": "string",          "width": 0,          "height": 0        },        "thumb": {          "url": "string",          "width": 0,          "height": 0        },        "squarePreview": {          "url": "string",          "width": 0,          "height": 0        }      },      "videoSources": {        "property1": "string",        "property2": "string"      }    }  ],  "author": {},  "canComment": true,  "canEdit": true,  "hasVoting": true,  "voting": [    {      "id": 0,      "text": "string",      "votesCount": 0,      "isSelected": true    }  ]}