Zoho Books API: Bulk update thousands of records using Node.js with OAuth refresh, retries and resume support

Zoho Books API: Bulk update thousands of records using Node.js with OAuth refresh, retries and resume support

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

  1. Create a custom view containing the records that need to be updated.
  2. Export the records and extract their IDs into a text file (one ID per line).
  3. Point the script at the IDs file.
  4. Define the custom fields and new values in .env.
  5. Run the migration in three stages: probedry-runrun.

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