Loading...
Loading...
Zoho Books and Zoho Inventory API integration for TSH Clients Console. Use when: (1) Creating new API routes that call Zoho endpoints (2) Debugging API errors, token issues, or rate limits (3) Adding new Zoho data fetching functions (4) Understanding OAuth token caching with Upstash Redis (5) Working with products, orders, invoices, payments, or credit notes (6) Troubleshooting "Contact for price" or stock display issues
npx skill4agent add qmop1967/clients-console zoho-api| API | Base URL |
|---|---|
| Zoho Inventory | |
| Zoho Books | |
748369814| File | Purpose |
|---|---|
| OAuth client, token caching, |
| Products, stock extraction |
| Price list constants and fetching |
| Customer lookup by email |
| Sales orders |
| Invoices |
| Payments |
| Credit notes |
import { zohoFetch } from '@/lib/zoho/client';
// GET request
const data = await zohoFetch('/inventory/v1/items', {
params: {
organization_id: process.env.ZOHO_ORGANIZATION_ID,
page: 1,
per_page: 100,
},
});
// Single item with locations
const item = await zohoFetch(`/inventory/v1/items/${itemId}`, {
params: { organization_id: process.env.ZOHO_ORGANIZATION_ID },
});Memory Cache → Upstash Redis → Zoho OAuth Refresh
(50-min TTL) (rate limit: 10s guard)UPSTASH_REDIS_REST_URLUPSTASH_REDIS_REST_TOKENcurl https://www.tsh.sale/api/debug/tokenGET /items # List products
GET /items/{id} # Single product (includes locations)
GET /categories # List categories
GET /pricebooks/{id} # Pricebook with itemsGET /contacts # List customers
GET /salesorders # Sales orders
GET /invoices # Invoices
GET /customerpayments # Payments
GET /creditnotes # Credit notesimport { unstable_cache } from 'next/cache';
const getCachedProducts = unstable_cache(
async () => await fetchProducts(),
['products'],
{ revalidate: 3600, tags: ['products'] }
);curl "https://www.tsh.sale/api/revalidate?tag=products&secret=tsh-revalidate-2024"try {
const data = await zohoFetch('/inventory/v1/items', { ... });
} catch (error) {
if (error.message.includes('401')) {
// Token expired - auto-refreshes
} else if (error.message.includes('429')) {
// Rate limited - wait and retry
}
}// src/app/api/zoho/[resource]/route.ts
import { NextResponse } from 'next/server';
import { zohoFetch } from '@/lib/zoho/client';
export async function GET(request: Request) {
const data = await zohoFetch('/inventory/v1/items', {
params: {
organization_id: process.env.ZOHO_ORGANIZATION_ID,
},
});
return NextResponse.json(data);
}| API | Limit |
|---|---|
| OAuth Refresh | ~100/minute |
| Inventory API | 100/minute |
| Books API | 100/minute |
# Check token
curl "https://www.tsh.sale/api/debug/token"
# Check prices
curl "https://www.tsh.sale/api/debug/prices"
# Check stock
curl "https://www.tsh.sale/api/debug/stock"
# Revalidate cache
curl "https://www.tsh.sale/api/revalidate?tag=all&secret=tsh-revalidate-2024"