ERPNEXT FURNITURE MANUFACTURING
Give your AI agent deep expertise in ERPNext for furniture manufacturing. Covers the full REST API, Bills of Materials, work orders, production planning, inventory, and AI-powered operations on the edge.
LIVE v1.0 Manufacturing REST API Frappe Edge AI
npx skills add imbilawork/2nth-skills@erpnext-furniture
01

OVERVIEW

ERPNext is an open-source ERP built on the Frappe framework. It's widely used in manufacturing, especially for make-to-order and make-to-stock operations. This skill is tailored for furniture manufacturing — covering BOMs, production routing, timber/hardware inventory, and quality inspection.

ERPNext exposes a comprehensive REST API for every doctype, plus an RPC API for server-side methods. This skill gives AI agents the knowledge to query, automate, and report on a furniture factory — without hallucinating endpoints or field names.

API Type
REST + RPC
Auth
TOKEN / BASIC
Framework
FRAPPE
Doctypes
12+ MFG
02

ARCHITECTURE

The recommended pattern uses a Cloudflare Worker as a proxy — this avoids CORS, secures API keys at the edge, and enables AI analysis via Workers AI.

User / Dashboard
Cloudflare Worker
Proxy + AI
ERPNext
REST / RPC API

Base URL

GET  https://<site>/api/resource/<DocType>
POST https://<site>/api/method/<dotted.path>

Authentication

# API Key + Secret (recommended)
Authorization: token api_key:api_secret

# Or Basic Auth
Authorization: Basic base64(user:password)
Security

Never expose API keys in client-side code. Use a Cloudflare Worker proxy with secrets stored via wrangler secret put.

03

CAPABILITIES

What your agent can do with this skill installed:

  • Manage BOMs — create, explode, and cost Bills of Materials for furniture
  • Schedule production — work orders, job cards, workstation capacity
  • Track inventory — stock levels, reorder alerts, material transfers
  • Process sales — orders, deliveries, invoices, customer analytics
  • Handle procurement — purchase orders, supplier performance, cost tracking
  • Quality control — inspections, readings, pass/fail automation
  • Generate reports — revenue, production output, material usage, margins
  • Natural language queries — translate questions into ERPNext API calls
  • Deploy to edge — Cloudflare Workers proxy with AI analysis
04

KEY DOCTYPES

ERPNext uses "doctypes" — each is a data model with its own REST endpoint.

DoctypeEndpointFurniture Context
Item/api/resource/ItemFinished furniture, timber, hardware, fabric
BOM/api/resource/BOMRecipe: 4 legs + 1 top + 8 screws = Table
Work Order/api/resource/Work Order"Make 30 Dining Tables"
Job Card/api/resource/Job CardCNC cutting, assembly, finishing steps
Workstation/api/resource/WorkstationCNC Router, Spray Booth, Assembly Line
Stock Entry/api/resource/Stock EntryMaterial issue, manufacture, transfer
Quality Inspection/api/resource/Quality InspectionSurface finish, dimensions, joint strength
Sales Order/api/resource/Sales OrderRetailer and custom orders
Purchase Order/api/resource/Purchase OrderTimber, hardware, finish supplies

Item Groups (furniture setup)

All Item Groups ├── Finished Goods │ ├── Dining / Lounge / Bedroom / Storage / Custom ├── Raw Material │ ├── Timber / Board & Panel / Fabric & Foam / Finish / Hardware ├── Sub Assembly │ └── Frames / Tops & Surfaces / Upholstered Parts └── Consumable └── Sandpaper / PPE / Packaging
05

MANUFACTURING FLOW

Sales Order
Work Order
from BOM
Job Cards
per operation
Stock Entry
manufacture
QC → Ship

Operations Routing (typical furniture)

#OperationWorkstationTime
1CNC CuttingCNC Router15-45 min
2MachiningCNC Router / Mortiser10-30 min
3JoiningAssembly Bench20-60 min
4SandingSanding Station15-30 min
5FinishingSpray Booth / Oil Station20-45 min
6UpholsteryUpholstery Bench30-60 min
7Final AssemblyAssembly Line15-45 min
8QCInspection Station10-20 min

Example BOM — Dining Table

{
  "item": "NOHA-DINING-TABLE-8",
  "quantity": 1,
  "items": [
    {"item_code": "RM-OAK-25MM",     "qty": 24,  "uom": "Board Foot"},
    {"item_code": "RM-OAK-VENEER",   "qty": 2.4, "uom": "Square Meter"},
    {"item_code": "HW-BOLT-M8X60",   "qty": 16,  "uom": "Nos"},
    {"item_code": "HW-BRACKET-L",    "qty": 8,   "uom": "Nos"},
    {"item_code": "FN-DANISH-OIL",   "qty": 0.8, "uom": "Litre"},
    {"item_code": "FN-SANDPAPER-180","qty": 4,   "uom": "Sheet"}
  ]
}
06

