n8n-nodes-brightpearl
v0.19.0
Published
n8n community node for the Brightpearl API (orders, products, price lists)
Downloads
2,423
Readme
n8n-nodes-brightpearl
An n8n community node for the Brightpearl REST API. Covers sales orders, products, price lists, and order custom fields. Works as a standard n8n node and is usableAsTool for AI agents. (AI agents are currently untested with it.)
Disclaimer
Most of the "code" portion of modifying the template into this was written with Claude in a day. Sort of a mixture of proof of concept and making something that works for some quick features I needed. I feel it's important to note that while I at best provided direction, it did the work of modifying things to ensure it would work with n8n properly. (I had done an attempt before, but some docs were out of date, so I fed what I had into Claude and let it do the rest.)
Claude did attempt to incorporate the rate limit handling per the API docs, but this is an untested option that I am not sure how n8n will operate with as of yet.
Installation
In your n8n instance:
Settings → Community Nodes → Install and enter:
n8n-nodes-brightpearlOr via CLI on a self-hosted instance:
npm install n8n-nodes-brightpearlSee Cloud Note for more information when it comes to n8n cloud, but TL;DR, I'm using self hosted, so it has a few options that may not work on n8n Cloud.
Authentication
The node supports both Brightpearl auth modes — pick one via the Authentication field at the top of the node:
Private App (three-header auth)
Use this for internal integrations on your own account. Headers sent:
brightpearl-account-tokenbrightpearl-app-refbrightpearl-staff-token
| Credential field | Where to find it |
|---|---|
| Account Code | The subdomain part of your Brightpearl URL |
| Datacenter Hostname | Match your account URL (e.g. use1.brightpearlconnect.com) |
| App Reference | Set when you create the private app under Apps → Private Apps |
| Account Token | Issued when the private app is created |
| Staff Token | The staff token for the user the app runs as |
OAuth2 (public app)
For published apps that need user-authorized access. Standard OAuth2 authorization-code flow against Brightpearl's endpoints, plus app-ref/dev-ref headers alongside the Bearer token.
Note: If you plan to use the oauth2 when using it with a generic http request node, you'll need to add two headers manually:
brightpearl-app-refbrightpearl-dev-ref
| Credential field | Where to find it | |---|---| | Account Code | The target account's code (used to build the per-account authorize/token URLs) | | Datacenter Hostname | Datacenter for API calls | | App Reference | Your registered app reference | | Developer Reference | Your developer reference (required for public apps) | | Client ID / Client Secret | From your Brightpearl app registration |
n8n handles the OAuth handshake (authorize URL https://oauth.brightpearl.com/authorize/{account}, token URL https://oauth.brightpearlapp.com/token/{account}) and the refresh-token cycle. The node injects brightpearl-app-ref and brightpearl-dev-ref alongside the Bearer token automatically.
Supported Operations
Order
- Add Note — POST a note to an order (
/order-service/order/{id}/note). Supports optionalisPublic,contactId,fileId, andaddedOnfields. - Get — fetch order(s) via
/sales-order/{id}. Rich response includesorderStatus.name. A Simplify toggle (default on) flattens it into a cleaner shape withstatusId/statusNameat the top level, rows as an array, etc. Accepts an ID set (single, ascending range100-200, or comma list1,2,3) — each order returns as its own output item. - Get (Order Endpoint) — same data via the generic
/order/{id}endpoint (also includes status name and supports Simplify + ID sets). Use whichever endpoint your workflow prefers; results are equivalent for sales orders. - Get Many — search sales orders with column-based filters; results should be auto-enriched with reference data labels (e.g.
orderStatusId: 5gainsorderStatusName: "Complete - Cancelled") - Create — create a new sales order with rows Currently Untested Please let me know if you do test this functionality.
- Update Status — change order status, optionally with a note
- Get Custom Field Metadata — list every order custom field definition (code, name, type, and for SELECT/list fields the available option IDs + labels). Run this first to discover what to send in Update Custom Fields.
- Get Custom Fields — read all custom fields set on an order
- Update Custom Fields — set or remove custom fields via JSON Patch. Two Input Modes:
- Builder — add entries with an Operation (Add/Replace/Remove), Field Code, Value Type (Text/Date, Number, Boolean, List/Select), and Value. The Value Type ensures the correct JSON type is sent — a mismatch makes Brightpearl return a 500. For List/Select enter the numeric option ID (from the metadata operation).
- Raw JSON Patch — paste a complete RFC 6902 patch array yourself, e.g.
[{ "op": "add", "path": "/PCF_SHIPPEDD", "value": "={{ $json.ShippedDate }}" }]. Expressions work inside string values. SELECT fields use{"id": N}.
Product
- Get — fetch a single product by ID
- Get Many — search products
- Create — create a new product Currently Untested Please let me know if you do test this functionality.
Contact
- Get — fetch one or more contacts by ID via
/contact-service/contact/{ids}. ID set syntax supported. - Get Many — search contacts via
/contact-service/contact-searchwith filters (name, company, email, phone, isCustomer/isSupplier/isStaff flags, date ranges), columns, sort, pagination, batching.
Warehouse
- Get Product Availability — fetch on-hand / available / allocated / in-transit stock for one or more products via
/warehouse-service/product-availability/{ids}(all warehouses) or/warehouse-service/warehouse/{id}/product-availability/{ids}(single warehouse). Accepts ID sets. - Get Many — list all warehouses on the account; useful for discovering warehouse IDs.
Price List
- Get Many — list all price lists on the account Currently Untested Please let me know if you do test this functionality.
- Get Product Prices — get a product's prices on a specific price list Currently Untested Please let me know if you do test this functionality.
- Set Product Price — set or update a product's price (with optional quantity-break tiers) Currently Untested Please let me know if you do test this functionality.
Rate Limiting
Brightpearl enforces a per-account quota. The node handles rate limits automatically:
- HTTP 503 (quota exhausted) — waits the number of seconds in the
brightpearl-throttle-timeheader before retrying - HTTP 429 (burst limit) — waits the number of seconds in the
Retry-Afterheader - Up to 5 retries per request, with a single wait capped at 60 seconds
This is transparent to your workflow — if a transient throttle hits, the node sleeps and tries again with no extra configuration needed.
For batch workloads that intentionally pace themselves (e.g. updating thousands of orders), layer your own Wait node into the workflow. The in-node retry covers transient throttling, not long-term pacing.
Note on n8n Cloud: the rate-limit retry uses
node:timers/promisesfor sleeping, which n8n Cloud's sandbox doesn't allow. This package is therefore configured for self-hosted n8n and is not verifiable for n8n Cloud. If you specifically need Cloud verification, remove the retry loop fromGenericFunctions.tsand switcheslint.config.mjsback to theconfigexport from@n8n/node-cli/eslint.
Reference Data Enrichment
Brightpearl search endpoints return rows as positional arrays plus a top-level reference block mapping coded values (status IDs, etc.) to display names. This node converts results to keyed objects and, for any column that declares referenceData, adds a sibling field with the resolved label:
orderStatusId: 5→orderStatusName: "Complete - Cancelled"
There should also be an option to return the raw output if that is helpful for your use case.
Columns ending in Id get a Name counterpart; other columns get a Label suffix. The resolution is automatic for any column Brightpearl flags with reference data.
Links
License
MIT
