Send WhatsApp invoice alerts the moment a Zoho Books invoice is created or paid, and automate payment reminders from outstanding receivables. OAuth 2.0 setup, India-region domain, workflow webhook configuration, and live balance queries covered.
Zoho operates regional data centres. Indian Zoho Books accounts use https://www.zohoapis.in/books/v3/ and https://accounts.zoho.in/oauth/v2/. Using the .com domain with an Indian account returns errors or empty responses. If you are unsure of your region, log in to your Zoho account and check the URL: accounts.zoho.in confirms the India region.
Zoho Books supports multiple organisations per account. Every API endpoint requires ?organization_id=YOUR_ORG_ID as a query parameter. Omitting it returns an error. Retrieve it once with GET /books/v3/organizations and store it for all future calls.
Zoho Books uses OAuth 2.0. For a server-to-server integration (where you control both Zoho Books and WA.Expert), use the Self Client flow in the Zoho Developer Console. This avoids building a full redirect-URI flow.
ZohoBooks.fullaccess.all
(or narrower scopes: ZohoBooks.invoices.READ,ZohoBooks.invoices.CREATE,ZohoBooks.settings.CREATE).
Set Time Duration to the longest available (typically 10 minutes).POST https://accounts.zoho.in/oauth/v2/token
Content-Type: application/x-www-form-urlencoded
Body (form-encoded):
grant_type=authorization_code
&code=YOUR_GRANT_TOKEN
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&redirect_uri=https://www.zoho.in/books
Response:
{
"access_token": "1000.41d9xxxx...c2d1",
"refresh_token": "1000.xxxx...yyyy",
"expires_in": 3600,
"token_type": "Bearer"
}
Store both. Use access_token in API calls.
Refresh when it expires (after 1 hour).POST https://accounts.zoho.in/oauth/v2/token Content-Type: application/x-www-form-urlencoded Body: grant_type=refresh_token &refresh_token=YOUR_REFRESH_TOKEN &client_id=YOUR_CLIENT_ID &client_secret=YOUR_CLIENT_SECRET Response: new access_token (valid another 1 hour). Run this automatically when you receive a 401 response.
GET https://www.zohoapis.in/books/v3/organizations
Authorization: Zoho-oauthtoken YOUR_ACCESS_TOKEN
Response:
{
"organizations": [
{
"organization_id": "10234695",
"name": "ABC Traders",
"country_code": "IN",
"currency_code": "INR"
}
]
}
Copy organization_id and add it to every subsequent request:
?organization_id=10234695Zoho Books uses a specific prefix in the Authorization header: Zoho-oauthtoken YOUR_ACCESS_TOKEN. Not Bearer, not token. The exact string is Zoho-oauthtoken followed by a space and the token.
Configure a Workflow Rule in Zoho Books so that when an invoice is created or a payment is received, Zoho Books POSTs the details to your WA.Expert automation URL automatically.
Zoho Books API: zoho.com/books/api/v3
{
"invoice_id": "INV-000142",
"customer_name": "Priya Textiles",
"mobile": "9820012345",
"total": 48500.00,
"balance": 48500.00,
"due_date": "2026-07-07",
"status": "sent",
"currency_code": "INR"
}
Map to WA.Expert variables:
customer_name -> party_name
"+91" + mobile -> wa_phone <- PREPEND +91 if bare 10-digit
invoice_id -> invoice_number
total -> invoice_amount
due_date -> payment_due
balance -> outstandingRun a scheduled WA.Expert automation each morning that pulls all overdue invoices and sends payment reminder WhatsApp messages.
GET https://www.zohoapis.in/books/v3/invoices
?organization_id=10234695
&status=overdue
&sort_column=due_date
&sort_order=A
Authorization: Zoho-oauthtoken YOUR_ACCESS_TOKEN
Response:
{
"code": 0,
"invoices": [
{
"invoice_id": "INV-000138",
"customer_name": "Rajesh Enterprises",
"mobile": "9820012345",
"total": 22000.00,
"balance": 22000.00,
"due_date": "2026-06-20"
}
]
}
For each invoice in the response:
wa_phone = "+91" + mobile
Send WhatsApp payment reminder with invoice_id, balance, due_date.Trigger: Every day at 9:00 AM IST (scheduled)
Step 1 (External API Request — GET overdue invoices):
GET https://www.zohoapis.in/books/v3/invoices
?organization_id=10234695&status=overdue
Authorization: Zoho-oauthtoken ACCESS_TOKEN
Step 2 (Loop through each invoice):
For each invoice where balance > 0:
wa_phone = '+91' + invoice.mobile
Send WhatsApp utility template:
'Dear Rajesh Enterprises,
Invoice INV-000138 for Rs. 22,000 was due on 20 June.
Kindly arrange payment. Reply here for any queries.'| Symptom | Likely cause | Fix |
|---|---|---|
| Invalid domain / 404 errors | Using .com domain for Indian account | Indian Zoho Books accounts use zohoapis.in. Replace all .com with .in in your API URLs and oauth URLs. |
| 401 Unauthorized | Access token expired or wrong format | Access tokens expire after 1 hour. Use the refresh token to get a new one. Header must be 'Zoho-oauthtoken TOKEN' (not Bearer, not token). |
| org_id required / error | organization_id missing | Add ?organization_id=YOUR_ORG_ID to every API call. Retrieve the ID from GET /books/v3/organizations. |
| Grant token expired | Grant token not exchanged within 10 minutes | The Self Client grant token is valid for only a few minutes. Generate a new grant token and exchange it immediately. |
| Workflow webhook not firing | Workflow rule condition not matching | Check the Workflow Rule conditions in Zoho Books. If the rule has a status condition, ensure new invoices match that status. |
| Mobile number missing from payload | Not set on Contact record | Ensure the mobile number is stored on the customer's Contact record in Zoho Books. Prepend +91 to bare 10-digit numbers before sending WhatsApp. |
ERPNext: open-source ERP with token auth and built-in webhooks.
Read guideTallyPrime: XML-over-HTTP gateway, payment reminders, voucher creation.
Read guideFree trial, no credit card. If you get stuck, we answer live on WhatsApp.