Salesforce Bulk API 2.0 limits
Bulk API 2.0 removed manual batching but added its own limits and job-lifecycle rules. The route records below document ingest and query jobs as working integrations run them.
Sourced from 4 live route records · regenerated 2026-07-08
Documented failure modes
developer.salesforce.comsampled
- CSV files must use UTF-8 encoding and include a header row matching Salesforce API field names exactly
- A single bulk job has a record-count limit and a file-size limit — consult current Salesforce documentation for exact thresholds as they vary by edition
- Bulk API 2.0 jobs are asynchronous; polling too aggressively can hit API usage limits — use exponential backoff
salesforce.comsampled
- Bulk API 2.0 jobs are asynchronous — do not assume completion after the UploadComplete PATCH; always poll state before acting on results.
- CSV must use UTF-8 encoding and include a header row matching Salesforce field API names exactly; mismatched headers cause silent row-level failures visible only in failedResults.
- Bulk API 2.0 does not support all objects (e.g., ContentNote) and does not support relationship fields in header notation (Account.ExternalId__c) — use the externalIdFieldName parameter for upsert instead.
developer.salesforce.comsampled
- Result locators expire after a short window; download all batches promptly after job completion or the locator chain is lost
- Relationship fields in SOQL (e.g., Account.Name) are flattened with dot notation in the CSV headers, which can confuse naive CSV parsers
- The Bulk API 2.0 query endpoint is separate from the ingest endpoint; mixing up job type parameters silently creates the wrong job type
developer.salesforce.comsampled
- Bulk API 2.0 query uses a locator-based pagination scheme that differs from Bulk API 1.0's result batches; the two APIs are not interchangeable
- Including too many relationship traversal fields in the SOQL can cause the job to fail; simplify the query and join data post-download if needed
- The CSV header row is only included in the first chunk; subsequent locator-fetched chunks contain data rows only
The working procedure
- POST to /services/data/vXX.0/jobs/ingest with a JSON body specifying object, operation (insert/update/upsert/delete), and contentType (CSV)
- Upload a CSV payload via PUT to the uploadedFiles endpoint returned in the job creation response, with Content-Type text/csv
- Close the upload by sending a PATCH to the job URL with state UploadComplete
- Poll the job URL with GET until state reaches JobComplete or Failed
- Retrieve success and failure result files via the GET successfulResults and failedResults URLs on the job
Source: Ingest records using the Salesforce Bulk API 2.0 — a live route record (status: sampled). Route content is community/operator contributed and re-checked over time; read the live record for the current version.
How agents avoid this automatically
Agents wired to Waymark's MCP server pull this route (and its gotchas) at plan time instead of rediscovering the failure modes in production. Reads are free and keyless.
# Any MCP client — one call, no key:
waymark_query({ "task": "salesforce bulk api 2.0 ingest job limits" })
# Or plain HTTP:
curl -s "https://mcp.waymark.network/search?q=salesforce%20bulk%20api%202.0%20ingest%20job%20limits"