Bulk Lead Import

Bulk Lead Import Endpoint Reference

For large amounts of lead records, leads can be imported asynchronously with the bulk API.  This allows you to import a list of records into Marketo using a flat file with the delimiters (comma, tab, or semi-colon).  The file can contain any number of records, so long as the file totals less than 10MB in size.  The record operation is “createOrUpdate” only.

Processing Limits

You are allowed to submit more than one bulk import request, with limitations.  Each request is added as a job to a FIFO queue to be processed.  A maximum of 2 jobs are processed at the same time.  A maximum of 10 jobs are allowed in the queue at any given time (including the 2 currently being processed).  If you exceed the 10 job maximum, then a “1016, Too many imports” error is returned.

Import File

The first row of the file must be a header which lists the corresponding REST API fields to map the values of each row into.  A typical file would follow this basic pattern:

The call itself is made using the multipart/form-data content-type.
This request type can be difficult to implement, so it is highly recommended that you use an existing library implementation.

Creating a Job

To make a bulk import request, you need to set your content-type header to “multipart/form-data” and include at least a file parameter with your file content, and a format parameter with the value “csv”, “tsv”, or “ssv” denoting your file format.

A simple way to do this with cURL from the command line looks like this:

curl -i -F format=csv -F file=@leaddata.csv -F access_token=<accesstoken> <REST API Endpoint Base URL>/bulk/v1/leads.json

You can also optionally include the lookupField, listId, and partitionName parameters in your request.  lookupField allows you to select a specific field to deduplicate on, just like Sync Leads, and defaults to email.  listId allows you to select a static list to import the list of leads to; this will cause the leads in the list to become members of this static list, in addition to any creations or updates caused by the import.  partitionName selects a specific partition to import to.  See the Workspaces and Partitions section for more information.

Notice in the response to our call, that there is not a listing of successes or failures like with Sync Leads, but a batchId and a status field for the record in the result array.  This is because this API is asynchronous, and can return a status of Queued, Importing, or Failed.  You will need to retain the batchId in order to get the status of the import job, and to retrieve failures and/or warnings upon completion.   The batchId remains valid for 7 days.

Polling Job Status

It is best practice to poll the job every 5-30 seconds, depending on required latency and API call limitations, in order to see the status of the import job.  You can do so with the Get Import Lead Status API.

This response shows a completed import, but the status can be one of:

  • Complete
  • Queued
  • Importing
  • Failed

If the job has completed, you’ll have a listing of the number of rows processed, failed, on ones with warnings.  The message parameter may also give the failure message if status is Failed.


To retrieve the records and causes of failed rows, you’ll need to retrieve the failure file:

The API will respond with a file indicating which rows failed, along with a message indicating why the record failed.


To get the warning file you can follow a similar pattern, and it will return a similar response indicating the warnings: