Comparing REST API vs Bulk API for large-scale marketing campaign imports

I’m evaluating our approach to importing large marketing campaign data sets into Salesforce. We typically process 10K-50K campaign member records daily from external marketing platforms, and I’m trying to decide between REST API and Bulk API.

Currently using REST API with batches of 200 records, but we’re hitting governor limits during peak import windows. Bulk API seems like the obvious choice for volume, but I’m concerned about error handling complexity and real-time feedback. Our imports need to complete within 2-hour windows and we need detailed error reporting for failed records.

What are others using for large-scale marketing campaign imports? Are there scenarios where REST API still makes sense even with higher volumes, or is Bulk API the clear winner once you cross a certain threshold? Particularly interested in experiences with error handling strategies for both approaches.

At 10K–50K records daily with 2-hour completion windows, you’re squarely in the territory where the choice materially affects reliability, not just performance. Here’s how the two approaches compare across your specific criteria:

Criteria REST API (Composite/Collections) Bulk API 2.0
Throughput ~200–2,000 records/call (Collections endpoint) Up to 100M records/job; async processing
Governor limit exposure High — counts against per-hour API call limits Low — separate async allocation
Latency / real-time feedback Synchronous; per-call response Asynchronous; poll for completion
Error granularity Per-record error in same response payload Results file after job completion; row-level error detail available
Error handling complexity Lower — inline, tight retry loops Higher — requires job state polling, result file parsing
2-hour window fit Risky at 50K; depends on concurrency Reliable at 50K; typical job completion well within window (verify in your version)
CampaignMember support Full object support Full object support

Key architectural considerations:

REST API with SObject Collections (not single-record calls) can handle up to 200 records per request and up to 25 requests per composite call — that’s meaningful throughput improvement over your current approach. If you’re still hitting EXCEEDED_MAX_SIZE_REQUEST or hourly API limits, the ceiling is real.

Bulk API 2.0 removes most of those ceilings. You upload a CSV, Salesforce processes it asynchronously, and you retrieve a results file. The tradeoff: you don’t get per-record feedback until the job completes. For error handling, poll /services/data/vXX.X/jobs/ingest/{jobId}/failedResults to retrieve a CSV of failed rows with error codes — this is actually quite structured once you build the parser. Retry logic means re-uploading a corrected subset CSV as a new job.

For your specific scenario, the Bulk API 2.0 path is lower-risk at peak volume, but your error reporting pipeline needs deliberate design:

  • Retrieve both successfulResults and failedResults endpoints post-completion
  • Parse sf__Error and sf__Id columns for reconciliation
  • Consider a dead-letter queue pattern for failed rows — requeue with corrected data rather than manual intervention

One nuance worth testing: CampaignMember upsert via Bulk API requires an external ID field on the object or matching on CampaignId + LeadId/ContactId composite key — confirm your matching strategy handles deduplication correctly (verify in your version for any object-specific restrictions).

REST API remains relevant when you need sub-second confirmation per record (e.g., triggering downstream logic immediately), or when volumes stay under ~5K records in a window with predictable API headroom.

Ultimately, the right choice depends on context / your requirements — specifically whether synchronous feedback or throughput ceiling is the harder constraint in your architecture.


This draft is based on general Salesforce knowledge. It has not been verified against your specific version and environment. Practitioners: verify the steps and share your experience below.

We switched from REST to Bulk API last year for similar volumes. The main advantage is Bulk API doesn’t count against your daily API limits the same way. With 50K records, you’d burn through REST API limits quickly. Bulk API processes asynchronously which takes getting used to, but for batch imports it’s definitely the way to go.

The decision really depends on your error handling requirements. REST API gives you immediate synchronous response for each batch - you know instantly which records failed and why. Bulk API requires polling the job status and downloading results files. If you need real-time validation feedback, REST API might still be worth it despite the governor limits. But for pure throughput on large datasets, Bulk API wins hands down.

