```json
{
    "title": "Frappe REST API Basics: Authentication, Endpoints and Common Use Cases",
    "url": "https://aavatto.com/blog/frappe-rest-api-basics/",
    "datePublished": "2026-10-26",
    "dateModified": "2026-10-26",
    "language": "en-US",
    "description": "Frappe REST API basics for dev leads: how authentication works, the core endpoints, and the integrations the API is actually good for.",
    "author": "Aavatto",
    "publisher": "Aavatto - Frappe & ERPNext Experts | Custom Development, Implementation & Support"
}
```

# Frappe REST API Basics: Authentication, Endpoints and Common Use Cases

If you are evaluating Frappe as the base for a custom business application, one early question is how other systems will talk to it. The short answer: Frappe exposes every DocType over a REST API automatically, so you get working endpoints before you write any API code.

**The short version:** Frappe's REST API has three pieces. You authenticate with an API key and secret (token auth), a session cookie, or OAuth 2. You read and write documents through `/api/resource/{DocType}`. And you call your own server-side functions, marked as whitelisted, through `/api/method/{path}`. Every call runs with the permissions of the authenticated user.

That last sentence matters more than it looks, and we will come back to it. First, the mechanics.

## What "REST API" means in Frappe

Frappe is a framework, not just an ERP. When you define a DocType (a Frappe data model with its form, validations and permissions), the framework generates database tables, a UI, and API endpoints for it. You do not write controllers or routes for basic create, read, update and delete.

For a CTO, the practical consequence is that your API surface and your data model grow together. Add a field to a DocType, and it is available over the API once the schema migrates. For a non-technical founder, this means integrations with a website, a mobile app or a third-party tool do not need to wait for a separate "API project".

## Frappe API authentication: three ways in

Frappe API authentication comes down to three options. Which one you pick depends on who is calling.

### Token authentication(API key and secret)

This is the usual choice for server-to-server integrations. In the User record, an administrator generates an API key and API secret. The secret is shown once, so store it in your integration's secrets manager immediately.
The client then sends a header on each request:

```


					Authorization: token :
```

Because the key belongs to a specific user, you can create a dedicated integration user with only the roles it needs. That is better than reusing an administrator's keys, and it keeps your audit trail readable.

### Session authentication

For browser-based or script-based flows, you post a username and password to 

`/api/method/login`

, and Frappe returns a session cookie. Later requests carry that cookie. State-changing requests made from a browser session also need a CSRF token. Token auth skips this, which is one reason it suits backend integrations better.

### OAuth 2

Frappe can act as an OAuth 2 provider, with clients registered in the system. Use this when a third-party application needs to act on behalf of a user without ever holding that user's credentials. It takes more setup than token auth, so it is rarely the first choice for an internal integration.

## Frappe API endpoints you will use most

The core Frappe API endpoints are few. Most integrations use these:

EndpointMethodWhat it does`/api/resource/{DocType}`GETList documents, with filtering and field selection`/api/resource/{DocType}`POSTCreate a document`/api/resource/{DocType}/{name}`GETRead one document, including its child table rows`/api/resource/{DocType}/{name}`PUTUpdate fields on a document`/api/resource/{DocType}/{name}`DELETEDelete a document`/api/method/{dotted.path}`GET / POSTCall a whitelisted server-side function

Resource calls return their payload under a 

`data`

 key. Method calls return theirs under 

`message`

. It is a small difference that trips up many first integrations.

### Listing and filtering

List calls accept query parameters such as 

`fields`

, 

`filters`

, 

`order_by`

, 

`limit_start`

 and 

`limit_page_length`

. Filters are passed as a JSON-encoded list. A request for open sales orders for one customer, with only three fields returned, looks like this:

```


					GET /api/resource/Sales Order
  ?fields=["name","customer","grand_total"]
  &filters=[["customer","=","Acme Traders"],["status","=","To Deliver and Bill"]]
  &limit_page_length=50
```

List calls are paginated by default, so integrations that sync large tables need to loop using limit_start. Selecting only the fields you need keeps responses small.

### Creating and updating documents

