Back to Docs
API Reference

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.

Request Header
Authorization: Bearer your_access_token

Security 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.created

A new challenge was created

Example Payload
{
  "challenge_id": "ch_123",
  "title": "Summer Remix Challenge",
  "status": "draft"
}
challenge.published

A challenge went live

Example Payload
{
  "challenge_id": "ch_123",
  "title": "Summer Remix Challenge",
  "status": "live",
  "end_at": "2024-12-31T23:59:59Z"
}
entry.submitted

A new entry was submitted to a challenge

Example Payload
{
  "entry_id": "ent_456",
  "challenge_id": "ch_123",
  "youtube_url": "https://youtube.com/...",
  "submitted_at": "2024-01-15T10:30:00Z"
}
entry.approved

An entry was approved by the host

Example Payload
{
  "entry_id": "ent_456",
  "challenge_id": "ch_123",
  "approved_at": "2024-01-15T12:00:00Z"
}
winner.selected

A winner was selected for a challenge

Example Payload
{
  "entry_id": "ent_456",
  "challenge_id": "ch_123",
  "winner_handle": "@artist123",
  "selected_at": "2024-01-20T15:00: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

GET/api/challenges

List all challenges for your account

Auth: Bearer Token

Query Parameters:

status(string)Filter: draft, live, closed
limit(number)Max results (default: 20)
GET/api/challenges/:id

Get challenge details including entry count

Auth: Bearer Token
GET/api/challenges/:id/entries

List entries for a challenge

Auth: Bearer Token

Query Parameters:

status(string)Filter: pending, approved, winner
GET/api/challenges/:id/analytics

Get challenge analytics (views, entries, engagement)

Auth: Bearer Token

Webhooks

Receive real-time notifications for events in your account

POST/api/webhooks/configure

Configure webhook endpoints for your account

Auth: Bearer Token

Request Body:

{
  "url": "https://your-domain.com/webhook",
  "events": [
    "challenge.created",
    "entry.submitted",
    "winner.selected"
  ],
  "secret": "whsec_..."
}
GET/api/webhooks/deliveries

List recent webhook delivery attempts

Auth: Bearer Token

Query Parameters:

limit(number)Max results (default: 50)
status(string)Filter by status: success, failed, pending
POST/api/webhooks/test

Send a test webhook to verify your endpoint

Auth: Bearer Token

Request Body:

{
  "endpoint_id": "wh_endpoint_123",
  "event_type": "test.ping"
}

Profile

Manage your public profile and analytics

GET/api/profile

Get your profile details

Auth: Bearer Token
GET/api/profile/analytics

Get profile analytics (views, clicks, engagement)

Auth: Bearer Token

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('collab_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: 'collab_challenge_entry' },
    (payload) => console.log('New entry:', payload.new)
  )
  .subscribe();

Fetch API Example

// Fetch challenges (JavaScript)
const response = await fetch('https://api.collab.newfanspro.com/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.