Dynamic Badges Documentation

Everything you need to integrate blockchain-powered loyalty badges

Get Started →

Quick Start

5 minutes to integrate

Get started with Dynamic Badges in just 5 minutes. Follow these simple steps to add loyalty badges to your application.

1

Install the SDK

(30 seconds)

Install the Blockquest Badges SDK using your preferred package manager:

npm install @blockquest/badges
2

Initialize the Client

(1 minute)

Create a new instance of the SDK with your API key:

import { BlockquestBadges } from '@blockquest/badges';

const badges = new BlockquestBadges({
  apiKey: 'YOUR_API_KEY',
  baseUrl: 'https://dynamic-badges.vercel.app/api'
});

💡 Tip: Your API key will be automatically filled in once you're logged in. See the API Keys section below.

3

Mint Your First Badge

(2 minutes)

Use the smartMint method to award a badge:

// Smart mint - automatically handles new vs returning users
const result = await badges.smartMint({
  campaignId: 'your-campaign-id',
  userEmail: 'user@example.com',
  tier: 1,
  metadata: {
    source: 'signup',
    timestamp: new Date().toISOString()
  }
});

if (result.success) {
  console.log('Badge minted!', result.data);
}

🎯 Smart Minting

The SDK automatically handles new vs returning users. New users get a claim link via email, while returning users with wallets get badges minted directly!

4

Use Event Triggers (Optional)

(1 minute)

For even simpler integration, use event-based triggers:

// Trigger a badge claim for a campaign
await badges.trigger('your-campaign-id', {
  userEmail: 'user@example.com',
  tier: 1,
  eventType: 'user_completed_onboarding',
  metadata: {
    completedAt: new Date().toISOString()
  }
});
5

Test It Out

(30 seconds)

Verify that everything is working:

// Verify the badge was minted
const badge = await badges.getUserBadge({
  campaignId: 'your-campaign-id',
  userEmail: 'user@example.com'
});

console.log('User badge:', badge.data);

🎉 You're all set!

You've successfully integrated Dynamic Badges. Your users can now earn loyalty badges!

Next steps:

API Reference

Complete reference for all Dynamic Badges API endpoints. All examples use the SDK, but you can also call the REST API directly.

Base URL: https://dynamic-badges.vercel.app/api

Smart Mint

Intelligently mint badges by automatically choosing between direct minting (for returning users) or creating claim links (for new users).

Endpoint

POST /badges/mint-smart

SDK Usage

const result = await badges.smartMint({
  campaignId: 'campaign-uuid',
  userEmail: 'user@example.com',
  tier: 1,
  metadata: {
    source: 'signup',
    timestamp: new Date().toISOString()
  }
});

if (result.success) {
  if (result.data.flow === 'direct_mint') {
    console.log('Badge minted to wallet:', result.data.badge.wallet_address);
  } else {
    console.log('Claim link sent:', result.data.claim_url);
  }
}

Parameters

ParameterTypeRequiredDescription
campaignIdstringYesUUID of the campaign
userEmailstringYesUser's email address
tiernumberNoBadge tier (default: 1)
metadataobjectNoAdditional event data

Response

{
  "success": true,
  "flow": "claim_link", // or "direct_mint"
  "message": "Claim link created for new user",
  "claim_url": "https://dynamic-badges.vercel.app/claim?code=ABC123",
  "claim_code": "ABC123",
  "user_status": "new_user" // or "returning_user"
}

Trigger

Award badges based on event names. The system automatically maps events to campaigns, making integration even simpler.

Endpoint

POST /badges/trigger-claim

SDK Usage

// Trigger a badge claim for a campaign
await badges.trigger('campaign-uuid', {
  userEmail: 'user@example.com',
  tier: 1,
  eventType: 'user_completed_onboarding',
  metadata: {
    completedAt: new Date().toISOString(),
    steps: 5
  }
});

💡 Pro Tip: Event triggers are perfect for common actions like signups, purchases, or milestones. No need to hardcode campaign IDs!

Upgrade Badge

Upgrade a user's existing badge to a higher tier. Perfect for loyalty programs and progressive achievements.

Endpoint

POST /badges/upgrade

SDK Usage

