Kaizen #13 - Bulk Write API

Kaizen #13 - Bulk Write API

Hello everyone!

Welcome to yet another post in the Kaizen series.
This week, we are going to discuss the Bulk Write API.

What is the Bulk Write API?

The bulk write API allows you to insert, update, and upsert records in a module in Zoho CRM in bulk. The primary difference between the bulk write API, and the Insert, Update, Upsert records API, is the number of records that you can handle. 

While you can insert, update, and upsert, only 100 records via the Insert, Update, and Upsert Records API per call, you can handle 25000 records via a Bulk Write API call.

When you should use the Bulk Write API?
  1. When you want to insert, update, or upsert more than 100 records per API call. 
  2. When you want to perform background processes like migration and initial data sync between Zoho CRM and external services.
Below are the differences between Insert, Update, Upsert Records API and the Bulk Write API.

Insert, Update, Upsert Records
Bulk Write API
You can insert, update, or upsert only 100 records per API call.
You can insert, update, or upsert 25000 records per API call.
The response is available instantly.
The response is not available instantly; the bulk write job is scheduled, and the status is available after job completion in the callback URL.
You will receive a success response. 
A downloadable ZIP file containing a CSV file, is available with ID, status, and errors if any.

How does the Bulk Write API work?

To insert, update, or upsert records in bulk, follow the below steps:

  1. Prepare your CSV file
  2. Upload your file
  3. Create a bulk write job
  4. Check the job status
  5. Download the result
Now, let us see each step in detail.

1. Prepare your CSV file

The Bulk Write API only accepts a CSV file compressed into a ZIP file as input. The first row should contain the field API names. Refer to the field metadata API, to get the field API names. Each subsequent row contains the data to be written in Zoho CRM. You can insert, update, or upsert records only in a single module through one bulk write API call. Refer to attachments to get a sample ZIP file to bulk-insert contacts. 

Input format for each data type

Datatype
Description
Single Line
Accepts up to 255 characters.
Accepts alphanumeric and special characters.
Ex: Mike O'Leary
Multi-Line
Small - accepts up to 2000 characters.
Large - accepts up to 32000 characters.
Ex: This is a sample description.
Email
Accepts valid email IDs.
Phone
Accepts up to 30 characters. This limit may vary based on the value configured in 'Number of characters allowed' in the properties pop-up of the field, in UI.
Accepts only numeric characters and '+' (to add extensions). 
Ex: 9800000099
Picklist
You can pass an existing pick list value. If you give a new one, it is automatically added to the pick list set.
The pick list value accepts all alphanumeric and special characters.
Ex: auto mobile
Multiselect Picklist
You can either pass the existing pick list values or add a new one. The values are separated by semicolon(;).
The pick list value accepts all alphanumeric and special characters.
Ex: Analytics;Bigdata
Date
Accepts date in yyyy-MM-dd format.
Ex: 2019-08-28
Date/Time
Accepts date and time in yyyy-MM-ddTHH:mm:ss±HH:mm
ISO 8601 format.
Number
Accepts numbers up to 9 digits. This limit may vary based on the value configured in 'Maximum digits allowed' in the properties pop-up of the field, in UI.
Accepts only numeric values.
Ex: 350
Currency
Before the decimal point - accepts numbers up to 16 digits.  This limit may vary based on the value configured in 'Maximum digits allowed' in the properties pop-up of the field, in UI.
After the decimal point - accepts precision up to 9 digits. This limit may vary based on the value configured in 'Number of decimal paces' in the properties pop-up of the field, in UI.
Decimal
Before the decimal point - accepts numbers up to 16 digits. This limit may vary based on the value configured in 'Maximum digits allowed' in the properties pop-up of the field, in UI.
After the decimal point - accepts precision up to 9 digits. This limit may vary based on the value configured in 'Number of decimal places' in the properties pop-up of the field, in UI.
Accepts only numeric values.
Ex: 250000.50
Percent
Accepts numbers up to 5 digits.
Accepts only numeric values.
Ex: 25
Long Integer
Accepts numbers up to 18 digits. This limit may vary based on the value configured in 'Maximum digits allowed' in the properties pop-up of the field, in UI.
Accepts only numeric values.
Ex: 0012345600012
Checkbox
Accepts Boolean values (true,false).
Ex: true
URL
Accepts valid URLs.
Lookup
Accepts the unique ID of the record, which you can get through the get records API.
Use the dot(.) operator to link the record. For instance, if there is an account lookup in the Contacts module, you can give the column name as Account.id
Ex: Account.id : 4150868000001136302

Note:
Multiselect and User datatype fields are not supported in Bulk Write.

