Fanvue
Manage content, chats, subscribers, and earnings on the Fanvue creator platform via OAuth 2.0 API.
Manage content, chats, subscribers, and earnings on the Fanvue creator platform via OAuth 2.0 API.
Real data. Real impact.
Growing
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
Integrate with the Fanvue creator platform to manage chats, posts, subscribers, earnings insights, and media content.
https://your-app.com/callback)Set these environment variables:
FANVUE_CLIENT_ID=your_client_id FANVUE_CLIENT_SECRET=your_client_secret FANVUE_REDIRECT_URI=https://your-app.com/callback
Fanvue uses OAuth 2.0 with PKCE (Proof Key for Code Exchange). All API requests require:
Bearer <access_token>X-Fanvue-API-Version: 2025-06-26Request these scopes based on your needs:
| Scope | Access |
|---|---|
| OpenID Connect authentication |
| Refresh token support |
| Offline access |
| Read authenticated user profile |
| Read chat conversations |
| Send messages, update chats |
| Read posts |
| Create posts |
| Read subscriber/follower data |
| Read media vault |
| Manage campaign links |
| Read earnings/analytics (creator accounts) |
| Read subscriber lists (creator accounts) |
Note: Some endpoints (subscribers, insights, earnings) require a creator account and may need additional scopes not listed in the public documentation.
import { randomBytes, createHash } from 'crypto';// 1. Generate PKCE parameters const codeVerifier = randomBytes(32).toString('base64url'); const codeChallenge = createHash('sha256') .update(codeVerifier) .digest('base64url');
// 2. Build authorization URL const authUrl = new URL('https://auth.fanvue.com/oauth2/auth'); authUrl.searchParams.set('client_id', process.env.FANVUE_CLIENT_ID); authUrl.searchParams.set('redirect_uri', process.env.FANVUE_REDIRECT_URI); authUrl.searchParams.set('response_type', 'code'); authUrl.searchParams.set('scope', 'openid offline_access read:self read:chat write:chat read:post'); authUrl.searchParams.set('state', randomBytes(32).toString('hex')); authUrl.searchParams.set('code_challenge', codeChallenge); authUrl.searchParams.set('code_challenge_method', 'S256');
// Redirect user to: authUrl.toString()
// 3. Exchange authorization code for tokens const tokenResponse = await fetch('https://auth.fanvue.com/oauth2/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ grant_type: 'authorization_code', client_id: process.env.FANVUE_CLIENT_ID, client_secret: process.env.FANVUE_CLIENT_SECRET, code: authorizationCode, redirect_uri: process.env.FANVUE_REDIRECT_URI, code_verifier: codeVerifier, }), }); const tokens = await tokenResponse.json(); // tokens.access_token, tokens.refresh_token
All API requests go to:
https://api.fanvue.com
const headers = { 'Authorization': `Bearer ${accessToken}`, 'X-Fanvue-API-Version': '2025-06-26', 'Content-Type': 'application/json', };
These workflows are designed for AI agents automating Fanvue creator accounts.
The basic
/media endpoint only returns metadata. To get actual viewable URLs, use the variants query parameter:
// Step 1: List all media const list = await fetch('https://api.fanvue.com/media', { headers }); const { data } = await list.json();// Step 2: Get signed URLs for a specific media item const media = await fetch(
, { headers } ); const { variants } = await media.json();https://api.fanvue.com/media/${uuid}?variants=main,thumbnail,blurred// variants = [ // { variantType: 'main', url: 'https://media.fanvue.com/private/...' }, // { variantType: 'thumbnail', url: '...' }, // { variantType: 'blurred', url: '...' } // ]
Variant Types:
main - Full resolution originalthumbnail - Optimized preview (smaller)blurred - Censored version for teasers// Step 1: Have existing media UUIDs from vault const mediaIds = ['media-uuid-1', 'media-uuid-2'];// Step 2: Create post const response = await fetch('https://api.fanvue.com/posts', { method: 'POST', headers, body: JSON.stringify({ text: 'Check out my new content! ๐ฅ', mediaIds, audience: 'subscribers', // or 'followers-and-subscribers' // Optional: price: null, // Set for pay-per-view publishAt: null, // Set for scheduled posts }), });
Audience Options:
| Value | Who Can See |
|---|---|
| Paid subscribers only |
| Both free followers and subscribers |
// Get subscriber list for decision making const subs = await fetch('https://api.fanvue.com/creators/list-subscribers', { headers }); const { data: subscribers } = await subs.json();// Get top spenders for VIP targeting const vips = await fetch('https://api.fanvue.com/insights/get-top-spenders', { headers }); const { data: topSpenders } = await vips.json();
// Send personalized message with media await fetch('https://api.fanvue.com/chat-messages', { method: 'POST', headers, body: JSON.stringify({ recipientUuid: subscribers[0].userUuid, content: 'Thanks for being a subscriber! Here's something special for you ๐', mediaIds: ['vault-media-uuid'], // Attach media from vault }), });
// Or send to multiple subscribers at once await fetch('https://api.fanvue.com/chat-messages/mass', { method: 'POST', headers, body: JSON.stringify({ recipientUuids: subscribers.map(s => s.userUuid), content: 'New exclusive content just dropped! ๐', mediaIds: ['vault-media-uuid'], }), });
For effective automation, gather this context:
interface AutomationContext { // Current media in vault media: { uuid: string; name: string; type: 'image' | 'video'; description: string; // AI-generated caption signedUrl: string; // From variants query }[];// Audience data subscribers: { uuid: string; name: string; subscribedAt: string; tier: string; }[];
// Engagement signals topSpenders: { uuid: string; totalSpent: number; }[];
// Recent earnings for trend analysis earnings: { period: string; total: number; breakdown: { type: string; amount: number }[]; }; }
const response = await fetch('https://api.fanvue.com/users/me', { headers }); const user = await response.json();
const response = await fetch('https://api.fanvue.com/chats', { headers }); const { data, pagination } = await response.json();
const response = await fetch('https://api.fanvue.com/chat-messages', { method: 'POST', headers, body: JSON.stringify({ recipientUuid: 'user-uuid-here', content: 'Hello! Thanks for subscribing!', }), });
const response = await fetch('https://api.fanvue.com/posts', { method: 'POST', headers, body: JSON.stringify({ content: 'New content available!', // Add media IDs, pricing, etc. }), });
const response = await fetch('https://api.fanvue.com/insights/get-earnings', { headers }); const earnings = await response.json();
const response = await fetch('https://api.fanvue.com/creators/list-subscribers', { headers }); const { data } = await response.json();
See api-reference.md for the complete endpoint documentation.
Access tokens expire. Use the refresh token to get new ones:
const response = await fetch('https://auth.fanvue.com/oauth2/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ grant_type: 'refresh_token', client_id: process.env.FANVUE_CLIENT_ID, client_secret: process.env.FANVUE_CLIENT_SECRET, refresh_token: currentRefreshToken, }), });const newTokens = await response.json();
Common HTTP status codes:
| Status | Meaning |
|---|---|
| Success |
| Bad request - check your parameters |
| Unauthorized - token expired or invalid |
| Forbidden - missing required scope |
| Resource not found |
| Rate limited - slow down requests |
No automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
ยฉ 2026 Torly.ai. All rights reserved.