A POST to `/api/resource/{DocType}` with a JSON body creates a document. Frappe runs the same validations it runs when a user saves the form: mandatory fields, link checks, naming rules and any custom validation in the DocType controller. If a validation fails, the API returns an error with the message the form would have shown. Check the response body rather than relying on the status code alone, since validation failures do not always arrive as the status code a REST purist would expect.

Child tables are sent as nested arrays inside the parent document. An invoice with line items is one request, not many.

### Calling your own methods

This is where a custom Frappe app starts to differ from plain CRUD. You write a Python function and decorate it with `@frappe.whitelist()`. Frappe then exposes it at `/api/method/your_app.module.function_name`.

Use methods when the operation is a business action rather than a data edit: "approve this requisition", "reserve stock for this order", "return the delivery slots for this pincode". Wrapping that logic in one method keeps the rules on the server, where you can test them, instead of scattered across client applications.

### Permissions: your API is only as safe as your roles

Every REST call runs as the authenticated user, and Frappe applies that user's role permissions and any user permissions (record-level restrictions) before it returns or changes data. There is no separate API permission layer to configure.

This is good news if you have already modelled roles properly. It also means weak role design shows up in your API first. A few habits help:

Create one integration user per external system, not one shared key.

Give each user only the roles the integration needs.

Mark methods as whitelisted deliberately, and check permissions inside them where the action is sensitive. Whitelisting makes a function callable; it does not decide who should call it.

Rotate keys when staff or vendors change.

## Common use cases

These are the situations where teams usually reach for the Frappe REST API:

**Website or app front end.** A customer portal, mobile app or storefront reads items and prices and posts orders into Frappe.

**Third-party system sync.** Pushing shipment status from a courier, payments from a gateway, or attendance from a device into the matching DocTypes.

**Reporting and BI.** Pulling filtered lists into a data tool on a schedule.

**Workflow triggers.** An external system calls a whitelisted method that moves a document through its workflow.

**Migration scripts.** Bulk creation of masters and opening balances, which then pass the same validation as manual entry.

For event-driven needs in the other direction, such as telling another system when a document changes, Frappe's webhooks are usually a better fit than polling the API.

## Where this gets harder than the basics

The REST API handles most integrations without custom code, but a few things deserve planning:

Version differences

Newer Frappe releases add API versions and options beyond what is covered here, so check the documentation for the version you run.

Bulk operations

One request per document is simple but slow for large loads. Batch sensibly and test with realistic volumes.

Idempotency

Retried POST calls can create duplicates unless your integration checks first or you design the method to be safe to repeat.

Error handling

Treat validation messages as part of the contract with your integration, and log them.

If your project goes beyond reading and writing documents, such as custom whitelisted methods, background jobs or a mobile app on top of Frappe, that is the territory of [custom Frappe apps](/services/custom-frappe-apps/). Teams weighing the framework itself can read more about [Frappe framework development](/services/frappe-framework-development/) before committing to an approach.

*If you are mapping out an integration and want a second pair of eyes on the endpoint design, a short conversation with an engineer usually saves rework later.*

## Frequently Asked Questions

[Does Frappe have a REST API out of the box?](#collapse-2611)

Yes. Every DocType gets resource endpoints under `/api/resource/`, and any function you whitelist is callable under `/api/method/`. No extra module needs installing.

[How do I authenticate with the Frappe API?](#collapse-2612)

For backend integrations, generate an API key and secret on a user and send `Authorization: token key:secret`. Use session login for browser flows and OAuth 2 when third-party apps act for users.

[Can the Frappe API call custom business logic?](#collapse-2613)

Yes. Write a Python function, decorate it with `@frappe.whitelist()`, and call it at `/api/method/` followed by its dotted path. Add permission checks inside for sensitive actions.

[Does the API respect user permissions?](#collapse-2614)

Yes. Calls run as the authenticated user, so role permissions and user permissions apply to every read and write.

[Is there a GraphQL option?](#collapse-2615)

The built-in API is REST. If you need a different shape, you can write whitelisted methods that return exactly the structure your client wants.

## Next step

If you are weighing Frappe for a custom application and want to talk through how the API fits your integrations, [talk to our Frappe development team](/hire-frappe-developers/). We can review your data model and integration list and tell you plainly where the framework helps and where extra engineering is needed.
