Claude
Skills
Sign in
Back

frappe-api

Included with Lifetime
$97 forever

Frappe Python and JavaScript API reference including document operations, database queries, utilities, and REST API patterns. Use when working with frappe.get_doc, frappe.db, frappe.call, or any Frappe API methods.

Backend & APIs

What this skill does


# Frappe API Reference

Complete reference for Frappe's Python and JavaScript APIs for document operations, database queries, utilities, and server communication.

## When to Use This Skill

- Working with Document API (get_doc, new_doc, save)
- Database operations (frappe.db.*)
- Making API calls from client to server
- Using Frappe utilities (date, number formatting)
- Creating whitelisted API endpoints
- Working with REST API

## Python API

### Document Operations

#### Get Document
```python
# Get existing document
doc = frappe.get_doc("Customer", "CUST-001")

# Get document with filters
doc = frappe.get_doc("Customer", {"customer_name": "John"})

# Get last document
doc = frappe.get_last_doc("Customer", filters={"status": "Active"})

# Get cached document (read-only, faster)
doc = frappe.get_cached_doc("Customer", "CUST-001")

# Check if document exists
if frappe.db.exists("Customer", "CUST-001"):
    doc = frappe.get_doc("Customer", "CUST-001")
```

#### Create Document
```python
# Create new document
doc = frappe.new_doc("Customer")
doc.customer_name = "New Customer"
doc.customer_type = "Company"
doc.insert()

# Create with dict
doc = frappe.get_doc({
    "doctype": "Customer",
    "customer_name": "New Customer",
    "customer_type": "Company"
})
doc.insert()

# Create and insert in one step
doc = frappe.get_doc({
    "doctype": "Customer",
    "customer_name": "New Customer"
}).insert()

# Insert ignoring permissions
doc.insert(ignore_permissions=True)

# Insert ignoring mandatory fields
doc.insert(ignore_mandatory=True)
```

#### Update Document
```python
# Update and save
doc = frappe.get_doc("Customer", "CUST-001")
doc.customer_name = "Updated Name"
doc.save()

# Save ignoring permissions
doc.save(ignore_permissions=True)

# Update single value
frappe.db.set_value("Customer", "CUST-001", "customer_name", "New Name")

# Update multiple values
frappe.db.set_value("Customer", "CUST-001", {
    "customer_name": "New Name",
    "status": "Active"
})

# Bulk update
frappe.db.set_value("Customer", {"status": "Inactive"}, "status", "Active")
```

#### Delete Document
```python
# Delete document
frappe.delete_doc("Customer", "CUST-001")

# Delete ignoring permissions
frappe.delete_doc("Customer", "CUST-001", ignore_permissions=True)

# Delete with linked documents
frappe.delete_doc("Customer", "CUST-001", force=True)

# Delete from controller
doc.delete()
```

### Database API (frappe.db)

#### Select Queries
```python
# Get single value
value = frappe.db.get_value("Customer", "CUST-001", "customer_name")

# Get multiple fields
values = frappe.db.get_value("Customer", "CUST-001",
    ["customer_name", "status"], as_dict=True)

# Get with filters
value = frappe.db.get_value("Customer",
    {"customer_type": "Company"}, "customer_name")

# Get list of values
names = frappe.db.get_all("Customer",
    filters={"status": "Active"},
    fields=["name", "customer_name"],
    order_by="creation desc",
    limit=10
)

# Get list with pluck (single field as list)
names = frappe.db.get_all("Customer",
    filters={"status": "Active"},
    pluck="name"
)

# Complex filters
docs = frappe.db.get_all("Sales Invoice",
    filters={
        "status": ["in", ["Paid", "Unpaid"]],
        "grand_total": [">", 1000],
        "posting_date": ["between", ["2024-01-01", "2024-12-31"]],
        "customer": ["like", "%Corp%"]
    },
    fields=["name", "customer", "grand_total"]
)

# Filter operators
# =, !=, <, >, <=, >=
# in, not in
# like, not like
# between
# is, is not (for None)
# descendants of, ancestors of (for tree doctypes)

# Get count
count = frappe.db.count("Customer", {"status": "Active"})

# Check existence
exists = frappe.db.exists("Customer", "CUST-001")
exists = frappe.db.exists("Customer", {"customer_name": "John"})
```