const result = await badges.upgrade({
  campaignId: 'campaign-uuid',
  userEmail: 'user@example.com',
  newTier: 2
});

if (result.success) {
  console.log('Badge upgraded to tier', result.data.current_tier);
}

Get User Badge

Retrieve a specific badge for a user in a campaign.

Endpoint

GET /badges/claim?campaignId=...&userWalletAddress=...

SDK Usage

const result = await badges.getUserBadge({
  campaignId: 'campaign-uuid',
  userEmail: 'user@example.com'
});

if (result.success && result.data) {
  console.log('User has tier', result.data.tier, 'badge');
}

Verify Badge

Verify if a user owns a specific badge. Returns a simple boolean.

SDK Usage

const hasBadge = await badges.verifyBadge({
  campaignId: 'campaign-uuid',
  userEmail: 'user@example.com'
});

if (hasBadge) {
  console.log('User has this badge!');
}

Webhooks

Receive real-time notifications when badges are minted, upgraded, or claimed.

Setup

Configure your webhook URL in the dashboard settings. We'll send POST requests to your endpoint whenever badge events occur.

Event Types

  • badge.minted- Fired when a badge is minted
  • badge.upgraded- Fired when a badge is upgraded
  • badge.claimed- Fired when a claim link is used

Payload Example

{
  "event": "badge.minted",
  "timestamp": "2026-01-18T20:00:00Z",
  "data": {
    "badge_id": "badge-uuid",
    "campaign_id": "campaign-uuid",
    "campaign_name": "Loyalty Program",
    "user_email": "user@example.com",
    "user_wallet_address": "0x1234...",
    "tier_level": 1,
    "tier_name": "Bronze",
    "transaction_hash": "0xabc..."
  }
}

AI IDE Templates

Ready-to-use templates and prompts for AI-powered IDEs like Lovable, Bolt, and Cursor. Copy and paste these to integrate Dynamic Badges in minutes.

🤖 AI-Powered Integration: These templates are optimized for AI IDEs. Just paste them into your AI assistant and it will handle the integration!

Lovable Template

Complete integration guide for Lovable.dev projects. Copy this entire template and paste it into Lovable's chat.

# Dynamic Badges Integration for Lovable

## Quick Setup

1. Install the SDK:
```bash
npm install @blockquest/badges
```

2. Create a badges service file:
```typescript
// src/services/badges.ts
import { BlockquestBadges } from '@blockquest/badges';

export const badges = new BlockquestBadges({
  apiKey: process.env.BLOCKQUEST_API_KEY!,
  baseUrl: 'https://dynamic-badges.vercel.app/api'
});
```

3. Use in your components:
```typescript
import { badges } from '@/services/badges';

// Award a badge on signup
async function handleSignup(email: string) {
  await badges.smartMint({
    campaignId: 'your-campaign-id',
    userEmail: email,
    tier: 1
  });
}
```

## Environment Variables
Add to your `.env`:
```
BLOCKQUEST_API_KEY=your_api_key_here
```

💡 Lovable Tip: After pasting, tell Lovable: "Implement this Dynamic Badges integration and award a badge when users sign up."

Bolt Template

React component template for Bolt.new. This component handles badge awarding with loading states and success messages.

// Bolt.new Component Template
// Copy this into your Bolt project

import { useState, useEffect } from 'react';
import { BlockquestBadges } from '@blockquest/badges';

const badges = new BlockquestBadges({
  apiKey: import.meta.env.VITE_BLOCKQUEST_API_KEY,
  baseUrl: 'https://dynamic-badges.vercel.app/api'
});

