Zoho Books
Zoho Books API integration with managed OAuth. Manage invoices, contacts, bills, expenses, and other accounting data. Use this skill when users want to read, create, update, or delete invoices, contac
Zoho Books API integration with managed OAuth. Manage invoices, contacts, bills, expenses, and other accounting data. Use this skill when users want to read, create, update, or delete invoices, contac
Real data. Real impact.
Emerging
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
Access the Zoho Books API with managed OAuth authentication. Manage invoices, contacts, bills, expenses, sales orders, purchase orders, and other accounting data with full CRUD operations.
# List contacts python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-books/books/v3/contacts') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
https://gateway.maton.ai/zoho-books/books/v3/{endpoint}
The gateway proxies requests to
www.zohoapis.com/books/v3 and automatically injects your OAuth token.
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as
MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Manage your Zoho Books OAuth connections at
https://ctrl.maton.ai.
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=zoho-books&status=ACTIVE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'zoho-books'}).encode() req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Response:
{ "connection": { "connection_id": "21fd90f9-5935-43cd-b6c8-bde9d915ca80", "status": "ACTIVE", "creation_time": "2025-12-08T07:20:53.488460Z", "last_updated_time": "2026-01-31T20:03:32.593153Z", "url": "https://connect.maton.ai/?session_token=...", "app": "zoho-books", "metadata": {} } }
Open the returned
url in a browser to complete OAuth authorization.
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
If you have multiple Zoho Books connections, specify which one to use with the
Maton-Connection header:
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-books/books/v3/contacts') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
If omitted, the gateway uses the default (oldest) active connection.
Zoho Books organizes data into modules. Key modules include:
| Module | Endpoint | Description |
|---|---|---|
| Contacts | | Customers and vendors |
| Invoices | | Sales invoices |
| Bills | | Vendor bills |
| Expenses | | Business expenses |
| Sales Orders | | Sales orders |
| Purchase Orders | | Purchase orders |
| Credit Notes | | Customer credit notes |
| Recurring Invoices | | Automated recurring invoices |
| Recurring Bills | | Automated recurring bills |
GET /zoho-books/books/v3/contacts
Example:
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-books/books/v3/contacts') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Response:
{ "code": 0, "message": "success", "contacts": [...], "page_context": { "page": 1, "per_page": 200, "has_more_page": false, "sort_column": "contact_name", "sort_order": "A" } }
GET /zoho-books/books/v3/contacts/{contact_id}
Example:
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-books/books/v3/contacts/8527119000000099001') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
POST /zoho-books/books/v3/contacts Content-Type: application/json{ "contact_name": "Customer Name", "contact_type": "customer" }
Required Fields:
contact_name - Display name for the contactcontact_type - Either customer or vendorOptional Fields:
company_name - Legal entity nameemail - Email addressphone - Phone numberbilling_address - Address objectpayment_terms - Days for paymentExample:
python <<'EOF' import urllib.request, os, json data = json.dumps({ "contact_name": "Acme Corporation", "contact_type": "customer", "company_name": "Acme Corp", "email": "billing@acme.com", "phone": "+1-555-1234" }).encode() req = urllib.request.Request('https://gateway.maton.ai/zoho-books/books/v3/contacts', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Response:
{ "code": 0, "message": "The contact has been added.", "contact": { "contact_id": "8527119000000099001", "contact_name": "Acme Corporation", "company_name": "Acme Corp", "contact_type": "customer", ... } }
PUT /zoho-books/books/v3/contacts/{contact_id} Content-Type: application/json{ "contact_name": "Updated Name", "phone": "+1-555-9999" }
Example:
python <<'EOF' import urllib.request, os, json data = json.dumps({ "contact_name": "Acme Corporation Updated", "phone": "+1-555-9999" }).encode() req = urllib.request.Request('https://gateway.maton.ai/zoho-books/books/v3/contacts/8527119000000099001', data=data, method='PUT') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
DELETE /zoho-books/books/v3/contacts/{contact_id}
Example:
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-books/books/v3/contacts/8527119000000099001', method='DELETE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Response:
{ "code": 0, "message": "The customer has been deleted." }
GET /zoho-books/books/v3/invoices
Example:
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-books/books/v3/invoices') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
GET /zoho-books/books/v3/invoices/{invoice_id}
POST /zoho-books/books/v3/invoices Content-Type: application/json{ "customer_id": "8527119000000099001", "line_items": [ { "item_id": "8527119000000100001", "quantity": 1, "rate": 100.00 } ] }
Required Fields:
customer_id - Customer identifierline_items - Array of items with item_id or manual entryOptional Fields:
invoice_number - Auto-generated if not specifieddate - Invoice date (yyyy-mm-dd format)due_date - Payment due datediscount - Percentage or fixed amountpayment_terms - Days until duePUT /zoho-books/books/v3/invoices/{invoice_id}
DELETE /zoho-books/books/v3/invoices/{invoice_id}
# Mark as sent POST /zoho-books/books/v3/invoices/{invoice_id}/status/sentVoid invoice
POST /zoho-books/books/v3/invoices/{invoice_id}/status/void
Email invoice
POST /zoho-books/books/v3/invoices/{invoice_id}/email
GET /zoho-books/books/v3/bills
Example:
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-books/books/v3/bills') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
POST /zoho-books/books/v3/bills Content-Type: application/json{ "vendor_id": "8527119000000099002", "bill_number": "BILL-001", "date": "2026-02-06", "line_items": [ { "account_id": "8527119000000100002", "description": "Office Supplies", "amount": 150.00 } ] }
Required Fields:
vendor_id - Vendor identifierbill_number - Unique bill numberdate - Bill date (yyyy-mm-dd)PUT /zoho-books/books/v3/bills/{bill_id}
DELETE /zoho-books/books/v3/bills/{bill_id}
GET /zoho-books/books/v3/expenses
Example:
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/zoho-books/books/v3/expenses') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
POST /zoho-books/books/v3/expenses Content-Type: application/json{ "account_id": "8527119000000100003", "date": "2026-02-06", "amount": 75.50, "paid_through_account_id": "8527119000000100004", "description": "Business lunch" }
Required Fields:
account_id - Expense account IDdate - Expense date (yyyy-mm-dd)amount - Expense amountpaid_through_account_id - Payment account IDOptional Fields:
description - Expense detailscustomer_id - Billable customer IDis_billable - Boolean for billable expensesproject_id - Associated projectPUT /zoho-books/books/v3/expenses/{expense_id}
DELETE /zoho-books/books/v3/expenses/{expense_id}
GET /zoho-books/books/v3/salesorders
POST /zoho-books/books/v3/salesorders
GET /zoho-books/books/v3/purchaseorders
POST /zoho-books/books/v3/purchaseorders
GET /zoho-books/books/v3/creditnotes
GET /zoho-books/books/v3/recurringinvoices
GET /zoho-books/books/v3/recurringbills
Zoho Books uses page-based pagination:
GET /zoho-books/books/v3/contacts?page=1&per_page=50
Response includes pagination info in
page_context:
{ "code": 0, "message": "success", "contacts": [...], "page_context": { "page": 1, "per_page": 50, "has_more_page": true, "sort_column": "contact_name", "sort_order": "A" } }
Continue fetching while
has_more_page is true, incrementing page each time.
const response = await fetch( 'https://gateway.maton.ai/zoho-books/books/v3/contacts', { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } } ); const data = await response.json();
import os import requestsresponse = requests.get( 'https://gateway.maton.ai/zoho-books/books/v3/contacts', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'} ) data = response.json()
code: 0 and a message fieldyyyy-mm-dd formatcustomer or vendorcurl -g when URLs contain brackets to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| Status | Meaning |
|---|---|
| 400 | Missing Zoho Books connection or invalid request |
| 401 | Invalid or missing Maton API key, or OAuth scope mismatch |
| 404 | Resource not found |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Zoho Books API |
| Code | Description |
|---|---|
| 0 | Success |
| 57 | Not authorized (OAuth scope mismatch) |
| 1 | Invalid value |
| 2 | Mandatory field missing |
| 3 | Resource does not exist |
| 5 | Invalid URL |
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
zoho-books. For example:https://gateway.maton.ai/zoho-books/books/v3/contactshttps://gateway.maton.ai/books/v3/contactsNo automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.