#### Raw SQL
```python
# Execute SQL query
result = frappe.db.sql("""
    SELECT name, customer_name, grand_total
    FROM `tabSales Invoice`
    WHERE status = %s AND grand_total > %s
    ORDER BY creation DESC
    LIMIT 10
""", ("Paid", 1000), as_dict=True)

# Single value
total = frappe.db.sql("""
    SELECT SUM(grand_total) FROM `tabSales Invoice`
    WHERE status = 'Paid'
""")[0][0]

# With named parameters
result = frappe.db.sql("""
    SELECT * FROM `tabCustomer`
    WHERE name = %(name)s
""", {"name": "CUST-001"}, as_dict=True)
```

#### Insert/Update
```python
# Insert raw
frappe.db.sql("""
    INSERT INTO `tabCustomer` (name, customer_name)
    VALUES (%s, %s)
""", ("CUST-002", "New Customer"))

# Commit transaction
frappe.db.commit()

# Rollback
frappe.db.rollback()
```

### Whitelisted API

```python
# Create API endpoint
@frappe.whitelist()
def get_customer_details(customer):
    """Get customer details

    Args:
        customer: Customer ID

    Returns:
        dict: Customer details
    """
    doc = frappe.get_doc("Customer", customer)
    return {
        "name": doc.name,
        "customer_name": doc.customer_name,
        "outstanding_amount": get_outstanding(customer)
    }

# Allow guest access (no login required)
@frappe.whitelist(allow_guest=True)
def public_api():
    return {"status": "ok"}

# With specific methods
@frappe.whitelist(methods=["POST"])
def create_record(data):
    doc = frappe.get_doc(data)
    doc.insert()
    return doc.name
```

### Utilities

#### Date/Time
```python
from frappe.utils import (
    now, nowdate, nowtime, now_datetime,
    today, getdate, get_datetime,
    add_days, add_months, add_years,
    date_diff, time_diff, time_diff_in_seconds,
    get_first_day, get_last_day,
    formatdate, format_datetime
)

# Current date/time
current = nowdate()  # "2024-01-15"
current_dt = now_datetime()  # datetime object
timestamp = now()  # "2024-01-15 10:30:00"

# Date arithmetic
next_week = add_days(nowdate(), 7)
next_month = add_months(nowdate(), 1)
last_year = add_years(nowdate(), -1)

# Date difference
days = date_diff(end_date, start_date)
seconds = time_diff_in_seconds(end_time, start_time)

# First/last day of month
first = get_first_day(nowdate())
last = get_last_day(nowdate())

# Parse dates
date_obj = getdate("2024-01-15")
dt_obj = get_datetime("2024-01-15 10:30:00")

# Format dates
formatted = formatdate("2024-01-15", "dd-MM-yyyy")
```

#### Numbers
```python
from frappe.utils import (
    flt, cint, cstr,
    fmt_money, rounded,
    money_in_words
)

# Type conversion with defaults
num = flt(value)  # float, None -> 0.0
num = flt(value, 2)  # with precision
integer = cint(value)  # int, None -> 0
string = cstr(value)  # string, None -> ""

# Formatting
formatted = fmt_money(1234.56, currency="USD")  # "$1,234.56"
rounded_val = rounded(1234.567, 2)  # 1234.57
words = money_in_words(1234.56, "USD")  # "One Thousand..."
```

#### Strings
```python
from frappe.utils import (
    strip_html, strip_html_tags,
    escape_html, sanitize_html,
    scrub, unscrub
)

# HTML handling
plain = strip_html("<p>Hello</p>")  # "Hello"
safe = escape_html("<script>bad</script>")

# Field name conversion
field = scrub("My Field Name")  # "my_field_name"
label = unscrub("my_field_name")  # "My Field Name"
```

### Messaging & Notifications

```python
# Show message (appears as toast)
frappe.msgprint("Document saved successfully")

# With indicator
frappe.msgprint("Error occurred", indicator="red", title="Error")

# Throw error (stops execution)
frappe.throw("Invalid data provided")

# With exception type
from frappe.exceptions import ValidationError
frappe.throw("Validation failed", exc=ValidationError)

# Send email
frappe.sendmail(
    recipients=["[email protected]"],
    subject="Hello",
    message="Email body",
    template="email_template",
    args={"name": "John"}
)

# Create system notification
frappe.publish_realtime(
    "msgprint",
    {"message": "Task completed"},
    user="[email protected]"
)
```

### Background Jobs

```python
# Enqueue background job
frappe.enqueue(
    "myapp.tasks.heavy_task",
    queue="long",
    timeout=600,
    job_name="Heavy Task",
    customer="CUST-001"

Related in Backend & APIs