export function BadgeAward({ userEmail, campaignId }) {
  const [loading, setLoading] = useState(false);
  const [success, setSuccess] = useState(false);

  const awardBadge = async () => {
    setLoading(true);
    try {
      const result = await badges.smartMint({
        campaignId,
        userEmail,
        tier: 1
      });
      
      if (result.success) {
        setSuccess(true);
      }
    } catch (error) {
      console.error('Failed to award badge:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <button 
      onClick={awardBadge}
      disabled={loading || success}
      className="px-4 py-2 bg-blue-600 text-white rounded-lg"
    >
      {success ? '✓ Badge Awarded!' : loading ? 'Awarding...' : 'Award Badge'}
    </button>
  );
}

💡 Bolt Tip: Add this to your .env file:

VITE_BLOCKQUEST_API_KEY=your_api_key_here

Cursor Rules

Add these rules to your .cursorrules file to help Cursor AI understand how to work with Dynamic Badges.

# Cursor AI Rules for Dynamic Badges

## Project Context
This project uses Dynamic Badges (@blockquest/badges) for user loyalty and gamification.

## Code Style
- Use TypeScript for type safety
- Async/await for all badge operations
- Handle errors gracefully with try/catch
- Log badge events for debugging

## Common Patterns

### Award Badge on User Action
```typescript
// After successful signup/purchase/milestone
await badges.smartMint({
  campaignId: 'campaign-id',
  userEmail: user.email,
  tier: 1,
  metadata: { source: 'action-name' }
});
```

### Check Badge Ownership
```typescript
const hasBadge = await badges.verifyBadge({
  campaignId: 'campaign-id',
  userEmail: user.email
});

if (hasBadge) {
  // Show premium features
}
```

### Upgrade Badge Tier
```typescript
await badges.upgrade({
  campaignId: 'campaign-id',
  userEmail: user.email,
  newTier: 2
});
```

## Best Practices
1. Always use environment variables for API keys
2. Handle both direct_mint and claim_link flows
3. Add loading states for badge operations
4. Show success/error messages to users
5. Cache badge status to reduce API calls

## Error Handling
```typescript
try {
  await badges.smartMint({ ... });
} catch (error) {
  if (error instanceof AuthenticationError) {
    // Invalid API key
  } else if (error instanceof ValidationError) {
    // Missing required fields
  } else {
    // Other errors
  }
}
```

✅ Setup: Create a .cursorrules file in your project root and paste these rules. Cursor will now understand Dynamic Badges patterns!

Prompt Library

Copy-paste prompts for common Dynamic Badges integration tasks. Works with any AI IDE (Lovable, Bolt, Cursor, Windsurf, etc.).

# AI Prompt Library for Dynamic Badges

## Prompt 1: Add Badge System to Existing App
"Add Dynamic Badges integration to this app. Install @blockquest/badges, create a badges service with API key from env, and award a badge when users complete [ACTION]. Handle both new users (claim link) and returning users (direct mint)."

## Prompt 2: Create Badge Award Component
"Create a React component that awards a badge using @blockquest/badges. It should:
- Take userEmail and campaignId as props
- Show loading state while minting
- Display success message with claim link or wallet address
- Handle errors gracefully
- Use Tailwind for styling"

## Prompt 3: Add Badge Verification
"Add badge verification to check if user has completed [MILESTONE]. Use @blockquest/badges verifyBadge method. If user has badge, show [PREMIUM_FEATURE], otherwise show upgrade prompt."

## Prompt 4: Implement Loyalty Tiers
"Implement a 3-tier loyalty system using Dynamic Badges:
- Bronze: After first purchase
- Silver: After 5 purchases
- Gold: After 10 purchases
Use the upgrade method to progress users through tiers."

## Prompt 5: Add Badge Display
"Create a user profile section that displays all badges earned using getUserBadges. Show badge tier, campaign name, and earned date. Make it visually appealing with icons and colors."

## Prompt 6: Event-Based Triggers
"Set up event-based badge triggers for:
- user_signup
- first_purchase
- profile_completed
- referral_made
Use the trigger method instead of hardcoding campaign IDs."

## Prompt 7: Webhook Handler
"Create a webhook endpoint to receive badge events from Dynamic Badges. Handle badge.minted, badge.upgraded, and badge.claimed events. Update user records and send notifications."

## Prompt 8: Badge Analytics Dashboard
"Create an admin dashboard showing badge statistics:
- Total badges minted
- Badges by campaign
- Recent badge activity
- User badge distribution
Fetch data using the API and display with charts."

🎯 For Beginners

Start with Prompt 1 or 2 to add basic badge functionality to your app.

🚀 For Advanced Users

Use Prompts 4-8 for loyalty systems, webhooks, and analytics dashboards.

Examples & Use Cases

Real-world examples showing how to integrate Dynamic Badges into different types of applications. Copy and adapt these patterns for your use case.

SaaS Integration

Complete example for a SaaS application with onboarding badges, milestone tracking, and premium access control.

Use Cases:

  • Award "Onboarding Champion" badge when users sign up
  • Track profile completion with badges
  • Upgrade "Power User" badge based on activity
  • Gate premium features behind badge ownership
// SaaS Onboarding Example
import { BlockquestBadges } from '@blockquest/badges';

const badges = new BlockquestBadges({
  apiKey: 'YOUR_API_KEY',
  baseUrl: 'https://dynamic-badges.vercel.app/api'
});

// Award badge on signup
async function handleUserSignup(email) {
  await badges.smartMint({
    campaignId: 'onboarding-champion',
    userEmail: email,
    tier: 1,
    metadata: { source: 'signup' }
  });
}

// Award badge on profile completion
async function handleProfileCompleted(email) {
  await badges.trigger('profile_completed', {
    userEmail: email,
    metadata: { completedAt: new Date().toISOString() }
  });
}

// Upgrade badge on milestone
async function handleMilestone(email, milestoneCount) {
  const tier = milestoneCount >= 10 ? 3 : milestoneCount >= 5 ? 2 : 1;
  
  await badges.upgrade({
    campaignId: 'power-user',
    userEmail: email,
    newTier: tier
  });
}

// Check for premium access
async function checkPremiumAccess(email) {
  const hasPremiumBadge = await badges.verifyBadge({
    campaignId: 'premium-member',
    userEmail: email
  });
  
  return hasPremiumBadge;
}

💡 Pro Tip: Use event triggers for common actions to avoid hardcoding campaign IDs. This makes your code more maintainable!

KOL Campaign

Perfect for influencers, content creators, and community builders who want to reward their audience with collectible badges.

Use Cases:

  • Award badges to event attendees (conferences, meetups)
  • Create VIP badges for top supporters
  • Distribute badges via QR codes at physical events
  • Track and display all badges earned by followers
// KOL Campaign Example
import { BlockquestBadges } from '@blockquest/badges';

const badges = new BlockquestBadges({
  apiKey: 'YOUR_API_KEY',
  baseUrl: 'https://dynamic-badges.vercel.app/api'
});

// Award badge to event attendee
async function awardEventBadge(attendeeEmail, eventName) {
  const result = await badges.smartMint({
    campaignId: 'event-attendee-2024',
    userEmail: attendeeEmail,
    tier: 1,
    metadata: {
      eventName,
      attendedAt: new Date().toISOString()
    }
  });
  
  if (result.success) {
    if (result.data.flow === 'claim_link') {
      // Send claim link to attendee
      console.log('Claim URL:', result.data.claim_url);
      // Email or SMS this to the attendee
    } else {
      console.log('Badge minted to:', result.data.badge.wallet_address);
    }
  }
}

// Award VIP badge to top supporters
async function awardVipBadge(supporterEmail) {
  await badges.smartMint({
    campaignId: 'vip-supporter',
    userEmail: supporterEmail,
    tier: 3, // Gold tier
    metadata: {
      vipLevel: 'gold',
      awardedAt: new Date().toISOString()
    }
  });
}

// Get all badges for a user
async function getUserBadges(email) {
  const result = await badges.getUserBadges(email);
  
  if (result.success) {
    console.log(`User has ${result.data.length} badges`);
    return result.data;
  }
}

🎯 KOL Tip: Generate QR codes for your campaigns and display them at events. Attendees can scan to claim their badges instantly!

E-commerce Loyalty

Build a complete loyalty program with tiered rewards, purchase tracking, and discount eligibility based on badge ownership.

Use Cases:

  • Award "First Purchase" badge to new customers
  • 3-tier loyalty system (Bronze, Silver, Gold)
  • Automatic tier upgrades based on purchase count
  • Discount eligibility based on badge tier
  • Referral badges for customer acquisition
// E-commerce Loyalty Example
import { BlockquestBadges } from '@blockquest/badges';

const badges = new BlockquestBadges({
  apiKey: 'YOUR_API_KEY',
  baseUrl: 'https://dynamic-badges.vercel.app/api'
});

// Award badge on first purchase
async function handleFirstPurchase(customerEmail, orderId, amount) {
  await badges.smartMint({
    campaignId: 'first-purchase',
    userEmail: customerEmail,
    tier: 1,
    metadata: {
      orderId,
      amount,
      purchaseDate: new Date().toISOString()
    }
  });
}

// Loyalty tier system based on total purchases
async function updateLoyaltyTier(customerEmail, totalPurchases) {
  let tier = 1; // Bronze
  let campaignId = 'loyalty-program';
  
  if (totalPurchases >= 10) {
    tier = 3; // Gold
  } else if (totalPurchases >= 5) {
    tier = 2; // Silver
  }
  
  // Check if user has badge
  const existingBadge = await badges.getUserBadge({
    campaignId,
    userEmail: customerEmail
  });
  
  if (existingBadge.success && existingBadge.data) {
    // Upgrade existing badge
    if (existingBadge.data.tier < tier) {
      await badges.upgrade({
        campaignId,
        userEmail: customerEmail,
        newTier: tier
      });
    }
  } else {
    // Mint new badge
    await badges.smartMint({
      campaignId,
      userEmail: customerEmail,
      tier,
      metadata: { totalPurchases }
    });
  }
}

// Check for loyalty discount eligibility
async function checkDiscountEligibility(customerEmail) {
  const badge = await badges.getUserBadge({
    campaignId: 'loyalty-program',
    userEmail: customerEmail
  });
  
  if (badge.success && badge.data) {
    // Gold tier gets 20% off, Silver 10%, Bronze 5%
    const discounts = { 3: 0.20, 2: 0.10, 1: 0.05 };
    return discounts[badge.data.tier] || 0;
  }
  
  return 0;
}

// Award referral badge
async function handleReferral(referrerEmail, referredEmail) {
  await badges.trigger('referral_made', {
    userEmail: referrerEmail,
    metadata: {
      referredEmail,
      referredAt: new Date().toISOString()
    }
  });
}

💰 E-commerce Tip: Offer exclusive discounts to badge holders. Gold tier = 20% off, Silver = 10%, Bronze = 5%. This drives repeat purchases!

Widget & QR Codes

Embed badge displays on your website or generate QR codes for physical events.

Embeddable Widget

Display user badges on your website with our embeddable widget. No backend required!

<!-- Add this to your HTML -->
<div id="blockquest-badges" data-email="user@example.com"></div>

<script src="https://dynamic-badges.vercel.app/widget.js"></script>
<script>
  BlockquestWidget.init({
    apiKey: 'YOUR_API_KEY',
    theme: 'light', // or 'dark'
    layout: 'grid' // or 'list'
  });
</script>

Coming Soon: The embeddable widget is currently in development. Use the SDK for now to fetch and display badges.

QR Code Generation

Generate QR codes for your campaigns to distribute badges at physical events.

Generate via Dashboard

  1. Go to your campaign page in the dashboard
  2. Click "Generate QR Code"
  3. Download as PNG or SVG
  4. Print and display at your event

Generate via API

GET /api/campaigns/{campaignId}/qr-code?format=png

Response: QR code image file

🎯 Use Case: Print QR codes on posters, badges, or swag at conferences. Attendees scan to claim their badge instantly!

FAQ & Troubleshooting

Common questions and solutions. Can't find what you're looking for? Contact support

Common Issues

❌ "Invalid API key" error

Solution: Check that your API key is correct and hasn't been regenerated. Make sure you're using the Bearer token format in the Authorization header.

❌ "Rate limit exceeded" error

Solution: You've hit your hourly rate limit. Wait for the reset time (shown in the error) or upgrade to Pro for higher limits.

❌ Badge not showing up

Solution: If using claim link flow, the badge won't be minted until the user claims it. Check the claim status in your dashboard.

❌ "Campaign not found" error

Solution: Verify the campaign ID is correct and the campaign belongs to your business. Campaign IDs are UUIDs, not names.

❌ Webhook not receiving events

Solution: Ensure your webhook URL is publicly accessible (not localhost). Check that your endpoint returns a 200 status code. View webhook logs in the dashboard.

Need More Help?

Our support team is here to help you succeed with Dynamic Badges.

Email: support@blockquest.com

Response Time: Usually within 2 hours during business hours

Discord: Join our community

Ready to integrate?

Sign up to get your API key and start minting badges.

Get Started Free