Here is a sample content for a CSV file with different field types.



Note:
  1. To give multiple values for a multi-select pick list field, enclose them in double quotes("") and separate each value with the semicolon(;).
  2. If your multi-line field has more than one line, input them directly by enclosing them in double quotes("").
2. Upload your CSV file

This involves making a POST API call, with the ZIP file containing the required data. The file is passed as form-data input, with key as file. When the call is successful, you will receive a file_id which you can further use to create a bulk write job.

Headers

Header Name
Description
feature
bulk-write
X-CRM-ORG
Your zgid which you get from the organization API.




3. Create a bulk write job

In this step, make a POST API call with the file_id obtained from the previous step, the callback URL, operation type (insert, update, upsert), module, and field API names. When the call is successful, you will receive a job ID in the response. You can use this ID in another request to poll for the status of the job.

Request URL

{{api-domain}}/crm/bulk/v2/write

Sample Input for bulk insert

{
    "operation": "insert",
    "callback": {
        "method": "post"
    },
    "resource": [
        {
            "type": "data",
            "module": "Contacts",
            "file_id": "4150868000001038001",
            "field_mappings": [
                {
                    "api_name": "Last_Name",
                    "index": 0,
                    "default_value": {
                        "value": "DefaultValue"
                    }
                },
                {
                    "api_name": "Email",
                    "index": 1
                },
                {
                    "api_name": "Phone",
                    "index": 2
                }
            ]
        }
    ]
}

Sample Input for Bulk Update

{
  "operation": "update",
  "callBack": {
    "method": "post"
  },
  "resource": [
    {
      "type": "data",
      "module": "Contacts",
      "file_id": "4150868000001123001",
      "field_mappings": [
        {
          "api_name": "Last_Name",
          "index": 0
        },
        {
          "api_name": "Email",
          "index": 1
        },
        {
          "api_name": "Phone",
          "index": 2,
          "ignore_empty": true
        }
      ],
      "find_by": "Email"
    }
  ]
}

Input Keys

Key
Description
operation
string, mandatory
The operation to be done. The possible values are—insert, update, upsert.
insert - To insert records in bulk.
update - To update existing records in bulk.
upsert - To update if the record exists or insert the record.
callback
JSON object, mandatory
The callback details. Contains callback URL in the "callback" key and the "method" as post. 
resource
JSON array, mandatory
The details of the data in the ZIP file that is uploaded. 
  • "type" with value "data "
  • "module"- It is the module (API name) you want to write the data in, from the uploaded CSV file.  Refer to the module metadata for more details.
  • "file_id" - It is the file ID obtained in the previous step.
field_mappings
JSON array, mandatory
The details about the fields given in the CSV file. Each object corresponds to each field in the CSV file. Mention the position of the fields in the CSV file in the "index" key, that must start from 0. 
"default_value" key can be used when a few fields are left blank, and you want the system to fill the default details.
ignore_empty
boolean, optional
If you have a few empty fields while updating the record and you want the system to ignore it, input the value as true.
find_by
string, mandatory (for Update and Upsert)
The system finds the record to be updated by the "find_by" field. It must be a unique field configured in Zoho CRM. 

To check the same, go to Setup > Modules and Fields > Choose Module > Choose Layout > Choose the field > Click on more options > Check if Do not allow duplicate values is enabled. 
Using field metadata API, you can get which fields can be set as unique fields in the CRM.



4. Check job status

The Bulk Write API supports polling and callback. 

Polling
You can poll to check the status of the scheduled bulk write job with the job ID you received in the previous step.

Request URL: {{api-domain}}/crm/bulk/v2/write/{job_id}
Request Method: GET



Sample Response

  1. The status can be either ADDED, INPROGRESS, or COMPLETED. Only the COMPLETED jobs will have the "download-URL" key in the response. 
  2. The "file" JSON object in the response represents the total count of records (added, skipped, updated). If the status is mentioned as "skipped" for any record, the reason will be displayed under the ERRORS column, in the downloaded ZIP file. 
{
  "status": "COMPLETED",
  "character_encoding": "UTF-8",
  "resource": [
    {
      "status": "COMPLETED",
      "type": "data",
      "module": "Contacts",
      "field_mappings": [
        {
          "api_name": "Email",
          "index": 1,
          "format": null,
          "find_by": null,
          "module": null,
          "default_value": null
        },
        {
          "api_name": "Last_Name",
          "index": 0,
          "format": null,
          "find_by": null,
          "module": null,
          "default_value": {
            "name": null,
            "module": null,
            "value": "DefaultValue"
          }
        },
        {
          "api_name": "Phone",
          "index": 2,
          "format": null,
          "find_by": null,
          "module": null,
          "default_value": null
        }
      ],
      "file": {
        "status": "COMPLETED",
        "name": "Contacts.csv",
        "added_count": 7,
        "skipped_count": 0,
        "updated_count": 0,
        "total_count": 7
      }
    }
  ],
  "id": "4150868000001060014",
  "callback": {
    "method": "post"
  },
  "result": {
  },
  "created_by": {
    "id": "4150868000000225013",
    "name": "Patricia Boyle"
  },
  "operation": "insert",
  "created_time": "2020-01-03T15:19:52+05:30"
}

