Frappe List API Guide (v15)
What is the List API in Frappe?
The List API in Frappe Framework v15 provides a Python interface to retrieve multiple documents from the database in the form of lists, using efficient query parsing and metadata-driven filtering. It reads DocType records from the database using two primary methods:
frappe.get_list()
frappe.get_all()
Both functions return a list of dictionaries containing field values, supporting filtering, pagination, ordering, grouping, and joins through supported arguments.
When should you use get_list vs get_all?
The difference is important:
get_list
- Applies permission checks
- Enforces user access rights
- Suitable for UI, user queries, and client-facing APIs
get_all
- Does NOT apply permission rules
- Intended for backend operations
- Use only where security control is handled explicitly
Example rule:
Use get_list in controller code for UI logic and use get_all for backend internal operations where permissions are already validated.
How Frappe List API Works
The List API converts your filter and field parameters into a SQL SELECT query based on DocType metadata.
Flow:
- Receive parameters from Python
- Resolve DocType table name
- Inject conditions from filters, fields
- Apply permissions (only in get_list)
- Execute database query
- Return results as a list of dicts
Basic Usage Examples
Get all items (simple list)
frappe.get_list("Item")
Returns:
[
{"name": "ITEM-0001"},
{"name": "ITEM-0002"}
]
Select specific fields
frappe.get_list(
"Customer",
fields=["name", "customer_name", "customer_type"]
)
Apply filters
Filters can be single or nested.
frappe.get_list(
"Sales Order",
filters={
"customer": "John Doe"
},
fields=["name", "transaction_date"]
)
Using list of tuples (multi filter)
frappe.get_list(
"Item",
filters=[
["disabled", "=", 0],
["item_group", "=", "Raw Material"]
]
)
Limit and Offset (Pagination)
frappe.get_list(
"Purchase Order",
fields=["name"],
limit_start=20,
limit_page_length=10
)
Order By Clause
frappe.get_list(
"Task",
fields=["name", "status"],
order_by="creation desc"
)
Group By Clause
Useful for aggregation.
frappe.get_list(
"Timesheet",
fields=["status", "sum(billing_hours)"],
group_by="status"
)
Using get_all() (Advanced Use)
Fetch without permission check
frappe.get_all("Employee", fields=["name", "employee_name"])
Use this carefully.
get_all() is intended for backend logic where access rights are validated by your code.
List API Parameters (v15)
| Parameter | Type | Description |
| doctype | str | DocType name |
| filters | dict / list | Filter conditions |
| fields | list | Fields to return |
| limit_start | int | Start index |
| limit_page_length | int | Page size |
| order_by | str | Sort expression |
| group_by | str | Grouping field |
| distinct | bool | Unique results |
| as_list | bool | Return list values |
| ignore_permissions | bool | Force bypass permissions |
How to use Filters in List API
Filters accept:
- Dict format: {field: value}
- List format: [[field, operator, value]]
- Tuple format: (“field”, “=”, value)
- Multiple filters: list of lists
All formats translate to SQL WHERE conditions.
Example complex filter:
filters=[
["status", "=", "Active"],
["creation", ">", frappe.utils.add_days(today(), -30)]
]
Using Keywords Instead of SQL Operators
Supported operators include:
- =
- !=
- >
- <
- >=
- <=
- like
- in
- between
Example:
filters=[
["status", "in", ["Draft", "Submitted"]]
]
Return Format
Default return type
List of dict:
[
{"name": "SO-0001", "customer": "John Doe"},
{"name": "SO-0002", "customer": "Smith Corp"}
]
Return as list
frappe.get_list(
"Item",
fields=["name"],
as_list=True
)
returns:
[["ITEM-0001"], ["ITEM-0002"]]
Using List API from JavaScript (Client Side)
The same API is exposed via REST:
/api/resource/<doctype>?fields=["field1","field2"]&filters=[...]
Example:
frappe.call({
method: "frappe.client.get_list",
args: {
doctype: "Customer",
fields: ["name", "customer_name"]
}
})
Best Practices & Tips
- Prefer get_list() unless you fully control permissions
- Specify fields to reduce heavy payloads
- Use limit_page_length for pagination
- Use indexed columns in filters for speed
- Avoid pulling child table data via List API
- Use group_by with aggregation functions
Official References (Verified v15)
Docs: https://docs.frappe.io/framework/user/en/api/list
Source Code: https://github.com/frappe/frappe/tree/version-15
Relevant code paths:
frappe/database/database.py
frappe/model/db_query.py
frappe/__init__.py