API PATTERNS

List Records

GET /api/resource/Item
  ?filters=[["item_group","=","Finished Goods"]]
  &fields=["name","item_name","standard_rate","stock_uom"]
  &limit_page_length=50
  &order_by=item_name asc

Active Work Orders

GET /api/resource/Work Order
  ?filters=[["status","in",["Not Started","In Process"]],["docstatus","=",1]]
  &fields=["name","production_item","qty","produced_qty","status","planned_start_date"]
  &order_by=planned_start_date asc

Explode BOM (get all materials for a batch)

POST /api/method/erpnext.manufacturing.doctype.bom.bom.get_bom_items
{"bom":"BOM-NOHA-DINING-TABLE-001","qty":30,"fetch_exploded":1}

Stock Balance

POST /api/method/erpnext.stock.utils.get_stock_balance
{"item_code":"RM-OAK-25MM","warehouse":"Raw Materials Store"}

Filter Operators

OperatorMeaningExample
=Equals["status","=","Open"]
!=Not equals["status","!=","Cancelled"]
> / >=Greater than["qty",">",0]
likeWildcard["item_name","like","%Oak%"]
inIn list["status","in",["Open","In Process"]]
betweenDate range["posting_date","between",["2026-01-01","2026-03-31"]]
07

REPORTING PATTERNS

ERPNext supports server-side aggregation via frappe.client.get_list with group_by.

Revenue by Customer

POST /api/method/frappe.client.get_list
{
  "doctype": "Sales Invoice",
  "filters": [["docstatus","=",1],["posting_date",">=","2026-01-01"]],
  "fields": ["customer","sum(grand_total) as revenue"],
  "group_by": "customer",
  "order_by": "revenue desc",
  "limit_page_length": 20
}

Production Output by Product

POST /api/method/frappe.client.get_list
{
  "doctype": "Work Order",
  "filters": [["status","=","Completed"],["actual_end_date",">=","2026-03-01"]],
  "fields": ["production_item","sum(produced_qty) as total_produced"],
  "group_by": "production_item",
  "order_by": "total_produced desc"
}

Material Usage This Month

GET /api/resource/Stock Ledger Entry
  ?filters=[["voucher_type","=","Stock Entry"],["posting_date",">=","2026-03-01"],["actual_qty","<",0]]
  &fields=["item_code","sum(actual_qty) as total_issued"]
  &group_by=item_code
  &order_by=total_issued asc
08

AI INTEGRATION

Natural language in, operational intelligence out.

User Question
LLM generates
API call
Execute on
ERPNext
LLM analyzes
results
Report

Cloudflare Worker Proxy

async function proxyERPNext(request, env) {
  const url = new URL(request.url);
  const erpPath = url.pathname.replace('/api/erp/', '/api/');
  const erpUrl = `${env.ERPNEXT_URL}${erpPath}${url.search}`;

  return fetch(erpUrl, {
    method: request.method,
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `token ${env.ERPNEXT_API_KEY}:${env.ERPNEXT_API_SECRET}`,
    },
    body: request.method !== 'GET' ? await request.text() : undefined,
  });
}

System Prompt for Query Generation

You are an ERPNext API expert for a furniture manufacturer.
Generate the API call for the user's question.

API: GET /api/resource/<DocType>?filters=...&fields=...
RPC: POST /api/method/<dotted.path>

Key doctypes: Item, BOM, Work Order, Job Card, Stock Entry,
Sales Order, Purchase Order, Quality Inspection, Bin.

Filters: JSON arrays [field, operator, value].
Always include docstatus=1 for submitted docs.
Respond with HTTP method, path, and body only.
09

INSTALL

Works with Claude Code, Cursor, Windsurf, Cline, and 30+ other AI agents:

npx skills add imbilawork/2nth-skills@erpnext-furniture

Or install globally with no prompts:

npx skills add imbilawork/2nth-skills@erpnext-furniture -g -y

The skill loads automatically when your agent works on ERPNext or manufacturing tasks.

10

GOTCHAS

IssueDetail
Docstatus0=Draft, 1=Submitted, 2=Cancelled. Most queries need ["docstatus","=",1]
PaginationDefault limit_page_length=20. Set explicitly or use 0 for all (careful)
Child tablesBOM items, SO items are child tables — fetch via parent or fields=["items.item_code"]
Rate limitsFrappe defaults to 5 req/sec for API keys
Naming seriesUse name (ID) not item_name for lookups
BOM versioningMultiple BOMs per item — filter is_active=1 and is_default=1
Stock Entry types"Material Issue", "Material Transfer for Manufacture", "Manufacture"
CORSBrowser requests may be blocked — use a server-side proxy