Fanvue

Manage content, chats, subscribers, and earnings on the Fanvue creator platform via OAuth 2.0 API.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "Fanvue" with this command: npx skills add igorls/fanvue

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

  1. Go to the Fanvue Developer Portal
  2. Create a new OAuth application
  3. Note your Client ID and Client Secret
  4. 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:

ScopeAccess
openidOpenID Connect authentication
offline_accessRefresh token support
offlineOffline access
read:selfRead authenticated user profile
read:chatRead chat conversations
write:chatSend messages, update chats
read:postRead posts
write:postCreate posts
read:creatorRead subscriber/follower data
read:mediaRead media vault
write:tracking_linksManage campaign links
read:insightsRead earnings/analytics (creator accounts)
read:subscribersRead 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';

// 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

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:

// 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(
  `https://api.fanvue.com/media/${uuid}?variants=main,thumbnail,blurred`, 
  { headers }
);
const { variants } = await media.json();

// variants = [
//   { variantType: 'main', url: 'https://media.fanvue.com/private/...' },
//   { variantType: 'thumbnail', url: '...' },
//   { variantType: 'blurred', url: '...' }
// ]

Variant Types:

  • main - Full resolution original
  • thumbnail - Optimized preview (smaller)
  • blurred - Censored version for teasers

Creating a Post with Media

// 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:

ValueWho Can See
subscribersPaid subscribers only
followers-and-subscribersBoth free followers and subscribers

Sending Messages with Media

// 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'],
  }),
});

Agent Decision Context

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 }[];
  };
}

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!',
    // Add media IDs, pricing, etc.
  }),
});

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:

StatusMeaning
200Success
400Bad request - check your parameters
401Unauthorized - token expired or invalid
403Forbidden - missing required scope
404Resource not found
429Rate limited - slow down requests

Resources

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Maintenance

Maintenance makes home management simple. Record, search, and analyze your data with clear terminal output.

Registry SourceRecently Updated
General

ManualExpert

Professional translator for hardware and technical manuals delivering complete, page-by-page bilingual tables and Word exports for accurate DTP preparation.

Registry SourceRecently Updated
General

Semantic Router

让 AI 代理根据对话内容自动选择最合适的模型。四层识别(系统过滤→关键词→指示词→语义相似度),四池架构(高速/智能/人文/代理),五分支路由,全自动 Fallback 回路。支持 trigger_groups_all 非连续词组命中。

Registry SourceRecently Updated
General

Campaign

Campaign - command-line tool for everyday use

Registry SourceRecently Updated