Back to recipes
Intermediate · 15 min

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.

1

Create a campaign

Start by creating a new campaign with a specific type:

campaigns.ts
// 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...',
// }
2

Configure campaign details

Update the campaign with metadata like dates, participant limits, and reward configuration:

campaigns.ts
// 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,
//   ...
// }
3

Configure the NFT reward

Set up the NFT metadata that participants will receive as a reward for completing the campaign:

campaigns.ts
// 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,
  },
})
4

Publish the campaign

Once configured, publish the campaign to make it live. Set requiresReview to true if your campaign needs admin approval:

campaigns.ts
// 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',
//   ...
// }
5

Get campaign details

Retrieve campaign information including participation stats:

campaigns.ts
// 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 },
//   ...
// }
6

List merchant campaigns

Get all campaigns for a merchant with optional status filtering:

campaigns.ts
// 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,
// }
7

Archive a campaign

Archive a campaign when it's no longer needed. This is a soft delete that can be restored:

campaigns.ts
// 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:

complete-example.ts
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.

API Docs