Callback
If you do not want to poll for the status of the job, you can wait for the system to notify you of job completion on the callback URL provided in the POST request.

  • The state indicates the successful completion ("state":"COMPLETED") or failure ("state":"FAILED") of the job.
  • The callback response will also contain the download URL if the job was completed successfully.

5. Download the result

In this step you can get the result of the bulk write job in a ZIP containing the CSV file. Call the 'download_url' to download the result. The CSV file will contain the first three mapped columns from the uploaded file, and three more columns—STATUS, RECORD_ID, and ERRORS.

Request URL: {{api-domain}}/crm/bulk/v2/write/{job_id}/result

Sample Response



You can see that out of four records, one was skipped because the unique field had a duplicate value.

Limitations
  • You can upload only one ZIP file per bulk write API call.
  • You can bulk write to only one module per API call.
  • The size of the ZIP file being uploaded must not exceed 25 MB. If the file size exceeds the size limit, you must split the file and schedule it as multiple bulk write jobs. Also, you can bulk write only up to 25000 records with 200 column headers per bulk write API call.
  • Every successfully scheduled bulk write job reduces 500 credits from your daily credit limit. 
  • All the mandatory fields must be given in the CSV file if you are trying to insert records. Similarly, ID is mandatory when you are trying to update records.
  • Subforms are not supported in Bulk Write.
  • Consider that you have a lookup field in the Leads module, that looks up to other leads. You cannot have the value of this field as another Lead that is being written in this bulk write job. In other words, you can only lookup to an existing lead.
    For limitations, refer to limitations in our API guide.
    We hope you found this post useful. If you have any further queries, reach out to us at support@zohocrm.com or let us know in the comments section.

    Cheers!
        Previous 'Kaizen' - Bulk Read API
        Next 'Kaizen' - Notification API



    • Sticky Posts

    • Kaizen #197: Frequently Asked Questions on GraphQL APIs

      🎊 Nearing 200th Kaizen Post – We want to hear from you! Do you have any questions, suggestions, or topics you would like us to cover in future posts? Your insights and suggestions help us shape future content and make this series better for everyone.
    • Kaizen #198: Using Client Script for Custom Validation in Blueprint

      Nearing 200th Kaizen Post – 1 More to the Big Two-Oh-Oh! Do you have any questions, suggestions, or topics you would like us to cover in future posts? Your insights and suggestions help us shape future content and make this series better for everyone.
    • Celebrating 200 posts of Kaizen! Share your ideas for the milestone post

      Hello Developers, We launched the Kaizen series in 2019 to share helpful content to support your Zoho CRM development journey. Staying true to its spirit—Kaizen Series: Continuous Improvement for Developer Experience—we've shared everything from FAQs
    • Kaizen #193: Creating different fields in Zoho CRM through API

      🎊 Nearing 200th Kaizen Post – We want to hear from you! Do you have any questions, suggestions, or topics you would like us to cover in future posts? Your insights and suggestions help us shape future content and make this series better for everyone.
    • Client Script | Update - Introducing Commands in Client Script!

      Have you ever wished you could trigger Client Script from contexts other than just the supported pages and events? Have you ever wanted to leverage the advantage of Client Script at your finger tip? Discover the power of Client Script - Commands! Commands
    • Recent Topics

    • BUTTONS SHOWN AS AN ICON ON A REPORT

      Hi Is there any way to create an action button but show it as an icon on a report please? As per the attached example? So if the user clicks the icon, it triggers an action?
    • Dropshipping Address - Does Not Show on Invoice Correctly

      When a dropshipping address is used for a customer, the correct ship-to address does not seem to show on the Invoice. It shows correctly on the Sales Order, Shipment Order, and Package, just not the Invoice. This is a problem, because the company being
    • RFQ MODEL

      A Request for quotation model is used for Purchase Inquiries to multiple vendors. The Item is Created and then selected to send it to various vendors , once the Prices are received , a comparative chart is made for the user. this will help Zoho books
    • Will zoho thrive be integrated with Zoho Books?

      title
    • Product Updates in Zoho Workplace applications | August 2025

      Hello Workplace Community, Let’s take a look at the new features and enhancements that went live across all Workplace applications this August. Zoho Mail Delegate Email Alias Now you can let other users send emails on your behalf—not just from your primary
    • Notebook audio recordings disappearing

      I have recently been experiencing issues where some of my attached audio recordings are disappearing. I am referring specifically to ones made within a Note card in Notebook on mobile, made by pressing the "+" button and choosing "Record audio" (or similar),
    • Unable to send message; Reason:554 5.1.8 Email Outgoing Blocked

      Hi, I sent few emails and got this: Unable to send message; Reason:554 5.1.8 Email Outgoing Blocked And now I have few days since I cant send any email. Is there something wrong I did? Also can someone fix this please
    • Want to use Zoho Books in Switzerland. CHF support planned?

      Hi, We're a Swiss company using other Zoho suite software and I discovered Zoho Books and other accounting SaaS when looking for an accounting tool. Do you intend to cover Switzerland and CHF based accounting anytime soon? Roy
    • Zoho sheet desktop version

      Hi Zoho team Where can I access desktop version of zoho sheets? It is important as web version is slow and requires one to be online all the time to do even basic work. If it is available, please guide me to the same.
    • Weekly Tips : Teamwork made easy with Multiple Assignees

      Let's say you are working on a big project where different parts of a single task need attention from several people at the same time—like reviewing a proposal that requires input from sales, legal, and finance teams. Instead of sending separate reminders
    • Best way to share/download presentation files in Zoho without losing formatting?

      Hello Zoho Community, I often work with PPT/PDF files in Zoho Docs and share them with colleagues. While PDFs usually give a direct download option, I’ve noticed that PPT/PPTX files sometimes only open in the viewer without a clear download link. Is there
    • Celebrating Connections with Zoho Desk

      September 27 is a special day marking two great occasions: World Tourism Day and Google’s birthday. What do these two events have in common (besides the date)? It's something that Zoho Desk celebrates, too: making connections. The connect through tourism
    • What is Resolution Time in Business Hours

      HI, What is the formula used to find the total time spent by an agent on a particular ticket? How is Resolution Time in Business Hours calculated in Zohodesk? As we need to find out the time spent on the ticket's solution by an agent we seek your assistance
    • How use

      Good morning sir I tried Zoho Mail
    • Adding Overlays to Live Stream

      Hello folks, The company I work for will host an online event through Zoho Webinar. I want to add an overlay (an image) at the bottom of the screen with all the sponsors' logos. Is it possible to add an image as an overlay during the live stream? If so,
    • Email Sending Failed - SMTP Error: data not accepted. - WHMCS Not sending emails due to this error

      I have been trying to figure out a fix for about a week now and I haven't found one on my own so I am going to ask for help on here.  After checking all the settings and even resetting my password for the email used for WHMCS it still says: Email Sending Failed - SMTP Error: data not accepted.  I have no clue how to fix it at this point. Any insight would be lovely. 
    • Does Zoho Learn integrate with Zoho Connect,People,Workdrive,Project,Desk?

      Can we propose Zoho LEarn as a centralised Knowledge Portal tool that can get synched with the other Zoho products and serve as a central Knowledge repository?
    • Zoho Flow - Update record in Trackvia

      Hello, I have a Flow that executes correctly but I only want it to execute once when a particular field on a record is updated in TrackVia. I have the trigger filters setup correctly and I want to add an "update record" action at the end of the flow to
    • Add Comprehensive Accessibility Features to Zoho Desk Help Center for End Users

      Hello Zoho Desk Team, We hope you're doing well. We’d like to submit a feature request to enhance the client-facing Help Center in Zoho Desk with comprehensive accessibility features, similar to those already available on the agent interface. 🎯 Current
    • Rename Record Summary PDF in SendMail task

      So I've been tasked with renaming a record summary PDF to be sent as part of a sendmail task. Normally I would offer the manual solution, a user exports the PDF and uploads it to a file upload field, however this is not acceptable to the client in this
    • in zoho creator Sales Returns form has sub form Line Items return quantity when i upate the or enter any values in the sub form that want to reflect in the Sales Order form item deail sub form field Q

      in zoho creator Sales Returns form has sub form Line Items return quantity when i upate the or enter any values in the sub form that want to reflect in the Sales Order form item deail sub form field Quantity Returned\ pls check the recording fetch_salesorder
    • Estimates with options and sub-totals

      Hi It seems it would be great to be able to show multiple options in an estimate. For instance I have a core product to which I can add options, and maybe sub-options... It would be great to have subtotals and isolate the core from the not compulsory items. Thanks
    • Optional Items Estimate

      How do you handle optional items within an estimate? In our case we have only options to choose with. (Like your software pricing, ...standard, professional, enterprise) How can we disable the total price? Working with Qty = 0 is unprofessional....
    • Important Update : Zendesk Sell announced End of Life

      Hello Zendesk users, Zendesk has officially announced that Zendesk Sell will reach its End of Life (EOL) on August 31, 2027 (Learn more). In line with this deprecation, Zoho Analytics will retire its native Zendesk Sell connector effective October 1,
    • Zoho Sheets

      Hi, I am trying to transition into Zoho sheets, I have attached the issues encountered. Server issues, file trying to upload for more than 30 mins, even once uploaded my data aren't loaded. Simple calculations are not working I have attached the sample.
    • Zoho CRM + Zoho FSM : alignez vos équipes commerciales et techniques

      La vente est finalisée, mais le parcours client ne fait que commencer ! Dans les entreprises orientées service, conclure une vente représente seulement la première étape. Ce qui suit — installation, réparation ou maintenance régulière — influence grandement
    • Top Bar Shifting issue still not fixed yet

      I mentioned in a previous ticket that on Android, the top bar shifts up when you view collections or when you're in the settings. That issue still hasn't been fixed yet. I don't wanna have to reinstall the app as I've noticed for some reason, reinstalling
    • Power of Automation:: Automate the process of updating project status based on a specific task status.

      Hello Everyone, Today, I am pleased to showcase the capabilities of a custom function that is available in our Gallery. To explore the custom functions within the Gallery, please follow the steps below. Click Setup in the top right corner > Developer
    • ZOHO SHEETS

      Where can I access desktop version of zoho sheets? It is important to do basic work If it is available, please guide me to the same
    • Attention API Users: Upcoming Support for Renaming System Fields

      Hello all! We are excited to announce an upcoming enhancement in Zoho CRM: support for renaming system-defined fields! Current Behavior Currently, system-defined fields returned by the GET - Fields Metadata API have display_label and field_label properties
    • Billing Management: #3 Billing Unbilled Charges Periodically

      We had a smooth sail into Prorated Billing, a practice that ensures fairness when customers join, upgrade, or downgrade a service at any point during the billing cycle. But what happens when a customer requests additional limits or features during the
    • No bank feeds from First National Bank South Africa since 12 September

      I do not know how Zoho Books expects its customers to run a business like this. I have contacted Zoho books numerous times about this and the say it is solved - on email NO ONE ANSWERS THE SOUTH AFRICAN HELP LINE Come on Zoho Books, you cannot expect
    • Citation Problem

      I had an previous ticket (#116148702) on this subject. The basic problem is this; the "Fetch Details" feature works fine on the first attempt but fails on every subsequent attempt, Back in July after having submitted information electronically and was
    • Open Sans Font in Zoho Books is not Open Sans.

      Font choice in customising PDF Templates is very limited, we cannot upload custom fonts, and to make things worse, the font names are not accurate. I selected Open Sans, and thought the system was bugging, but no, Open Sans is not Open Sans. The real
    • Failing to generate Access and Refresh Token

      Hello.  I have two problems: First one when generating Access and Refresh Token I get this response:  As per the guide here : https://www.zoho.com/books/api/v3/#oauth (using server based application) I'm following all the steps. I have managed to get
    • Zeptomail 136.143.188.150 blocked by SpamCop

      Hi - it looks like this IP is being blocked, resulting in hard bounces unfortunately :( "Reason: uncategorized-bounceMessage: 5.7.1 Service unavailable; Client host [136.143.188.150] blocked using bl.spamcop.net; Blocked - see https://www.spamcop.net/bl.shtml?136.143.188.150
    • Apply transaction rules to multiple banks

      Is there any way to make transaction rules for one bank apply to other banks? It seems cumbersome to have to re-enter the same date for every account.
    • How to bulk update records with Data Enrichment by Zia

      Hi, I want to bulk update my records with Data Enrichment by Zia. How can I do this?
    • Need Guidance on SPF Flattening for Zoho Mail Configuration

      Hi everyone, I'm hoping to get some advice on optimizing my SPF record for a Zoho Mail setup. I use Zoho Mail along with several other Zoho services, and as a result, my current SPF record has grown to include multiple include mechanisms. My Cloudflare
    • How do I split a large CSV file into smaller parts for import into Zoho?

      Hi everyone, I’m trying to upload a CSV file into Zoho, but the file is very large (millions of rows), and Zoho keeps giving me errors or takes forever to process. I think the file size is too big for a single import. Manually breaking the CSV into smaller
    • Next Page