ERPNext API Patterns API Type Decision Tree What do you want to achieve? │ ├─► CRUD operations on documents │ └─► REST API: /api/resource/{doctype} │ ├─► Call custom business logic │ └─► RPC API: /api/method/{path} │ ├─► Notify external systems on events │ └─► Configure Webhooks │ └─► Client-side server calls (JavaScript) └─► frappe.call() or frappe.xcall() Quick Reference Authentication Headers
Token Auth (RECOMMENDED for integrations)
headers
{ 'Authorization' : 'token api_key:api_secret' , 'Accept' : 'application/json' , 'Content-Type' : 'application/json' }
Bearer Token (OAuth2)
headers
{ 'Authorization' : 'Bearer {access_token}' } REST API CRUD Operation Method Endpoint List GET /api/resource/{doctype} Create POST /api/resource/{doctype} Read GET /api/resource/{doctype}/{name} Update PUT /api/resource/{doctype}/{name} Delete DELETE /api/resource/{doctype}/{name} Filter Operators
Basic filters
filters
[ [ "status" , "=" , "Open" ] ] filters = [ [ "amount" , ">" , 1000 ] ] filters = [ [ "status" , "in" , [ "Open" , "Pending" ] ] ] filters = [ [ "date" , "between" , [ "2024-01-01" , "2024-12-31" ] ] ] filters = [ [ "reference" , "is" , "set" ] ]
NOT NULL
RPC Method Call
Server-side: mark with decorator
@frappe . whitelist ( ) def my_function ( param1 , param2 ) : return { "result" : "value" }
API call
POST / api / method / my_app . api . my_function { "param1" : "value1" , "param2" : "value2" } Client-Side Calls (JavaScript) // Async/await pattern (RECOMMENDED) const result = await frappe . xcall ( 'my_app.api.my_function' , { param1 : 'value' } ) ; // Promise pattern frappe . call ( { method : 'my_app.api.my_function' , args : { param1 : 'value' } , freeze : true , freeze_message : __ ( 'Processing...' ) } ) . then ( r => console . log ( r . message ) ) ; Response Structure REST API Success: { "data" : { ... } } RPC API Success: { "message" : "return_value" } Error Response: { "exc_type" : "ValidationError" , "_server_messages" : "[{\"message\": \"Error details\"}]" } HTTP Status Codes Code Meaning 200 Success 400 Validation error 401 No authentication 403 No permissions 404 Document not found 417 Server exception 429 Rate limit exceeded Critical Rules ALWAYS include Accept: application/json header ALWAYS add permission checks in whitelisted methods NEVER hardcode credentials - use frappe.conf NEVER write SQL injection vulnerable queries GET for read-only, POST for state-changing operations Reference Files File Contents authentication-methods.md Token, Session, OAuth2 implementation rest-api-reference.md Complete REST API with filters and pagination rpc-api-reference.md Whitelisted methods and frappe.call patterns webhooks-reference.md Webhook configuration and security anti-patterns.md Common mistakes and fixes Version Notes (v14 vs v15) Feature v14 v15 expand_links parameter ❌ ✅ Server Script rate limiting ❌ ✅ PKCE for OAuth2 Limited ✅