[Wishlist] Bulk select and verify email for all members at once in dashboard

Post author
Teresa K.

Would like to be able to select ALL members from the list in the dashboard and then be able to verify the email for all members at one time.

Comments

2 comments

  • Comment author
    Duncan from Memberstack
    • Edited

    Agreed! No ETA, but I can see how this would be a huge time saver. 

    0
  • Comment author
    Ramkumar T

    Three Implementation Options:

    • Node.js Backend - Uses the Memberstack Admin Package. Most secure since your API key stays on your server. Ideal if you have a Node.js backend.
    • REST API - Uses HTTP requests directly to the Admin API. Works with any backend language. Includes pagination to handle large member lists.
    • Specific Members - Verify only selected members by their IDs if you want more control.

    Key Features:

    • Handles pagination automatically to process all members regardless of list size
    • Filters for unverified members only (checks verifiedEmail field)
    • Updates members using the PATCH endpoint to set verifiedEmail: true
    • Returns detailed results showing which members succeeded and which failed
    • Includes error handling and reporting

    Setup Steps:

    1. Get your API key from Memberstack Dashboard → Dev Tools (use sk_sb_... for testing, sk_... for production)
    2. Store it as an environment variable: MEMBERSTACK_API_KEY
    3. Choose the implementation option that fits your stack
    4. Call the function when you want to verify all unverified members

    Important: Keep your API key secure and only use it server-side. Never expose it in client-side code or public repositories.

    // ============================================
    // MEMBERSTACK 2.0 BULK EMAIL VERIFICATION
    // ============================================
    // OPTION 1: Node.js + Express Backend
    // ============================================

    const express = require('express');
    const memberstackAdmin = require('@memberstack/admin');

    const app = express();
    app.use(express.json());

    const memberstack = memberstackAdmin.init(process.env.MEMBERSTACK_API_KEY);

    // Endpoint to bulk verify all unverified members
    app.post('/api/bulk-verify-emails', async (req, res) => {
     try {
      const verified = [];
      const failed = [];
      let nextCursor = null;
      let hasMore = true;

      // Paginate through all members
      while (hasMore) {
       const response = await memberstack.members.list({
        limit: 50,
        after: nextCursor
       });

       const members = response.data || [];

       // Process each member
       for (const member of members) {
        try {
         // Check if member is not verified
         if (member.auth?.verifiedEmail === false) {
          // Update member to mark as verified
          await memberstack.members.update(member.id, {
           auth: {
            verifiedEmail: true
           }
          });

          verified.push({
           id: member.id,
           email: member.auth?.email
          });
         }
        } catch (error) {
         failed.push({
          id: member.id,
          email: member.auth?.email,
          error: error.message
         });
        }
       }

       // Check for pagination
       hasMore = response.hasMore || false;
       nextCursor = response.endCursor || null;
      }

      res.json({
       success: true,
       summary: {
        verified: verified.length,
        failed: failed.length,
        totalProcessed: verified.length + failed.length
       },
       verified,
       failed
      });
     } catch (error) {
      res.status(500).json({
       success: false,
       error: error.message
      });
     }
    });

    // ============================================
    // OPTION 2: REST API (JavaScript/Frontend)
    // ============================================

    async function bulkVerifyMembersREST() {
     const API_KEY = process.env.MEMBERSTACK_SECRET_KEY;
     const BASE_URL = 'https://admin.memberstack.com/members';
      
     const headers = {
      'X-API-KEY': API_KEY,
      'Content-Type': 'application/json'
     };

     try {
      let allMembers = [];
      let nextCursor = null;
      let hasMore = true;

      // Fetch all members with pagination
      while (hasMore) {
       const url = nextCursor 
        ? `${BASE_URL}?limit=50&after=${nextCursor}`
        : `${BASE_URL}?limit=50`;

       const response = await fetch(url, {
        method: 'GET',
        headers
       });

       const data = await response.json();
       allMembers = allMembers.concat(data.data || []);

       hasMore = data.hasMore || false;
       nextCursor = data.endCursor || null;
      }

      // Filter unverified members
      const unverifiedMembers = allMembers.filter(
       m => m.auth?.verifiedEmail === false
      );

      const results = {
       verified: [],
       failed: [],
       skipped: allMembers.length - unverifiedMembers.length
      };

      // Update each unverified member
      for (const member of unverifiedMembers) {
       try {
        const response = await fetch(
         `${BASE_URL}/${member.id}`,
         {
          method: 'PATCH',
          headers,
          body: JSON.stringify({
           auth: {
            verifiedEmail: true
           }
          })
         }
        );

        if (response.ok) {
         results.verified.push({
          id: member.id,
          email: member.auth?.email
         });
        } else {
         results.failed.push({
          id: member.id,
          email: member.auth?.email,
          error: `HTTP ${response.status}`
         });
        }
       } catch (error) {
        results.failed.push({
         id: member.id,
         email: member.auth?.email,
         error: error.message
        });
       }
      }

      return {
       success: true,
       summary: {
        total: allMembers.length,
        verified: results.verified.length,
        failed: results.failed.length,
        skipped: results.skipped
       },
       ...results
      };
     } catch (error) {
      console.error('Bulk verification error:', error);
      throw error;
     }
    }

    // ============================================
    // OPTION 3: Verify Specific Members by ID
    // ============================================

    async function verifySpecificMembersREST(memberIds) {
     const API_KEY = process.env.MEMBERSTACK_SECRET_KEY;
     const BASE_URL = 'https://admin.memberstack.com/members';
      
     const headers = {
      'X-API-KEY': API_KEY,
      'Content-Type': 'application/json'
     };

     const results = { verified: [], failed: [] };

     for (const memberId of memberIds) {
      try {
       const response = await fetch(
        `${BASE_URL}/${memberId}`,
        {
         method: 'PATCH',
         headers,
         body: JSON.stringify({
          auth: {
           verifiedEmail: true
          }
         })
        }
       );

       if (response.ok) {
        const member = await response.json();
        results.verified.push({
         id: memberId,
         email: member.data?.auth?.email
        });
       } else {
        results.failed.push({
         id: memberId,
         error: `HTTP ${response.status}`
        });
       }
      } catch (error) {
       results.failed.push({
        id: memberId,
        error: error.message
       });
      }
     }

     return {
      success: results.failed.length === 0,
      verified: results.verified.length,
      failed: results.failed.length,
      details: results
     };
    }

    // ============================================
    // USAGE EXAMPLES
    // ============================================

    // Example 1: Start bulk verification via REST API
    // GET /api/bulk-verify-emails
    // Response: { success: true, summary: {...}, verified: [...], failed: [...] }

    // Example 2: Verify specific members
    // const memberIds = ['mem_abc123', 'mem_def456'];
    // await verifySpecificMembersREST(memberIds);

    // Example 3: Call from frontend button click
    // document.getElementById('bulkVerifyBtn').addEventListener('click', async () => {
    //  const result = await bulkVerifyMembersREST();
    //  console.log(`Verified: ${result.summary.verified}, Failed: ${result.summary.failed}`);
    // });
    0

Please sign in to leave a comment.