Hello everyone,
During Zoho Books implementations, one common challenge is updating a large number of existing records. The current options are usually:
- Update records manually from the UI using Mass Update (with limited batch size).
- Update records one by one through code using the API.
For large data corrections, migrations, or post-implementation changes, manually updating records is not practical, so I created a Node.js utility that safely performs bulk custom-field updates through the Zoho Books API.
The workflow
- Create a custom view containing the records that need to be updated.
- Export the records and extract their IDs into a text file (one ID per line).
- Point the script at the IDs file.
- Define the custom fields and new values in
.env. - Run the migration in three stages:
probe → dry-run → run.
Alternatively, instead of exporting IDs manually, you can write a small search function that retrieves the records you need and generates the IDs file automatically.
What the script supports
- Multiple custom-field updates in the same request.
- Any Books module (recurring invoices, invoices, contacts, bills, ...) via configuration — no code changes.
- Zero-ceremony OAuth: you provide only the Self Client grant code — the script exchanges it for a refresh token on first run, persists it locally, and mints access tokens automatically from then on. No manual token calls, no hardcoded tokens.
- Automatic re-refresh if Zoho invalidates the access token mid-run (401 handling).
- Request timeouts, retry with backoff for HTTP 429 and 5xx (honours
Retry-After). - Canary update: one record is updated and verified with a follow-up GET before the batch starts — a typo in a dropdown value aborts after one record, not after thousands.
- Progress milestones roughly every 10% of the batch, with a live ETA (the initial estimate is measured from the canary request's actual round-trip, not guessed).
- Resume capability: every outcome is appended to
results.jsonl; re-running skips records already updated successfully. A token problem or a network drop mid-run costs nothing. - Failed-ID export (
failed_ids.txt) for targeted retry.
Configuration
Everything lives in .env. You need exactly: data center, org ID, client ID/secret, a Self Client grant code, the module, the IDs file, and the fields to set — nothing else:
ZB_DC=eu
ZB_ORG_ID=123456789
ZB_CLIENT_ID=1000.xxxxx
ZB_CLIENT_SECRET=xxxxx
ZB_AUTH_CODE=1000.xxxxx
ZB_MODULE=recurringinvoices
ZB_IDS_FILE=invoice_ids.txt
ZB_THROTTLE_MS=700
ZB_FIELDS=[{"api_name":"cf_status","value":"Approved"},{"api_name":"cf_sync_date","value":"2026-07-16"}]
ZB_AUTH_CODE is the grant code from the API console (Self Client → Generate Code, with the scopes below). It is single-use and expires within 3–10 minutes, so run the script right after generating it — the first run exchanges it for a permanent refresh token and saves it to .zb_token_store.json. Add both .env and .zb_token_store.json to .gitignore, and revoke the client when the migration is done.
Gotchas worth knowing:
ZB_FIELDS must stay on a single line — dotenv does not parse unquoted multi-line values.ZB_DC must match the data center the client was created on. A client from api-console.zoho.eu will not authenticate against accounts.zoho.com.- If the exchange fails with
invalid_code, the grant code expired or was already consumed — generate a fresh one and re-run immediately.
ZB_MODULE is the URL path segment (recurringinvoices, invoices, contacts, ...). Note that Books responses wrap the record in a singular root key (invoice, recurring_invoice, ...) that doesn't match the URL segment — the script auto-detects it from the first GET, so you don't have to know this.
Usage
Probe the configuration and field mapping (read-only — this also performs the one-time grant-code exchange on first run):
bash
node zoho-books-bulk-cf-update.mjs probe
Update and verify one record, then stop:
bash
node zoho-books-bulk-cf-update.mjs dry-run
Execute the complete migration:
bash
node zoho-books-bulk-cf-update.mjs run
Sample run output:
48 IDs total · 0 already ok · 48 pending
auto-detected response entity key: "invoice"
Probe 639896000003678005: custom_fields present: cf_status, cf_sync_date, ...
cf_status → customfield_id 639896000000729241 (current: "Draft")
Canary update on 639896000003678005 ...
Canary verified.
Small batch (47 records) — throttle lowered to 300 ms.
1/48 · ETA 1.1 min
5/48 · ETA 1.0 min
10/48 · ETA 0.9 min
...
48/48 Done · ok=48 fail=0
Implementation details
The update process intentionally runs sequentially instead of firing parallel requests, to respect the per-minute API limit (100 requests/min per organization), avoid failures caused by throttling, and keep the migration predictable. The default 700 ms delay keeps the rate at roughly 85 requests/min. Batches of 90 records or fewer physically cannot breach the per-minute cap, so the script speeds those up automatically.
One detail that matters across orgs: custom fields in the update payload are addressed by customfield_id where possible. The script GETs one record first, resolves each api_name to its customfield_id, and only falls back to api_name addressing if the field is not present on the sample record.
Required scopes:
ZohoBooks.invoices.READ
ZohoBooks.invoices.UPDATE
(or the equivalent scopes for the module you are updating — always least-privilege rather than ZohoBooks.fullaccess.all)
Production considerations
- Mind the daily API cap as well as the per-minute one — it varies by Books plan. A 10,000-record migration may need to be split across days on lower plans.
- Dropdown custom fields must receive a value that matches an option exactly (spacing, hyphens, casing — especially with non-Latin characters). The canary catches this before the batch runs.
- An in-memory ID list is fine into the tens of thousands; the point of
results.jsonl is durability — progress survives crashes, token expiry, and Ctrl+C. - For extremely large or recurring migrations, the same logic can move into a queue-based Node.js worker where you control execution time, retry strategy, parallelism, and monitoring.
Where this is useful
- Updating custom fields after migrations.
- Fixing incorrectly imported data.
- Updating integration-generated records.
- Applying bulk corrections after changing business logic.
- Cleaning up data after implementation projects.
Sharing this pattern because bulk updates are a common challenge when working with the Zoho Books API. Script and example .env attached.
Recent Topics
Zoho Forms integration Google Sheets
Hi, quick one. I wonder if you can help. I have a Zoho Form integrated to a Google Sheet. The fields are showing across the top, but no records are there. I have checked in Zoho Forms to see if there have been any failed integrations, but there are none.
What's New in Zoho POS - August 2026
Hello everyone, Welcome to Zoho POS’s monthly update, where we share our latest feature updates, enhancements, events, and more. Let’s take a look at how August went. Boost your customer loyalty with loyalty points In a retail business, keeping a customer
Zoho ERP | Product updates | June 2026
Hello users, We launched Zoho ERP on January 23, and since then, our goal has been to help businesses streamline and manage their operations with greater efficiency, flexibility, and control. Since the launch, we've continued to enhance the platform every
3 numbers after comma in discount field
Hi, i need to make discount like: ex. 34,345% it's possible? Thank you.
ZOHO Campaigns in ZOHO Analytics - Campaigns vs Contacts Table
There seems to be information in the Zoho Campaigns table such as Unique Opens and Unique Clicks that can't be found in the Campaigns vs Contacts table where only Opens and Clicks are shown on a per contact level. Is there a way to bring Unique Opens
Canva Integration
Hello! As many marketing departments are streamlining their teams, many have begun utilizing Canva for all design mockups and approvals prior to its integration into Marketing automation software. While Zoho Social has this integration already accomplished,
Time Zone is incorrect
Time zone is not working properly...I've checked it twice. I'm eastern U.S. time it's currently 12:22 pm EST. CRM shows 3:22 pm EST.
Default Country list suggestions on CRM is different then on Book; how do/did others address this?
So I already have a support ticket in for this and waiting for a response but figured I'd ask the community also to see if others experienced the same problems and/or how they went about addressing it because sometimes I feel like I'm going crazy with
Zoho CRM Layout Rules: Nine New Actions, Profile-Based Execution, and Interactive Preview
Hello everyone, Availability: This feature is now available for all users. We’re excited to announce powerful new enhancements to Layout Rules in Zoho CRM - a feature built to guide our teams through form-filling by showing the right information to the
Vehicle Tracking
we have GPS devices that installed on our vehicles, and we would like to know if it's possible to get vehicle live location data from the GPS device To Zoho Creator App. Thank You
Check out the new Checkbox in Zoho Sheet
Checkbox, the simple GUI widget that lets you choose between two mutually exclusive options i.e Yes or No, is now in Zoho Sheet. Having made it across the web, Checkbox is familiar but is still elusive to most spreadsheet software. Special developer ribbons, macros and all other complexities to add a checkbox to a spreadsheet? Not in Zoho Sheet. How to add Checkbox to Zoho Sheet? Adding a Checkbox in Zoho Sheet is simple. Select a cell/range and choose "Checkbox" in "Input Controls" under the Format
I want to delete payment detail of my cards from the system.
I want to delete payment detail of my cards from the system.
Custom Calendar View for a Custom Module in Zoho CRM
Hello everyone, I’m looking to create a calendar view (monthly grid, similar to Google Calendar) for a custom module in Zoho CRM, based on a date field within that module. The goal is to have a highly customized visual layout — colors depending on the
Enhancements related to emails
Dear All, We hope you're well! We talked about the new email configuration in our previous announcement. In line with that, we're here with a few enhancements related to emails in Zoho CRM to improve how users view their emails and attachments from within
Project Change Orders and Additions
We are in the process of migrating from QuickBooks Online to Zoho Books. We have Zoho One and like the ability to sync all of our data across everything. And I like that projects work in a way that's less dumb than QuickBooks. I'm trying to figure out
How Can I Recover My Website After the August Spam Update?
Hi everyone, My website was hit quite badly during the August spam update 2026, and I'm trying to understand what I should do to recover it. My traffic and search visibility have dropped, but I'm not sure what exactly caused the problem. I have already
Assembly Reporting in Composite Item View - Add 'Per-Unit Cost' Column
When a user in the UI goes to a Composite Item, looks under Transactions, and selects Assemblies, the screen below is shown. This is all good information, but one piece of very important data is missing... the per-unit cost. I realize that for those on
Zoho Deluge Outage
Hello Enterprise Support Community, We wanted to make you aware that we are currently experiencing an outage affecting Zoho Deluge. Our developers are actively investigating the issue and working to restore service as quickly as possible. We apologize
Impact/Best Practices when "US Zoho Services Availability - Incident, Zoho Deluge is down"
I've been seeing this more recently and I've been wondering exactly what that means/affects and how to best address it when it does. I can check for function failures, but are all function calls when this happens logged a failure, or are errors silently
Day 2: Wait, where did everything go?
You log in the next morning, and the setup you finished yesterday is nowhere to be found. You are having a hard time finding your data. Here is where to look. In this post I logged in, and my data is gone. Where is it? I set things up, but I am looking
Estimates or quotes in Inventory
Our pottery wholesale business is heavily inventory based. We are planning to switch from Quickbooks to Zoho Inventory which will be a great improvement on the "sales" side for in-house sales and salesreps. The only thing we are missing in Zoho Inventory
CLIENT PORTAL (If clients can place orders directly on the portal)
Zoho client portal is excellent. Everything is there except one thing. Client should be able to place orders directly on the portal. This would enhance the portal and end users will be extremely happy. This suggestion infact came from one of our client.
Deal win rate
Hi, I would like to know something very simple, yet very important. Wath is the winning rate of the deals I've created. For exemple, what percentage of the deal i've close the last month where wins. Would seems easy to find... but can see a report for that... Help please.
Create Flexible Layouts with Layout Rules
In a project, when a work moves from planning to execution, the information teams need can change at every stage. A project can need one set of details, a phase can need another, and a custom process may require an entirely different set of information.
Zoho Team Inbox - roadmap
Hi, would be good to understand the Teaminbox roadmap, in particular: 1. API / Zoho Deluge connections. We have a process where the each email needs to be either tagged or assigned daily. It would be great if we could automate a 5pm alert for any exemptions
Conditional branching in Zoho Desk with Automation Studio
Hello everyone, We are introducing conditional branching that will allow businesses to manage complex, multi-condition workflows for customer service processes using Automation Studio. The primary goal is to create multi-branched logic in a single rule.
Custom Function to increment a value by one
Hi, I'm trying to find a solution to set up a counter on CRM records that tracks how many times certain actions have taken place. As a specific example: We have a field on Deals called "Times Close Updated". This starts at 0 on record creation. I'd like
Guide customers to the right booking page with routing forms
Greetings from the Zoho Bookings team! We're excited to introduce Routing Forms in Zoho Bookings. Routing forms let you collect information from customers before they schedule an appointment and automatically direct them to the most appropriate booking
One flow for fulfillment exceptions across CRM, Inventory, and Desk | Kiosk Studio Session #11
Hello folks, Some orders get flagged in the fulfillment stage. One is short by six units, with nothing from the warehouse explaining why. Another shipped in full three days ago and still reads as pending, because the carrier never posted a scan. A third
Zoho CRM Community Digest - August 2026 | Part 2
Hello everyone! August's second half brought a strong set of updates to Zoho CRM. The Functions experience gets a complete redesign, Incentives brings commission management natively inside the platform, and Dashboards pick up four focused improvements.
Spam Control in Zoho Mail: Manage and Filter Incoming Emails for Your Organization
Unwanted emails are a common challenge for organizations of all sizes. Without a structured spam control system, spam emails can flood user inboxes, expose sensitive data, and disrupt communication. Zoho Mail's Spam Control feature gives administrators
[Webinar] Automating document review and approval workflows
Live webinar on September 10, 2026 | Time: 2 PM IST | 2 PM EDT Hi, Still juggling multiple tools, chasing approvers manually, and losing visibility into where your documents stand? Join our live webinar to learn how Zoho Writer's built-in workflow engine
Version Control and Git Integration for Zoho Creator Applications
As Zoho Creator applications grow in complexity, managing code changes, tracking history, and collaborating across developers becomes increasingly difficult. Currently there is no native way to: Track what changed, when, and by whom across Deluge functions,
Zoho Inventory - Imporoved Order Fulfillment Reporting
Hi Inventory Team, i've tried to contact you through support@eu.zohoinventory.com but haven't received a response. I am contacting you on behalf of a client. Our client is a car parts wholesale business and we set them up on Zoho Inventory earlier this
Zoho Webinar - Sharing System Audio (NOT AVAILABLE)
Hi, We are having a serious problem with Zoho Webinar. In the webinars we run, we very often share the audio from a video we are streaming directly from YouTube or other applications. Until recently we were using Zoom, but as we use other Zoho applications
Phone field Zoho CRM E.164 format
Hi, We have a webhook triggered flow in Zoho Flow which creates a lead in Zoho CRM. However, the phone format is not always in E.164 format. How can I solve this problem? Do I need a custom function within Zoho Flow or in Zoho CRM? So the following formats
Workshops Zoho – 5 & 6 novembre 2026 | Paris
Les Workshops Zoho reviennent en France avec une édition pensée pour tous les niveaux ! Les 5 et 6 novembre, nous vous donnons rendez-vous au Mercure Hôtel Paris Porte de Versailles Expo pour deux jours de formation pratique, de démonstrations en direct
Stock Based Sort-by option in Category Pages
In a category page product with In-Stock should come in the top of the categories product list rather than out-of-stock products. No having this option is extremely disappointing, I made the initial request about 7 months ago but still not even an update
Zoho Books - France
L’équipe de Zoho France reçoit régulièrement des questions sur la conformité de ses applications de finances (Zoho Books/ Zoho Invoice) pour le marché français. Voici quelques points pour clarifier la question : Zoho Books est un logiciel de comptabilité
Editting PDF in Zoho online editor doesnt work
I just tried editting a simple 3 page PDF but it opens up blank. I dont see any errors or feedback if something went wrong
Next Page