One hybrid approach: use REST API for smaller daily updates (under 5K records) and Bulk API for weekly full syncs or historical data loads. This gives you the best of both worlds.

Bulk API batch processing is more efficient, but don’t underestimate the complexity of monitoring asynchronous jobs. You need robust polling logic, result file parsing, and retry mechanisms. We built a whole framework around Bulk API job management. If your team doesn’t have that infrastructure, REST API’s simplicity might be worth the governor limit trade-offs.

For marketing campaign imports specifically, consider the Campaign Member object’s unique constraints. Duplicate campaign members for the same contact/lead cause errors that need special handling. Bulk API’s all-or-nothing batch behavior can be problematic - one bad record fails the whole batch. REST API lets you handle duplicates more gracefully with upsert logic per record.

Also, if you’re importing campaign responses or engagement data that needs to trigger workflows immediately, REST API’s synchronous nature ensures those automations fire right away. Bulk API delays can cause timing issues with follow-up campaigns.

The duplicate handling point is important - we do see a lot of duplicate campaign member attempts. How do people typically handle error handling strategies with Bulk API when you need granular per-record error reporting?

Great discussion on REST API vs Bulk API trade-offs. Here’s my perspective after implementing both for multiple large-scale marketing operations:

Bulk API Batch Processing - When to Use:

Bulk API is optimal when:

  • Processing 10K+ records in a single operation
  • Import timing is flexible (can tolerate 5-30 minute processing windows)
  • Records are relatively clean with low error rates (under 5%)
  • You have infrastructure to poll job status and parse result files

For your 10K-50K daily campaign member imports, Bulk API is the right choice. Here’s why:

  1. Governor Limits: REST API has a 15K record per 24-hour limit for some operations. At 50K records, you’d exceed this immediately. Bulk API has much higher limits (10K batches, 100M records per 24 hours).

  2. Performance: Bulk API processes records in parallel batches of 10K. Your 50K records would split into 5 batches processed simultaneously. Total time: 10-20 minutes typically. REST API with 200-record batches would require 250 sequential API calls - much slower.

Error Handling Strategies for Bulk API:

The asynchronous nature doesn’t mean poor error handling. Here’s a robust approach:

  1. Job Monitoring: Poll the Bulk API job status every 5-10 seconds until complete
  2. Result Processing: Download the result CSV which maps each input record to success/failure
  3. Error Classification: Parse errors into categories (validation, duplicate, field-level, system)
  4. Retry Logic: Failed records go into a retry queue with exponential backoff
  5. Reporting: Generate detailed error reports showing exactly which campaign members failed and why

This gives you the same granular error visibility as REST API, just asynchronously.

REST API Governor Limits - When It Still Makes Sense:

REST API remains valuable for:

  • Real-time single record operations (under 200 records)
  • Operations requiring immediate workflow triggers
  • Complex upsert logic with external ID matching
  • Scenarios where you need synchronous confirmation before proceeding

For your marketing campaign imports, consider a hybrid:

  • Bulk API: Daily batch imports of 10K+ campaign members
  • REST API: Real-time campaign member additions from web forms or events (under 100 records)

Campaign Member-Specific Considerations:

For duplicate handling with Bulk API:


// Use External ID matching on composite key
CampaignId + ContactId as External_Campaign_Member_ID__c

This enables upsert behavior in Bulk API, preventing duplicate errors. Create a formula field or use before-insert triggers to populate this composite key.

Recommended Architecture:

  1. Stage records in a queue/database with metadata (source, timestamp, priority)
  2. Aggregate records every 15-30 minutes into Bulk API jobs
  3. Process high-priority/real-time records via REST API immediately
  4. Monitor both API limit consumption and adjust batch timing dynamically
  5. Implement circuit breaker pattern if error rates exceed 10%

With proper error handling infrastructure, Bulk API provides superior throughput for your volumes while maintaining the error visibility you need. The 2-hour processing window is more than sufficient for Bulk API to handle 50K records with full error reporting.