Bulk Email Finder enables you to discover email addresses by combining names with company domains. Upload a CSV file containing first names, last names, and company domains to generate accurate email addresses for your prospects.
Key Features
Name-to-Email Matching: Convert names and domains into valid email addresses
CSV Upload Support: Process large lists via file upload
Pattern Recognition: Use advanced algorithms to determine email patterns
Flexible Input: Support for various name and domain combinations
High Accuracy: Leverage domain-specific email patterns for precision
Verification Options: Optional email verification for deliverability
How Email Finder Bulk Works
Prepare CSV File: Create a file with columns for first name, last name, and domain
Map Columns: Specify which columns contain the required data
Upload and Configure: Upload your file and set processing parameters
Process Emails: Launch the email finding algorithm
// Create finder bulk with CSV file containing names and domainsparams := &models.BulkFinderCreateParams{ BulkCreateParams: models.BulkCreateParams{ Name: "Lead Generation - Tech Companies Q1", Delimiter: ",", Verify: true, // Enable email verification }, BulkFinderParams: models.BulkFinderParams{ ColumnFirst: 1, // First name column (1-based) ColumnLast: 2, // Last name column ColumnDomain: 3, // Company domain column Skip: false, },}// Upload CSV and create bulk finder operationresponse, err := client.CreateFinderBulk(params, "/path/to/prospects.csv")if err != nil { log.Fatal("Failed to create finder bulk:", err)}bulkID := *response.Data.IDfmt.Printf("Created finder bulk with ID: %d\n", bulkID)
Alternative Column Mapping (Full Name + Domain)
Code
// When you have full name in single columnparams := &models.BulkFinderCreateParams{ BulkCreateParams: models.BulkCreateParams{ Name: "Sales Prospects - SaaS Companies", Delimiter: ",", Verify: true, }, BulkFinderParams: models.BulkFinderParams{ ColumnName: 1, // Full name column ColumnDomain: 2, // Domain column Skip: false, },}response, err := client.CreateFinderBulk(params, "prospects-with-fullnames.csv")if err != nil { log.Fatal("Failed to create finder bulk:", err)}
Launching and Monitoring Email Finding
Code
// Launch the email finding processlaunchResponse, err := client.LaunchBulk(models.BulkTypeFinder, bulkID)if err != nil { log.Fatal("Failed to launch finder bulk:", err)}fmt.Println("Email finding process started!")// Monitor progress with detailed statusfor { progress, err := client.GetBulkProgress(models.BulkTypeFinder, bulkID) if err != nil { log.Printf("Error checking progress: %v", err) time.Sleep(30 * time.Second) continue } fmt.Printf("Finding emails: %d%% complete (%d processed)\n", progress.Progress, progress.Processed, ) if progress.Status { fmt.Println("Email finding completed successfully!") break } // Check every 30 seconds time.Sleep(30 * time.Second)}
Retrieving Found Emails
Code
// Get detailed bulk informationbulk, err := client.GetBulk(models.BulkTypeFinder, bulkID)if err != nil { log.Fatal("Failed to get bulk details:", err)}bulkInfo := bulk.Data[0]fmt.Printf("Bulk: %s\n", bulkInfo.Name)fmt.Printf("Status: %v\n", bulkInfo.Status)fmt.Printf("Total Processed: %d\n", bulkInfo.Processed)fmt.Printf("Emails Found: %d\n", *bulkInfo.TotalEmails)// Download all found emailserr = client.SaveBulkResults( models.BulkTypeFinder, bulkID, "found-emails.csv", "full",)if err != nil { log.Fatal("Failed to download results:", err)}fmt.Println("Found emails saved to found-emails.csv")
Downloading Different Result Types
Code
// Download only valid emailserr = client.SaveBulkResults( models.BulkTypeFinder, bulkID, "valid-emails.csv", "valid",)if err != nil { log.Printf("Error downloading valid emails: %v", err)}// Download records where no emails were founderr = client.SaveBulkResults( models.BulkTypeFinder, bulkID, "not-found.csv", "not_found",)if err != nil { log.Printf("Error downloading not found records: %v", err)}fmt.Println("Results downloaded in separate files")
Managing Finder Bulk Operations
Code
// List all finder bulks with filteringparams := &models.BulkGetParams{ Page: 1, Limit: 10, Direction: "desc", Filter: "all", // or "archived"}bulks, err := client.GetAllFinderBulks(params)if err != nil { log.Fatal("Failed to get finder bulks:", err)}fmt.Printf("Found %d finder bulk operations:\n", len(bulks.Data))for _, bulk := range bulks.Data { fmt.Printf("- ID: %d, Name: %s, Progress: %d%%\n", bulk.BulkID, bulk.Name, bulk.Progress)}// Rename a bulk operationrenameParams := &models.BulkRenameParams{ Name: "Updated Lead Generation Campaign",}_, err = client.RenameBulk(models.BulkTypeFinder, bulkID, renameParams)if err != nil { log.Fatal("Failed to rename bulk:", err)}// Archive completed bulk_, err = client.ArchiveBulk(models.BulkTypeFinder, bulkID)if err != nil { log.Fatal("Failed to archive bulk:", err)}
Advanced Example: Complete Email Finding Workflow
Code
func findEmailsFromProspects(client *tomba.Tomba, csvPath string) error { // Step 1: Create finder bulk with verification params := &models.BulkFinderCreateParams{ BulkCreateParams: models.BulkCreateParams{ Name: fmt.Sprintf("Email Discovery - %s", time.Now().Format("2006-01-02")), Delimiter: ",", Verify: true, // Verify found emails }, BulkFinderParams: models.BulkFinderParams{ ColumnFirst: 1, // First name in column 1 ColumnLast: 2, // Last name in column 2 ColumnDomain: 3, // Domain in column 3 Skip: false, }, } response, err := client.CreateFinderBulk(params, csvPath) if err != nil { return fmt.Errorf("failed to create finder bulk: %w", err) } bulkID := *response.Data.ID log.Printf("Created finder bulk: %d", bulkID) // Step 2: Launch the finding process _, err = client.LaunchBulk(models.BulkTypeFinder, bulkID) if err != nil { return fmt.Errorf("failed to launch bulk: %w", err) } log.Println("Email finding started...") // Step 3: Monitor with progress reporting startTime := time.Now() timeout := time.After(45 * time.Minute) // Longer timeout for finding ticker := time.NewTicker(30 * time.Second) defer ticker.Stop() var lastProgress int for { select { case <-timeout: return fmt.Errorf("email finding timed out after 45 minutes") case <-ticker.C: progress, err := client.GetBulkProgress(models.BulkTypeFinder, bulkID) if err != nil { log.Printf("Error checking progress: %v", err) continue } // Only log if progress changed significantly if progress.Progress != lastProgress { elapsed := time.Since(startTime).Round(time.Second) log.Printf("Finding progress: %d%% (%d processed) - Elapsed: %v", progress.Progress, progress.Processed, elapsed) lastProgress = progress.Progress } if progress.Status { // Step 4: Get final results and download bulk, err := client.GetBulk(models.BulkTypeFinder, bulkID) if err != nil { return fmt.Errorf("failed to get final bulk details: %w", err) } info := bulk.Data[0] log.Printf("Email finding completed!") log.Printf("Total processed: %d", info.Processed) if info.TotalEmails != nil { log.Printf("Emails found: %d", *info.TotalEmails) } // Download results outputFile := fmt.Sprintf("found-emails-%d.csv", bulkID) err = client.SaveBulkResults(models.BulkTypeFinder, bulkID, outputFile, "valid") if err != nil { return fmt.Errorf("failed to save results: %w", err) } log.Printf("Valid emails saved to: %s", outputFile) return nil } } }}// Usage examplefunc main() { client := tomba.NewTomba("your-api-key", "your-secret-key") err := findEmailsFromProspects(client, "prospects.csv") if err != nil { log.Fatal("Email finding failed:", err) }}