Zoho Books API v3 Integration Guide
Learn how to generate Zoho Books OAuth 2.0 credentials, locate your Organization ID & Refresh Token, map ZIMRA tax rates, and enable real-time fiscal receipt writebacks.
Zoho Data Center Domains Supported
1Generate OAuth 2.0 Client in Zoho API Console
Go to the official Zoho API Console ↗. Click Add Client and select Server-based Applications.
Zoho Client Registration — Field Guide
| Field Name | Required Value |
|---|---|
| Client Type | Server-based Applications |
| Client Name | Mutero VFD |
| Homepage URL | https://www.mutero.online |
| Authorized Redirect URIs | https://www.mutero.online/api/v1/vfd/integrations/zoho-books/callback |
Click Create. In the Client Details tab, copy your Client ID, and click Client Secret to copy your secret.
2Where to Find Each Required Credential
1. Organization ID
- Log into your Zoho Books Dashboard.
- Click Settings (top right gear icon) > Organization Profile.
- Under your company name at the top, copy your Organization ID (e.g.
812345678).
Shortcut: You can also see your Organization ID directly in your browser address bar URL: https://books.zoho.com/app#/home?organization_id=812345678.
2. Data Center Domain
Look at your web browser address bar when logged into Zoho Books:
- books.zoho.com → Select zoho.com (US / Global)
- books.zoho.eu → Select zoho.eu (Europe)
- books.zoho.in → Select zoho.in (India)
- books.zoho.com.au → Select zoho.com.au (Australia)
3. Automated Access and Refresh Token Generation
1-Click Automated Authorization Setup
To generate and save your OAuth Refresh Token automatically when connecting Zoho Books in the Mutero Integrations Hub:
- Enter your Client ID and Client Secret obtained from your Server-based application in Zoho API Console.
- Copy the displayed Authorized Redirect URI (e.g.
https://www.mutero.online/api/v1/vfd/integrations/zoho-books/callback) and save it in your Zoho API Console client under Authorized Redirect URIs. - Once both Client ID and Client Secret are filled, click the Authorize Zoho ↗ button.
- Click Accept on the Zoho consent prompt. Zoho automatically redirects back to Mutero and generates your Refresh Token with zero manual token copy-pasting required.
3Token Generation Troubleshooting
Common OAuth Token Errors & Solutions
access_type=offline and prompt=consent are included when generating codes if requesting re-consent.accounts.zoho.com, accounts.zoho.eu, etc.).4Enter Credentials in Mutero Integrations Hub
Go to Integrations Hub in your Mutero Dashboard, locate Zoho Books API v3, and click Connect Zoho Books.
Required Configuration Fields Summary
5First-Time Zoho Transaction Preferences (ZIMRA FDMS Compliance)
When creating your first invoice in Zoho Books or configuring initial preferences under Settings > Preferences > Invoices, set your transaction preferences according to ZIMRA fiscalization rules:
Zoho Transaction Preferences — Recommended Settings
| Zoho Setting | Recommended Selection | ZIMRA Compliance Requirement |
|---|---|---|
| Do you give discounts? | At Line Item Level OR At Transaction Level → Discount Before Tax | ZIMRA rules (RCPT024/026) calculate 15% VAT on the net price after discounts. Never select "Discount After Tax". |
| Items sold at rates inclusive of Tax? | Tax Exclusive (or Tax Inclusive) | Select based on your catalog pricing. Mutero automatically sets receiptLinesTaxInclusive accordingly. |
| Round Off Tax | At line level (Recommended) | ZIMRA computes tax per line item. Rounding at the line level ensures Zoho's tax math matches ZIMRA's line item totals exactly without 1-cent discrepancies. |
| Rounding off in Sales Transactions | No Rounding (Crucial) | ZIMRA requires exact 2-decimal cent math (RCPT038). Rounding off total amounts can cause 1-cent checksum rejections by ZIMRA. |
| Additional Charges | Adjustments & Shipping Charges (Optional) | Enable as needed. Ensure shipping rates carry appropriate VAT codes if taxable. |
Currency & payment method
Mutero reads Zoho's native invoice currency_code (USD, ZiG/ZWG, etc.) — this is a standard Zoho field, not a Mutero custom field. Set the invoice currency in Zoho when you create the invoice. Payment method is not synced from Zoho; Mutero submits Cash to ZIMRA by default (required on every fiscal receipt).
Adding Tax Rates in Zoho Books (Settings > Taxes > + New Tax)
Create the three standard ZIMRA tax entries in Zoho Books under Settings > Taxes > Tax Rates > + New Tax:
| Tax Name* | Rate (%)* | Compound Tax? | Automatic ZIMRA Mapping |
|---|---|---|---|
| VAT (15%) or Standard Rate | 15% | Unchecked (No) | Standard Rate (ZIMRA Tax ID 1) |
| Zero Rated (0%) or Export | 0% | Unchecked (No) | Zero Rated (ZIMRA Tax ID 2) |
| Exempt or NOP | 0% | Unchecked (No) | Exempt (ZIMRA Tax ID 3) |
Note: Do not check "This tax is a compound tax" as ZIMRA VAT is a single-tier tax. Mutero automatically maps these tax names to ZIMRA's numeric Tax IDs.
Unknown Zoho tax names never default to 15%
buyerData (register name + TIN, RCPT043) on both webhook and Sync Now paths.HS Code Configuration for Zero-Rated (0%) & Exempt Items
ZIMRA regulations require an 8-digit Harmonized System (HS) tariff code (e.g. 1001.11.00) for zero-rated or exempt sales to justify tax exemption during audit.
How Mutero handles HS codes for Zoho Books:
- Automatic Default Mapping (Recommended): In Mutero Dashboard → Settings > Integrations > Tax Mapping, assign your fallback 8-digit tariff code to your Zero-Rated tax mapping. All zero-rated items imported from Zoho Books will automatically inherit this 8-digit code.
- Zoho Custom Fields (Per Item): In Zoho Books, under Settings > Preferences > Items > Custom Fields, add a text field named
HS Code. Mutero automatically extracts this field during sync. - Standard 15% VAT & General Services: Items with standard 15% VAT that do not specify an HS code automatically default to ZIMRA fallback tariff
0000.00.00to prevent 422 payload rejections.
6Automatic ZIMRA Receipt Writeback Behavior
Once connected, Mutero monitors Zoho Books for approved sales invoices. Upon fiscalization, Mutero automatically:
- Signs the invoice payload using ZIMRA FDMS cryptographic keys.
- Posts a comment to the invoice timeline in Zoho Books containing the ZIMRA Receipt Number and Verification QR Link.
- Optionally updates configured custom fields (
Custom Field Receipt NumberandCustom Field Verification Link).
6bHow to issue a credit note
Easiest option: Mutero web app
To keep Zoho in sync, create the credit note in Zoho Books against an invoice Mutero has already fiscalised.
Steps in Zoho Books
- Open the original sales invoice (it should already show an FRN in Mutero).
- Click Credit Note (or create one from the Credit Notes module and link that invoice).
- Add a short reason in the notes / reference field.
- Save it (not as Draft).
What happens next
For real-time credit notes
- Reuse the same Mutero webhook URL (with your business_id).
- Add a Zoho workflow on the Credit Notes module (Created / Edited), excluding Draft and Void.
- Attach the Mutero webhook action.
7Auto-Fiscalize Zoho Invoices (Required for Real-Time)
What this enables
A. Enable Auto Fiscalize in Mutero
- Open Mutero Dashboard → Settings → Integrations (Integrations Hub).
- Confirm Zoho Books shows status Active and a default VFD device is selected.
- Turn Auto Fiscalize ON (default). When off, invoices are imported only and stay as drafts until you fiscalize manually.
- Complete Tax Mapping for your Zoho tax names (15% VAT, Zero Rated, Exempt).
- Copy your Business ID from the Integrations Hub / Business Profile — paste it as the Zoho webhook Parameter
business_id(or into the query string if you paste the full URL from Integrations Hub).
B. Your Mutero Webhook URL
Critical: use www.mutero.online — Zoho does not follow redirects
Zoho Books will show a 308 Permanent Redirect in the workflow execution log if the webhook host is wrong. That means Mutero never received the invoice (no notification, no import, no fiscalisation).
- Correct:
https://www.mutero.online/... - Wrong:
https://mutero.online/...(apex → www via 308; Zoho stops here)
Always copy the URL from Mutero → Integrations Hub, or type www. explicitly. Do not strip www.
In Zoho’s Edit Webhook screen, put the path in URL and add business_id as a separate Parameter (Zoho builds the preview query string for you):
https://www.mutero.online/api/webhooks/zoho-booksKey: business_id
Value: YOUR_MUTERO_BUSINESS_IDURL Preview should look like: https://www.mutero.online/api/webhooks/zoho-books?business_id=YOUR_MUTERO_BUSINESS_ID. Replace the value with your Mutero Business ID (24 hex characters). Do not add a trailing slash or a trailing &.
Legacy path (also public, still requires www): https://www.mutero.online/api/v1/vfd/integrations/zoho-books/webhook
C. Create the Webhook (required first)
The webhook is a reusable Zoho Workflow Action. Create and save it before (or while) building the workflow rule. Associating it later only links this saved action — it does not define the URL.
- Settings path: Zoho Books → Settings (gear) → Automation → Workflow Actions → Webhooks → + New Webhook.
- From a workflow rule: On the rule canvas, click + Immediate Actions → set Action Type to Webhooks → click the blue + Add New Action link (opens the same webhook creation form). After you save, select it and click Associate.
Fill Edit Webhook with these Mutero values (labels match the current Zoho Books UI):
| Zoho webhook field | Exact value for Mutero |
|---|---|
| Name | Mutero ZIMRA Fiscalisation Webhook |
| Module | Invoice |
| Description | Optional — e.g. “Notify Mutero when an invoice leaves draft for ZIMRA fiscalisation.” |
| Method | POST |
| URL | https://www.mutero.online/api/webhooks/zoho-booksHost must include www. Do not use apex mutero.online (308 redirect — Zoho does not follow it). |
| Parameters | Add one row: Key business_id · Value = your Mutero Business ID (24 hex). Zoho’s URL Preview should then show …/api/webhooks/zoho-books?business_id=…. Alternatively paste the full URL (with query) from Integrations Hub into URL and leave Parameters empty. |
| Headers | Leave empty (none required). |
| Authorization Type | Self Authorization |
| Body Type | Default Payload · Content-Type application/json;charset=UTF-8. Mutero accepts the invoice-only JSON Zoho sends (e.g. { "invoice": { ... } }). Root organization_id is optional when the integration is already configured. |
- Click Save (or Save and Execute to smoke-test the URL).
- Confirm the webhook appears under Settings → Automation → Workflow Actions → Webhooks and that URL Preview uses
www.mutero.onlinewithbusiness_id.
business_id vs organization_id
business_id belongs in the webhook URL / Parameters (Mutero business). organization_id is optional in the body — when present it must match the Zoho org saved in Mutero; when absent Mutero uses the stored integration credentials.D. Create the Workflow Rule (trigger)
After the webhook exists, create the rule that decides when Zoho calls it. You do not need to email the customer to fiscalise — choose a criterion that matches how you finalize invoices in Zoho.
- Go to Settings → Automation → Workflow Rules → + New Workflow Rule.
- Module: Invoice. Name:
Mutero ZIMRA Auto-Fiscalize. - Under WORKFLOW RULE EXECUTION CONDITION: Workflow Type = Event Based · Action Type = Created or Edited · Execute the workflow when = Any selected field is updated → select Status · Execute when the record is = Edited each time.
- Criterion 1: Add criteria Yes, then pick one of the options below (recommended first).
Criterion: Status isn’t Draft. Optionally add AND Status isn’t Void so cancelled invoices never fire the webhook.
This runs when an invoice leaves draft for any reason — Mark as Sent (without emailing), Approve, Paid, Overdue, Partially Paid, etc. You never have to send the invoice email just to fiscalise.
- Status is Sent — works, but only after the invoice is marked Sent. Prefer Zoho Mark as Sent (no email) over “Send Email” if you use this criterion.
- Status is Paid (or Overdue / Partially Paid) — fiscalise only after payment / aging, if that matches your process. Use OR conditions if you want several of these.
- Created only (Action Type = Created) with criterion Status isn’t Draft — if you create invoices already non-draft in one step.
Example canvas (recommended): Rule Mutero ZIMRA Auto-Fiscalize · Module Invoice · Created or edited → Any selected field is updated → Status · Criterion 1 Status isn’t Draft → TRUE → Immediate Actions.
E. Associate the Webhook on the rule
On the Criterion 1 TRUE branch, attach the webhook you created in step C:
- Click + Immediate Actions (not Time Based Actions).
- In the Associate Immediate Actions panel, set Action Type to Webhooks.
- Under Name, select Mutero ZIMRA Fiscalisation Webhook. Confirm the URL / preview uses
www.mutero.onlineand yourbusiness_id. (If the list is empty, use + Add New Action and complete step C, then return here.) - Click Associate, then Save the workflow rule.
When done, Immediate Actions should list: Webhooks / Name: Mutero ZIMRA Fiscalisation Webhook / URL pointing at Mutero (www host).
- In Zoho, create a test invoice with a mapped tax rate, then leave draft without emailing — e.g. Mark as Sent, or change status so it matches your criterion (Status isn’t Draft / Sent / Paid).
- In Zoho Workflow Logs, the webhook call must be 200 — not 308. A 308 means the URL still uses apex
mutero.online; switch towww.mutero.onlineand retest. - Within about a minute, open Mutero → Invoices — you should see
ZB-…appear. - Check the notification bell for “Zoho Books invoice received” / “Receipt fiscalized”.
- Open Sync Logs for status
webhook_received→success. - In Zoho, confirm a timeline comment with the ZIMRA FRN and verification link.