Back to Nodes

ERPNext HRMS

Last updated May 14, 2026

n8n community nodes for ERPNext/Frappe HRMS v15-v16.

35 Weekly Downloads
512 Monthly Downloads

Included Nodes

ERPNext HRMS

Description

n8n-nodes-erpnext-hrms

Community n8n node package for ERPNext/Frappe HRMS v15-v16.

This is the first package in the n8n2erpnext ecosystem. It focuses on HRMS doctypes and keeps a generic Frappe escape hatch for custom doctypes and whitelisted methods.

Who This Is For

This package is built for SME and mid-market teams that run ERPNext HRMS and want a controlled way to connect HR data with n8n workflows.

Typical users:

  • IT ERP administrators who maintain ERPNext/Frappe.
  • HRIS or operations teams that need employee, attendance, leave, payroll, or shift workflows.
  • Integration teams that need repeatable n8n automations without writing custom Frappe client code for every workflow.
  • The node is intentionally conservative: it exposes standard HRMS document operations, supports Frappe API v1 and v2, and allows controlled fallback access to custom DocTypes and whitelisted Frappe methods.

    Architecture At A Glance

    Read workflow from left to right:

    ERPNext / Frappe HRMS  <---- API token ---->  n8n ERPNext HRMS node  <---- webhook/API ---->  Client / App / Report
    

    Common read pattern:

    Client
      -> n8n Webhook
      -> ERPNext HRMS node
      -> Frappe REST API
      -> ERPNext HRMS DocType
      -> filtered JSON response
    

    Common ERPNext event pattern:

    ERPNext Webhook
      -> n8n Webhook Trigger
      -> validation / mapping / approval logic
      -> ERPNext HRMS node or downstream systems
    

    Recommended production network pattern:

    Public Client
      -> HTTPS reverse proxy / VPN / allowlist
      -> n8n
      -> private network or internal VPS address
      -> ERPNext / Frappe site
    

    Supported Resources

  • Employee
  • Attendance
  • Employee Checkin
  • Leave Application
  • Leave Allocation
  • Expense Claim
  • Salary Slip
  • Shift Assignment
  • Holiday List
  • Custom DocType
  • Frappe Method
  • Node Identity

    All n8n2erpnext module nodes use the same ERPNext-style logo shape. Each module changes only the main background color.

    | Module | Color | Hex | Reason |
    | — | — | — | — |
    | Core | ERPNext blue | #2490EF | Foundation package, closest to the ERPNext brand color. |
    | HRMS | People green | #2E7D5F | Human operations, employees, attendance, leave, payroll. |
    | Accounting | Finance orange-red | #D94A2B | Ledger, journals, invoices, financial control. |
    | Buying | Procurement amber | #C47F00 | Purchase flow, suppliers, RFQs, purchase orders, spend. |
    | Selling | Commerce teal | #00A6A6 | Customer-facing pipeline, quotations, sales orders, revenue. |
    | Stock | Frappe black | #171717 | Warehouses, items, inventory movement; aligned with Frappe black. |

    When building another module, copy the HRMS/Accounting SVG structure and change only the main background fill to that module color.

    Operations

    For HRMS doctypes:

  • Create
  • Get
  • Get Many
  • Update
  • Delete
  • Submit
  • Cancel
  • For Frappe methods:

  • Run Method
  • API Versions

    The node supports both ERPNext/Frappe document API styles:

  • v1: /api/resource/:doctype
  • v2: /api/v2/document/:doctype
  • Use v1 for broad compatibility. Use v2 when your ERPNext/Frappe v16 environment is ready for the newer document API behavior.

    Reference:

  • Frappe REST API
  • Credentials

    Create an API key and secret in ERPNext/Frappe, then configure:

  • Site URL: https://erp.example.com
  • Site Host Header, optional: erp.example.com
  • API Key
  • API Secret
  • Ignore SSL Issues, optional
  • The node authenticates with:

    Authorization: token apikey:apisecret
    

    Internal URL With Public Host Header

    When n8n and ERPNext run on the same VPS, you can point n8n at the internal ERPNext address and still send the public ERPNext host header:

  • Site URL: http://erpnext.internal:8001
  • Site Host Header: erp.example.com
  • This avoids public reverse-proxy authentication while still letting ERPNext receive the expected site host.

    For production, create a dedicated ERPNext integration user instead of using a daily admin account. Give that user only the roles required for the workflows it runs.

    Official Frappe references:

  • Frappe REST API authentication
  • tosetuptokenbased_auth”>Generate Frappe API key and secret
  • Examples

    Get active employees:

    {
      "resource": "employee",
      "operation": "getMany",
      "fields": "name,employee_name,status,company,department",
      "filtersJson": "[["status","=","Active"]]",
      "returnAll": true
    }
    

    Create an employee checkin:

    {
      "resource": "employeeCheckin",
      "operation": "create",
      "dataJson": {
        "employee": "HR-EMP-0001",
        "time": "2026-05-13 08:30:00",
        "log_type": "IN"
      }
    }
    

    Run a whitelisted Frappe method:

    {
      "resource": "frappeMethod",
      "operation": "runMethod",
      "methodName": "frappe.client.get_value",
      "argumentsJson": {
        "doctype": "Employee",
        "filters": { "user_id": "person@example.com" },
        "fieldname": ["name", "employee_name"]
      }
    }
    

    Webhook From n8n to ERPNext HRMS

    Use this pattern when you want an HTTP GET endpoint in n8n that returns HRMS data from ERPNext.

    Client / Browser / BI Tool
      -> GET n8n webhook URL
      -> ERPNext HRMS node
      -> GET /api/resource or /api/v2/document
      -> JSON response
    

    1. Configure the ERPNext Credential

    In n8n, create or edit an ERPNext API credential:

  • Site URL: http://erpnext.internal:8001
  • Site Host Header: erp.example.com
  • API Key: your ERPNext API key
  • API Secret: your ERPNext API secret
  • Ignore SSL Issues: false
  • If your ERPNext site is directly reachable without an internal proxy, use the public URL instead:

    https://erp.example.com
    

    2. Create the Workflow

    Create a workflow with these nodes:

    GET Webhook -> ERPNext HRMS
    

    Webhook node:

  • HTTP Method: GET
  • Path: erpnext-hrms-get-employees
  • Respond: When Last Node Finishes
  • Response Data: All Entries
  • ERPNext HRMS node:

  • Credential: your ERPNext API credential
  • Resource: Employee
  • Operation: Get Many
  • API Version: v1
  • Fields: name,employee_name,status,company,department
  • Filters JSON: [["status","=","Active"]]
  • Return All: false
  • Limit: 10
  • Order By: modified desc
  • For Frappe/ERPNext v16 API v2, use the same workflow and set:

    API Version: v2
    

    The node will call the v2 document endpoint:

    /api/v2/document/Employee
    

    Example v2 test endpoint:

    curl -i http://127.0.0.1:5678/webhook/erpnext-hrms-v2-get-employees
    

    3. Activate and Test

    Activate the workflow, then call:

    curl -i https://n8n.example.com/webhook/erpnext-hrms-get-employees
    

    On the local VPS, you can test without going through the public proxy:

    curl -i http://127.0.0.1:5678/webhook/erpnext-hrms-get-employees
    

    Example response:

    [
      {
        "name": "HR-EMP-00001",
        "employee_name": "Jane Doe",
        "status": "Active",
        "company": "Example Company",
        "department": "Human Resources - EX"
      }
    ]
    

    If the response is [], the workflow is working but ERPNext has no matching active Employee records.

    Webhook From ERPNext v16 to n8n

    Use this pattern when ERPNext should call n8n automatically after an HRMS document is created or updated. For example, ERPNext can call a n8n workflow whenever an Employee record is saved.

    ERPNext Doc Event
      -> Frappe Webhook
      -> POST n8n webhook URL
      -> n8n workflow
      -> validation, notification, sync, approval, or downstream automation
    

    1. Create the n8n Webhook Receiver

    Create a workflow in n8n with a Webhook trigger:

    Webhook -> your processing nodes
    

    Webhook node:

  • HTTP Method: POST
  • Path: erpnext-employee-event
  • Authentication: None for a private/internal test, or Header Auth for production
  • Respond: Immediately or When Last Node Finishes
  • The production webhook URL will look like:

    https://n8n.example.com/webhook/erpnext-employee-event
    

    On this VPS, if ERPNext and n8n are on the same host/network, you can also use the internal n8n URL from ERPNext:

    http://n8n.internal:5678/webhook/erpnext-employee-event
    

    Use the public URL if ERPNext cannot reach the internal n8n address.

    2. Add the Webhook in ERPNext/Frappe v16

    In ERPNext/Frappe Desk:

    1. Open the global search bar.
    2. Search for Webhook.
    3. Open Webhook from the Integrations area.
    4. Click New.

    Configure the Webhook:

  • Enabled: checked
  • Webhook Doctype: Employee
  • Doc Event: onupdate for every save, or afterinsert for newly created employees only
  • Request URL: your n8n production webhook URL
  • Request Method: POST
  • Request Structure: JSON
  • Webhook JSON: use the example below
  • Example JSON body:

    {
      "event": "employee_updated",
      "doctype": "{{ doc.doctype }}",
      "name": "{{ doc.name }}",
      "employeename": "{{ doc.employeename }}",
      "status": "{{ doc.status }}",
      "company": "{{ doc.company }}",
      "department": "{{ doc.department }}",
      "modified": "{{ doc.modified }}"
    }
    

    For a newly created Employee only, set:

    Doc Event: after_insert
    

    For every save/update, set:

    Doc Event: on_update
    

    3. Add Headers

    For a simple JSON webhook, add this header:

    Content-Type: application/json
    

    For production, add a shared secret header and validate it in n8n:

    X-ERPNext-Webhook-Secret: your-long-random-secret
    

    If you use Frappe’s Webhook Secret field, Frappe adds an X-Frappe-Webhook-Signature header generated from the payload and secret. You can verify this signature in n8n with a Code node if needed.

    Official Frappe reference:

  • Frappe Webhooks
  • 4. Test the ERPNext Webhook

    1. Activate the n8n workflow.
    2. In ERPNext, create or edit an Employee.
    3. Save the Employee.
    4. Open n8n executions and check the latest webhook execution.

    The n8n Webhook node should receive a body similar to:

    {
      "event": "employee_updated",
      "doctype": "Employee",
      "name": "HR-EMP-00001",
      "employee_name": "Jane Doe",
      "status": "Active",
      "company": "Example Company",
      "department": "Human Resources - EX",
      "modified": "2026-05-13 13:07:37.000000"
    }
    

    5. Common Issues

  • If ERPNext cannot reach the n8n URL, test from the ERPNext/LXD container with curl.
  • If the n8n public URL is protected by NetBird or another auth proxy, either allow ERPNext through that proxy or use an internal URL.
  • If n8n logs ERRERLUNEXPECTEDXFORWARDED_FOR, configure n8n trust proxy for your reverse proxy setup.
  • If the workflow does not run, make sure the n8n workflow is active and you are using the production /webhook/ URL, not the test /webhook-test/ URL.
  • Reverse Proxy Notes

    If https://erp.example.com is protected by NetBird or another reverse-proxy auth layer, n8n server-side requests may be blocked before they reach ERPNext. In that case:

  • Use the internal ERPNext URL in Site URL.
  • Set Site Host Header to the public ERPNext host.
  • Keep the API key and secret from the ERPNext user that has permission to read/write the target DocType.
  • Verified HRMS Audit Runs

    These audit runs were executed against the ERPNext LXD test instance for erp.thaiduy.digital.

    Security Audit And GET Retest

    The enterprise-style security audit covered repository leakage, package contents, dependency advisories, GET behavior, and light stress testing.

    Repository secret scan:

    No real API key, API secret, private key, bearer token, or credential material was found in source files.
    Matches were documentation placeholders, credential field names, or operational notes.
    

    Package contents check:

    npm pack --dry-run
    Tarball contains dist/**, README.md, LICENSE, and package.json.
    No SESSIONLOG.md, workflow JSON, .env, DB dump, credential export, source TypeScript, or nodemodules.
    

    Dependency audit:

    npm audit --omit=dev
    form-data advisory inherited through n8n-workflow
    Do not run npm audit fix --force blindly because it would upgrade n8n-workflow to a breaking version.
    

    GET single security finding:

    operation: get returned the full Employee document for HR-EMP-00001.
    This is expected Frappe behavior, but it can expose HR/PII fields if a single-document GET webhook is public.
    

    Mitigation:

    Temporary get-single workflow was deactivated after testing.
    Active public-ish demo endpoints remain limited to getMany with explicit fields:
    name, employee_name, status, company, department
    

    Bug fixed during audit:

    API v2 named document GET previously used a trailing slash:
    /api/v2/document/Employee/HR-EMP-00001/

    Frappe redirected that URL and n8n eventually timed out. The v2 named document endpoint was fixed to: /api/v2/document/Employee/HR-EMP-00001

    Retest matrix:

    GET /webhook/erpnext-hrms-get-employees                     HTTP 200
    GET /webhook/erpnext-hrms-v2-get-employees                  HTTP 200
    GET /webhook/erpnext-hrms-get-employee?name=HR-EMP-00001    HTTP 200 during test, then deactivated
    GET /webhook/erpnext-hrms-v2-get-employee?name=HR-EMP-00001 HTTP 200 during test, then deactivated
    

    Stress test:

    50 requests per endpoint
    4 endpoints
    200 total requests
    concurrency: 10

    200 / 200 requests returned HTTP 200 0 errors total duration: 6264 ms

    Latency summary:

    getMany v1:      min 263 ms | p50 342 ms | p95 389 ms | max 400 ms
    getMany v2:      min 201 ms | p50 295 ms | p95 455 ms | max 472 ms
    get single v1:   min 232 ms | p50 288 ms | p95 308 ms | max 313 ms
    get single v2:   min 215 ms | p50 280 ms | p95 360 ms | max 367 ms
    

    Final state after this audit:

    cY31OLkUamjHrm01  ERPNext HRMS GET Employees Webhook       active true
    cY31OLkUamjHrm02  ERPNext HRMS V2 GET Employees Webhook    active true
    cY31OLkUamjHrm03  ERPNext HRMS GET Employee By ID Webhooks active false
    

    Final GET Audit Across Supported Resources

    Final audit workflow artifact:

    n8n-webhook-erpnext-hrms-final-get-audit.workflow.json
    

    Temporary workflow:

    Workflow name: ERPNext HRMS Final GET Audit Webhooks
    Workflow id: cY31OLkUamjHrm04
    Status after audit: active false
    

    Pre-test ERPNext data count:

    Employee           1
    Attendance         1
    Employee Checkin   1
    Leave Application  0
    Leave Allocation   0
    Expense Claim      0
    Salary Slip        0
    Shift Assignment   0
    Holiday List       1
    User               4
    

    Audit result:

    Employee                  HTTP 200  count 1
    Attendance                HTTP 200  count 1
    Employee Checkin          HTTP 200  count 1
    Leave Application         HTTP 200  count 0
    Leave Allocation          HTTP 200  count 0
    Expense Claim             HTTP 200  count 0
    Salary Slip               HTTP 200  count 0
    Shift Assignment          HTTP 200  count 0
    Holiday List              HTTP 200  count 1
    Custom DocType Company    HTTP 200  count 1
    Frappe Method get_count   HTTP 200  result 1
    

    Detailed previews:

    [
      {
        "name": "Employee",
        "status": 200,
        "count": 1,
        "preview": {
          "name": "HR-EMP-00001",
          "employee_name": "Tèo Văn Nguyễn",
          "status": "Active",
          "company": "Thái Duy Digital",
          "department": "Human Resources - TDD"
        }
      },
      {
        "name": "Attendance",
        "status": 200,
        "count": 1,
        "preview": {
          "name": "HR-ATT-2026-00001",
          "employee": "HR-EMP-00001",
          "status": "Half Day",
          "attendance_date": "2026-05-15",
          "company": "Thái Duy Digital"
        }
      },
      {
        "name": "Employee Checkin",
        "status": 200,
        "count": 1,
        "preview": {
          "name": "EMP-CKIN-05-2026-000001",
          "employee": "HR-EMP-00001",
          "time": "2026-05-13 16:21:13",
          "log_type": "IN"
        }
      },
      {
        "name": "Holiday List",
        "status": 200,
        "count": 1,
        "preview": {
          "name": "Default Holiday List",
          "holidaylistname": "Default Holiday List",
          "from_date": "2026-05-13",
          "to_date": "2026-12-31"
        }
      },
      {
        "name": "Custom DocType Company",
        "status": 200,
        "count": 1,
        "preview": {
          "name": "Thái Duy Digital"
        }
      },
      {
        "name": "Frappe Method Employee Count",
        "status": 200,
        "preview": 1
      }
    ]
    

    Resources with no records returned HTTP 200 and empty arrays:

    Leave Application
    Leave Allocation
    Expense Claim
    Salary Slip
    Shift Assignment
    

    Final state after the final GET audit:

    cY31OLkUamjHrm01  ERPNext HRMS GET Employees Webhook          active true
    cY31OLkUamjHrm02  ERPNext HRMS V2 GET Employees Webhook       active true
    cY31OLkUamjHrm03  ERPNext HRMS GET Employee By ID Webhooks    active false
    cY31OLkUamjHrm04  ERPNext HRMS Final GET Audit Webhooks       active false
    

    Final verification after deactivating the audit workflow:

    GET /webhook/erpnext-hrms-get-employees     HTTP 200
    GET /webhook/erpnext-hrms-v2-get-employees  HTTP 200
    

    Public evaluation status:

  • All supported HRMS resources were exercised through the n8n node with getMany.
  • Custom DocType was exercised with Company.
  • Frappe Method was exercised with frappe.client.get_count.
  • Empty DocTypes returned safely as [].
  • Temporary audit workflows were deactivated after testing.
  • Active public demo endpoints are limited to selected Employee fields to reduce PII exposure.
  • Security Baseline

    HRMS data usually includes personal, attendance, leave, payroll, and identity-related records. Treat every workflow as sensitive by default.

    Recommended baseline:

  • Use a dedicated ERPNext API user for n8n integrations.
  • Avoid using a full Administrator API key in production.
  • Scope ERPNext roles to the exact DocTypes and actions needed by the workflow.
  • Prefer Get Many with explicit Fields over Get when exposing webhook responses, because Get can return the full document including sensitive fields.
  • Keep n8n webhook URLs private unless they are meant to be public.
  • Add authentication to public n8n webhooks, such as header auth, reverse proxy auth, VPN, IP allowlisting, or a shared secret.
  • Do not log API keys, API secrets, employee identity fields, salary data, or raw webhook payloads into external systems unless there is a clear retention policy.
  • Use HTTPS for public traffic.
  • If n8n and ERPNext are on the same VPS or private network, prefer the internal ERPNext URL plus Site Host Header.
  • Rotate API keys after testing, after staff changes, and after any suspected exposure.
  • Review n8n execution data retention. Disable or reduce saved execution data for workflows that process payroll, salary slips, or personally identifiable information.
  • Security Notice

    Security notice: form-data vulnerability is acknowledged but mitigated by infrastructure/scoped API access.

    The current dependency tree can report a transitive form-data advisory through n8n-workflow. In this package’s tested deployment model, risk is reduced by:

  • Internal network access between n8n and ERPNext.
  • Reverse proxy or VPN controls for public endpoints.
  • Dedicated ERPNext API credentials with scoped roles.
  • Explicit field selection for public webhook responses.
  • Avoiding public exposure of generic Custom DocType and Frappe Method workflows.
  • Do not treat this mitigation as a permanent substitute for dependency maintenance. Re-run npm audit --omit=dev before publishing a new package version and upgrade compatible n8n dependencies when the upstream dependency chain allows it without breaking n8n node compatibility.

    Deployment Checklist For SME And Mid-Market Teams

    Before going live:

  • Confirm ERPNext/Frappe version and choose API v1 or v2.
  • Create a dedicated ERPNext integration user.
  • Assign only the required HRMS roles and permissions.
  • Configure n8n credentials with the ERPNext internal URL when available.
  • Set Site Host Header if ERPNext is served by a named Frappe site.
  • Build and install the packed node package into the n8n custom nodes environment.
  • Test Get Many for each required resource with limited fields.
  • Test write operations in a staging site before production.
  • Review n8n execution data retention and error logging.
  • Protect public webhooks with authentication or network controls.
  • Keep workflow JSON exports out of public repositories if they contain real URLs, headers, filters, or business logic.
  • Suggested production approach:

  • Start with read-only HRMS reporting workflows.
  • Add write workflows only after role permissions and audit logs are reviewed.
  • Keep Custom DocType and Frappe Method workflows limited to trusted internal operators.
  • Document each production workflow owner, purpose, data fields, and rollback path.
  • Troubleshooting

    Common checks:

  • 401 or 403: verify API key, API secret, user roles, and DocType permissions in ERPNext.
  • TLS EPROTO or tlsv1 alert internal error: use the internal ERPNext HTTP URL from n8n when the public domain is protected by a reverse proxy or VPN layer.
  • Empty [] response: the node is working, but filters may not match any records.
  • Frappe site not found or wrong site: set Site Host Header to the public ERPNext site name.
  • n8n webhook does not run: activate the workflow and use the production /webhook/ URL, not /webhook-test/.
  • Unexpected sensitive fields in output: switch from Get to Get Many and set an explicit Fields list.
  • Development

    npm install
    npm run build
    

    For local n8n testing, link this package into your n8n custom nodes directory or install it from a packed tarball.

    Useful n8n references:

  • n8n community nodes installation
  • Install community nodes from the n8n GUI
  • Manual community node installation
  • Using community nodes
  • Creating n8n nodes
  • Using the n8n-node tool
  • n8n node linter
  • Submit community nodes
  • Scope And Roadmap

    This package is intentionally HRMS-focused. Other ERPNext modules should live in separate packages so each module can evolve independently:

  • n8n-nodes-erpnext-accounting
  • n8n-nodes-erpnext-selling
  • n8n-nodes-erpnext-buying
  • n8n-nodes-erpnext-stock
  • Recommended next hardening tasks before wider public adoption:

  • Add automated unit tests for request construction and API v1/v2 endpoint behavior.
  • Add credential redaction checks around error messages.
  • Add sample workflows that use limited fields by default.
  • Add a production security checklist to release notes for every package version.
  • Official References

    Frappe / ERPNext:

  • ERPNext introduction
  • Frappe HR overview
  • Employee
  • Attendance
  • Leave Application
  • Frappe REST API
  • tosetuptokenbased_auth”>Generate Frappe API key and secret
  • Frappe Webhooks
  • n8n:

  • n8n integrations and nodes overview
  • n8n community nodes installation
  • Manual community node installation
  • Using community nodes
  • Creating n8n nodes
  • Submit community nodes

License

MIT

Acknowledgement

Prepared and reviewed with care by Codex for the n8n2erpnext ERPNext HRMS integration work.

Signed: Codex, May 13, 2026.