Skip to main content
Frappe Helpdesk uses the Frappe Framework’s authentication system. All API requests must be authenticated unless explicitly marked as guest-accessible.

Authentication Methods

Frappe supports multiple authentication methods:
  1. Session-based (Cookie) - For web applications
  2. Token-based (API Key/Secret) - For integrations and scripts
  3. OAuth 2.0 - For third-party applications
  4. Basic Auth - For simple scripts (not recommended for production)

Session-based Authentication

Used by the Frappe Helpdesk web interface. After login, a session cookie is set.

Login

curl -X POST https://your-site.frappe.cloud/api/method/login \
  -H "Content-Type: application/json" \
  -d '{
    "usr": "[email protected]",
    "pwd": "password"
  }' \
  -c cookies.txt

Using the Session

curl https://your-site.frappe.cloud/api/resource/HD Ticket \
  -b cookies.txt

Logout

curl -X POST https://your-site.frappe.cloud/api/method/logout \
  -b cookies.txt

Token-based Authentication (API Keys)

Recommended for integrations and automated scripts.

Generate API Key

1

Navigate to User Settings

Go to User > API Access in Frappe
2

Generate Keys

Click Generate Keys to create an API Key and Secret
3

Save Credentials

Store the API Key and Secret securely - the secret is only shown once

Using API Keys

Pass credentials as HTTP headers:
curl https://your-site.frappe.cloud/api/resource/HD Ticket/HD-00042 \
  -H "Authorization: token api_key:api_secret"
Never commit API keys to version control. Use environment variables.

Python Example

import requests
import os

API_KEY = os.environ.get("FRAPPE_API_KEY")
API_SECRET = os.environ.get("FRAPPE_API_SECRET")
BASE_URL = "https://your-site.frappe.cloud"

headers = {
    "Authorization": f"token {API_KEY}:{API_SECRET}"
}

response = requests.get(
    f"{BASE_URL}/api/resource/HD Ticket",
    headers=headers
)

tickets = response.json()["data"]

JavaScript Example

const API_KEY = process.env.FRAPPE_API_KEY;
const API_SECRET = process.env.FRAPPE_API_SECRET;
const BASE_URL = "https://your-site.frappe.cloud";

const headers = {
  "Authorization": `token ${API_KEY}:${API_SECRET}`,
  "Content-Type": "application/json"
};

fetch(`${BASE_URL}/api/resource/HD Ticket`, { headers })
  .then(res => res.json())
  .then(data => console.log(data.data));

OAuth 2.0

For third-party applications that need delegated access.

OAuth Flow

1

Register OAuth Client

Create an OAuth Client in Frappe (Social Login Key DocType)
2

Authorization Request

Direct users to:
https://your-site.frappe.cloud/api/method/frappe.integrations.oauth2.authorize
  ?client_id=<client_id>
  &redirect_uri=<redirect_uri>
  &response_type=code
3

Exchange Code for Token

After user approves, exchange the authorization code for an access token:
curl -X POST https://your-site.frappe.cloud/api/method/frappe.integrations.oauth2.get_token \
  -d "grant_type=authorization_code" \
  -d "code=<authorization_code>" \
  -d "client_id=<client_id>" \
  -d "redirect_uri=<redirect_uri>"
4

Use Access Token

Include the token in API requests:
curl https://your-site.frappe.cloud/api/resource/HD Ticket \
  -H "Authorization: Bearer <access_token>"

User Roles and Permissions

Frappe Helpdesk uses role-based access control:

Roles

RoleAccess Level
CustomerOwn tickets, knowledge base
AgentAll tickets, knowledge base, saved replies
Agent Manager+ Team management, assignment rules
System ManagerFull system access

Checking Current User

Get information about the authenticated user:
curl https://your-site.frappe.cloud/api/method/helpdesk.api.auth.get_user \
  -H "Authorization: token api_key:api_secret"
Response:
{
  "message": {
    "user_id": "[email protected]",
    "user_name": "John Doe",
    "is_agent": true,
    "is_admin": false,
    "is_manager": false,
    "has_desk_access": true,
    "user_teams": ["Support Team", "Technical Team"],
    "time_zone": "America/New_York",
    "language": "en"
  }
}
From helpdesk/api/auth.py:8 - Returns current user details including roles and team memberships.

Permission System

Frappe Helpdesk enforces permissions at multiple levels:

Endpoint-level Permissions

Some endpoints are restricted to agents only:
from helpdesk.utils import agent_only

@frappe.whitelist()
@agent_only
def sent_invites(emails: list[str]):
    # Only agents can send invitations
    pass

DocType-level Permissions

Permissions are enforced when accessing documents:
# helpdesk/helpdesk/doctype/hd_ticket/hd_ticket.py
def has_permission(doc, ptype, user):
    """Custom permission logic for tickets"""
    if user_type == "System User":
        return True
    
    # Customers can only see their own tickets
    if doc.raised_by == user:
        return True
    
    return False

Guest Access

Some endpoints allow guest access (no authentication):
@frappe.whitelist(allow_guest=True)
def get_article(name: str):
    # Public knowledge base articles
    article = frappe.get_doc("HD Article", name)
    if article.status != "Published":
        frappe.throw("Access denied", frappe.PermissionError)
    return article

Endpoint Blocking

Frappe Helpdesk implements custom endpoint blocking for security (helpdesk/auth.py:69):
def authenticate():
    """Block certain Frappe endpoints for non-System Users"""
    user_type = frappe.db.get_value("User", frappe.session.user, "user_type")
    
    if user_type == "System User":
        return  # Full access
    
    # Allow helpdesk and telephony endpoints
    if path.startswith("/helpdesk") or path.startswith("/api/method/helpdesk."):
        return
    
    # Block other endpoints unless in allowlist
    if path not in ALLOWED_PATHS:
        frappe.throw(f"Access not allowed for this URL: {path}", 
                     frappe.PermissionError)
This blocking can be enabled via block_endpoints in site configuration.

Security Best Practices

1

Use HTTPS

Always use HTTPS in production to encrypt credentials in transit
2

Rotate API Keys

Regularly rotate API keys, especially after team member departures
3

Principle of Least Privilege

Grant users the minimum role necessary for their work
4

Monitor API Usage

Track API calls and watch for unusual patterns
5

Secure Storage

Never store credentials in code - use environment variables or secret management

Troubleshooting

401 Unauthorized

  • Verify API key and secret are correct
  • Check that the user account is active
  • Ensure Authorization header is properly formatted

403 Forbidden

  • User lacks required role for the operation
  • Check DocType permissions in Role Permission Manager
  • Verify custom permission logic in DocType code

429 Rate Limited

  • Slow down request rate
  • Check endpoint-specific rate limits
  • Contact admin to adjust limits if needed

Next Steps

Ticket API

Start creating and managing tickets

Agent API

Manage agent accounts and invitations

Build docs developers (and LLMs) love