| name | Fanvue |
| description | Manage content, chats, subscribers, and earnings on the Fanvue creator platform via OAuth 2.0 API. |
Fanvue API Skill
Integrate with the Fanvue creator platform to manage chats, posts, subscribers, earnings insights, and media content.
Prerequisites
1. Create an OAuth Application
- Go to the Fanvue Developer Portal
- Create a new OAuth application
- Note your Client ID and Client Secret
- Configure your Redirect URI (e.g.,
https://your-app.com/callback)
2. Environment Variables
Set these environment variables:
FANVUE_CLIENT_ID=your_client_id
FANVUE_CLIENT_SECRET=your_client_secret
FANVUE_REDIRECT_URI=https://your-app.com/callback
Authentication
Fanvue uses OAuth 2.0 with PKCE (Proof Key for Code Exchange). All API requests require:
- Authorization Header:
Bearer <access_token>
- API Version Header:
X-Fanvue-API-Version: 2025-06-26
OAuth Scopes
Request these scopes based on your needs:
| Scope | Access |
|---|
openid | OpenID Connect authentication |
offline_access | Refresh token support |
offline | Offline access |
read:self | Read authenticated user profile |
read:chat | Read chat conversations |
write:chat | Send messages, update chats |
read:post | Read posts |
write:post | Create posts |
read:creator | Read subscriber/follower data |
read:media | Read media vault |
write:tracking_links | Manage campaign links |
read:insights | Read earnings/analytics (creator accounts) |
read:subscribers | 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.
Quick Auth Flow
import { randomBytes, createHash } from 'crypto';
const codeVerifier = randomBytes(32).toString('base64url');
const codeChallenge = createHash('sha256')
.update(codeVerifier)
.digest('base64url');
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');
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();
API Base URL
All API requests go to: https://api.fanvue.com
Standard Request Headers
const headers = {
'Authorization': `Bearer ${accessToken}`,
'X-Fanvue-API-Version': '2025-06-26',
'Content-Type': 'application/json',
};
Agent Automation
These workflows are designed for AI agents automating Fanvue creator accounts.
Accessing Images (with Signed URLs)
The basic /media endpoint only returns metadata. To get actual viewable URLs, use the variants query parameter:
const list = await fetch('https://api.fanvue.com/media', { headers });
const { data } = await list.json();
const media = await fetch(
`https://api.fanvue.com/media/${uuid}?variants=main,thumbnail,blurred`,
{ headers }
);
const { variants } = await media.json();
Variant Types:
main - Full resolution original
thumbnail - Optimized preview (smaller)
blurred - Censored version for teasers
Creating a Post with Media
const mediaIds = ['media-uuid-1', 'media-uuid-2'];
const response = await fetch('https://api.fanvue.com/posts', {
method: 'POST',
headers,
body: JSON.stringify({
text: 'Check out my new content! ๐ฅ',
mediaIds,
audience: 'subscribers',
price: null,
publishAt: null,
}),
});
Audience Options:
| Value | Who Can See |
|---|
subscribers | Paid subscribers only |
followers-and-subscribers | Both free followers and subscribers |
Sending Messages with Media
const subs = await fetch('https://api.fanvue.com/creators/list-subscribers', { headers });
const { data: subscribers } = await subs.json();
const vips = await fetch('https://api.fanvue.com/insights/get-top-spenders', { headers });
const { data: topSpenders } = await vips.json();
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'],
}),
});
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'],
}),
});
Agent Decision Context
For effective automation, gather this context:
interface AutomationContext {
media: {
uuid: string;
name: string;
type: 'image' | 'video';
description: string;
signedUrl: string;
}[];
subscribers: {
uuid: string;
name: string;
subscribedAt: string;
tier: string;
}[];
topSpenders: {
uuid: string;
totalSpent: number;
}[];
earnings: {
period: string;
total: number;
breakdown: { type: string; amount: number }[];
};
}
Core Operations
Get Current User
const response = await fetch('https://api.fanvue.com/users/me', { headers });
const user = await response.json();
List Chats
const response = await fetch('https://api.fanvue.com/chats', { headers });
const { data, pagination } = await response.json();
Send a Message
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!',
}),
});
Create a Post
const response = await fetch('https://api.fanvue.com/posts', {
method: 'POST',
headers,
body: JSON.stringify({
content: 'New content available!',
}),
});
Get Earnings
const response = await fetch('https://api.fanvue.com/insights/get-earnings', { headers });
const earnings = await response.json();
List Subscribers
const response = await fetch('https://api.fanvue.com/creators/list-subscribers', { headers });
const { data } = await response.json();
API Reference
See api-reference.md for the complete endpoint documentation.
Token Refresh
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();
Error Handling
Common HTTP status codes:
| Status | Meaning |
|---|
200 | Success |
400 | Bad request - check your parameters |
401 | Unauthorized - token expired or invalid |
403 | Forbidden - missing required scope |
404 | Resource not found |
429 | Rate limited - slow down requests |
Resources