API & Webhooks
Integrate NewFans Collab into your workflow with our REST API and real-time webhooks.
Authentication
All API requests require authentication using a Bearer token. You can obtain your access token from the Supabase auth session.
Authorization: Bearer your_access_tokenSecurity Note
Never expose your access tokens in client-side code. Use server-side API calls or Supabase's built-in RLS policies for secure data access.
Webhook Events
Subscribe to webhook events to receive real-time notifications when actions occur in your account.
challenge.createdA new challenge was created
{
"challenge_id": "ch_123",
"title": "Summer Remix Challenge",
"status": "draft"
}challenge.publishedA challenge went live
{
"challenge_id": "ch_123",
"title": "Summer Remix Challenge",
"status": "live",
"end_at": "2024-12-31T23:59:59Z"
}entry.submittedA new entry was submitted to a challenge
{
"entry_id": "ent_456",
"challenge_id": "ch_123",
"youtube_url": "https://youtube.com/...",
"submitted_at": "2024-01-15T10:30:00Z"
}entry.approvedAn entry was approved by the host
{
"entry_id": "ent_456",
"challenge_id": "ch_123",
"approved_at": "2024-01-15T12:00:00Z"
}winner.selectedA winner was selected for a challenge
{
"entry_id": "ent_456",
"challenge_id": "ch_123",
"winner_handle": "@artist123",
"selected_at": "2024-01-20T15:00:00Z"
}drop.submissionA fan submitted a Drop form
{
"drop_id": "drp_123",
"email": "fan@example.com",
"submitted_at": "2024-01-15T10:30:00Z"
}mixtape.claimedA fan claimed a free mixtape
{
"drop_id": "drp_123",
"claim_id": "clm_456",
"email": "fan@example.com",
"claimed_at": "2024-01-15T10:30:00Z"
}Webhook Signature Verification
Always verify webhook signatures to ensure requests are from NewFans Collab.
// Verify webhook signature (Node.js)
import crypto from 'crypto';
function verifyWebhook(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(`sha256=${expectedSignature}`)
);
}
// In your webhook handler
app.post('/webhook', (req, res) => {
const signature = req.headers['x-newfans-signature'];
const isValid = verifyWebhook(
JSON.stringify(req.body),
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the webhook
const { event, data } = req.body as { event: string; data: unknown };
console.log(`Received ${event}:`, data);
res.status(200).json({ received: true });
});API Endpoints
Challenges
Manage Open Verse Challenges programmatically
/api/challengesList all challenges for your account
Query Parameters:
status(string)Filter: draft, live, closedlimit(number)Max results (default: 20)/api/challenges/:idGet challenge details including entry count
/api/challenges/:id/entriesList entries for a challenge
Query Parameters:
status(string)Filter: pending, approved, winner/api/challenges/:id/analyticsGet challenge analytics (views, entries, engagement)
Drops
Manage Drops and form submissions
/api/dropsList all Drops for your account
Query Parameters:
status(string)Filter: draft, active, inactivetype(string)Filter: free_download, waitlist, free_event, free_mixtape/api/drops/:id/submissionsList form submissions for a Drop
Query Parameters:
limit(number)Max results (default: 100)offset(number)Pagination offset/api/drops/:id/exportExport submissions as CSV (Launch/Creator plans)
/api/drops/:id/analyticsGet drop analytics (views, submissions, conversion)
Webhooks
Receive real-time notifications for events in your account
/api/webhooks/configureConfigure webhook endpoints for your account
Request Body:
{
"url": "https://your-domain.com/webhook",
"events": [
"challenge.created",
"entry.submitted",
"winner.selected"
],
"secret": "whsec_..."
}/api/webhooks/deliveriesList recent webhook delivery attempts
Query Parameters:
limit(number)Max results (default: 50)status(string)Filter by status: success, failed, pending/api/webhooks/testSend a test webhook to verify your endpoint
Request Body:
{
"endpoint_id": "wh_endpoint_123",
"event_type": "test.ping"
}Profile
Manage your public profile and analytics
/api/profileGet your profile details
/api/profile/analyticsGet profile analytics (views, clicks, engagement)
Query Parameters:
start_date(string)ISO date (YYYY-MM-DD)end_date(string)ISO date (YYYY-MM-DD)Code Examples
Using Supabase Client (Recommended)
// Using Supabase client (recommended)
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
);
// Fetch challenges
const { data: challenges, error } = await supabase
.from('challenge')
.select('*')
.eq('status', 'live')
.order('created_at', { ascending: false });
// Subscribe to real-time updates
supabase
.channel('challenges')
.on('postgres_changes',
{ event: 'INSERT', schema: 'public', table: 'challenge_entries' },
(payload) => console.log('New entry:', payload.new)
)
.subscribe();Fetch API Example
// Fetch challenges (JavaScript)
const response = await fetch('https://api.newfans.video/api/challenges', {
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
});
const { challenges } = await response.json();
console.log(challenges);Rate Limits
100
Requests per minute
1,000
Requests per hour
10,000
Requests per day
Rate limits are applied per user. If you need higher limits, contact support.
Need help with integration?
Check out our webhook documentation or reach out to our support team for assistance.