Campaigns
Create and manage engagement campaigns like surveys and polls. Collect feedback from your community and reward participants with NFT rewards.
Prerequisites
- Podium SDK installed and configured
- A merchant profile (see Merchant Setup recipe)
- Understanding of campaign goals and target audience
Campaigns let merchants engage their community through surveys, polls, and interactive experiences. Each campaign can reward participants with NFT-based rewards, creating incentives for engagement. This guide walks through creating a survey campaign to collect product feedback from your customers.
Create a campaign
Start by creating a new campaign with a specific type:
// Campaign types:
// • SURVEY - Collect structured feedback via questions
// • MULTIVARIANT - A/B test product variants with your audience
// • SWIPE - Tinder-style voting on options
// • UGC - User-generated content submissions
const campaign = await client.campaigns.create({
requestBody: {
creatorId: 'creator_xyz', // Your merchant ID
type: 'SURVEY',
},
})
console.log(campaign)
// {
// id: 'campaign_abc123',
// type: 'SURVEY',
// status: 'DRAFT',
// creatorId: 'creator_xyz',
// createdAt: '2025-01-15T...',
// }Configure campaign details
Update the campaign with metadata like dates, participant limits, and reward configuration:
// Configure the campaign
const updatedCampaign = await client.campaigns.replace({
id: campaign.id,
requestBody: {
logo: 'ipfs://QmXxx.../campaign-logo.png',
startDate: '2025-02-01T00:00:00Z',
endDate: '2025-02-28T23:59:59Z',
maxParticipants: 1000,
showLeaderboard: true,
showInstructions: true,
reward: {
points: 50, // Points per participant
maxSupply: 50000, // Total points available
},
},
})
console.log(updatedCampaign)
// {
// id: 'campaign_abc123',
// status: 'DRAFT',
// startDate: '2025-02-01T00:00:00Z',
// endDate: '2025-02-28T23:59:59Z',
// maxParticipants: 1000,
// ...
// }Configure the NFT reward
Set up the NFT metadata that participants will receive as a reward for completing the campaign:
// Configure NFT reward metadata
await client.campaigns.replaceNft({
id: campaign.id,
requestBody: {
name: 'Product Feedback Badge',
description: 'Awarded for sharing your product feedback',
// Image URL typically points to IPFS for on-chain permanence
imageUrl: 'ipfs://QmXxx.../feedback-badge.png',
points: 50,
},
})Publish the campaign
Once configured, publish the campaign to make it live. Set requiresReview to true if your campaign needs admin approval:
// Publish the campaign
const publishedCampaign = await client.campaigns.publish({
id: campaign.id,
requestBody: {
requiresReview: false, // Set to true if admin approval is needed
},
})
console.log(publishedCampaign)
// {
// id: 'campaign_abc123',
// status: 'PUBLISHED',
// ...
// }Get campaign details
Retrieve campaign information including participation stats:
// Get campaign by ID
const campaignDetails = await client.campaigns.get({
id: 'campaign_abc123',
})
console.log(campaignDetails)
// {
// id: 'campaign_abc123',
// type: 'SURVEY',
// status: 'PUBLISHED',
// title: 'Product Feedback Survey',
// participantCount: 142,
// reward: { points: 50, maxSupply: 50000, claimed: 7100 },
// ...
// }List merchant campaigns
Get all campaigns for a merchant with optional status filtering:
// List all campaigns for a merchant
const campaigns = await client.campaigns.list({
creatorId: 'creator_xyz',
statuses: ['PUBLISHED', 'ENDED'], // Optional filter
})
console.log(campaigns)
// {
// data: [
// {
// id: 'campaign_abc123',
// type: 'SURVEY',
// status: 'PUBLISHED',
// participantCount: 142,
// },
// {
// id: 'campaign_def456',
// type: 'SURVEY',
// status: 'ENDED',
// participantCount: 500,
// },
// ],
// total: 2,
// }Archive a campaign
Archive a campaign when it's no longer needed. This is a soft delete that can be restored:
// Archive a campaign (soft delete)
await client.merchantCampaign.delete({
creatorId: 'creator_xyz',
id: 'campaign_abc123',
})
// To restore an archived campaign:
await client.merchantCampaign.restore({
creatorId: 'creator_xyz',
id: 'campaign_abc123',
})Complete Example
Here's a complete working example combining all the steps:
import { createPodiumClient } from '@podiumcommerce/node-sdk'
const client = createPodiumClient({
apiKey: process.env.PODIUM_API_KEY,
})
// Create and launch a product feedback survey
async function createFeedbackSurvey(
creatorId: string,
title: string,
startDate: string,
endDate: string,
rewardPoints: number
) {
// Step 1: Create the campaign
const campaign = await client.campaigns.create({
requestBody: {
creatorId,
type: 'SURVEY',
},
})
console.log('Created campaign:', campaign.id)
// Step 2: Configure campaign details
await client.campaigns.replace({
id: campaign.id,
requestBody: {
startDate,
endDate,
maxParticipants: 1000,
showLeaderboard: true,
reward: {
points: rewardPoints,
maxSupply: rewardPoints * 1000,
},
},
})
// Step 3: Configure NFT reward
await client.campaigns.replaceNft({
id: campaign.id,
requestBody: {
name: `${title} Participant`,
description: 'Thank you for your feedback!',
imageUrl: 'ipfs://QmXxx.../survey-badge.png', // IPFS for permanence
points: rewardPoints,
},
})
// Step 4: Publish
const published = await client.campaigns.publish({
id: campaign.id,
requestBody: { requiresReview: false },
})
console.log('Published campaign:', published.status)
return published
}
// Get campaign analytics
async function getCampaignStats(creatorId: string) {
const campaigns = await client.campaigns.list({
creatorId,
statuses: ['PUBLISHED', 'ENDED'],
})
return {
totalCampaigns: campaigns.total,
activeCampaigns: campaigns.data.filter(c => c.status === 'PUBLISHED').length,
totalParticipants: campaigns.data.reduce(
(sum, c) => sum + (c.participantCount || 0),
0
),
}
}
// Usage
const survey = await createFeedbackSurvey(
'creator_xyz',
'Q1 Product Feedback',
'2025-02-01T00:00:00Z',
'2025-02-28T23:59:59Z',
50
)
const stats = await getCampaignStats('creator_xyz')
console.log('Campaign stats:', stats)Explore the full API
See all available endpoints and parameters in the API reference.
