Priority
Priority is an ERP platform covering financials, sales and purchase orders, invoicing, inventory, projects, service management and HR. It is deployed both as Priority Cloud and on-premise, and is especially widespread in Israel and across EMEA mid-market manufacturing, distribution and retail.
The Willow Priority connector talks to the Priority REST API, which is an OData v4 service. Every Priority form is exposed as an OData entity set, every field as a property, and every subform as a navigation property — so the same handful of tools reaches any form your installation exposes, including private customizations.
Authentication Types
Priority supports 2 authentication methods through this connector:
- API Key — A Personal Access Token (PAT) or a classic API user, sent as HTTP Basic authentication.
- Pros: Works on every Priority installation and version 19.1+, no extra modules to purchase, ideal for server-to-server automation.
- Cons: Shared service identity — all tool calls are attributed to one Priority user.
- Best for: Most deployments, and the only option unless you own the External ID module.
- OAuth 2.0 (Authorization Code with PKCE) — Each user connects with their own Priority account through your identity provider.
- Pros: Per-user attribution and permissions, automatic token refresh.
- Cons: Requires the External ID module, and all Priority users must already authenticate through an external IdP.
- Best for: Installations that have External ID configured and want end users acting as themselves.
Basic authentication with a username and password is disabled while External ID access is enabled. If your installation uses External ID, use OAuth 2.0 (or a PAT, if your administrator has enabled it).
General Settings
Before connecting, you must provide:
- Service Root URL — The full OData service root of your Priority installation, including the
tabula.inifile and company database.- On-premise example:
https://your-server.com/odata/Priority/tabula.ini/usdemo - Priority Cloud example:
https://www.eshbelsaas.com/ui/odata/Priority/tabmob.ini/usdemo
- On-premise example:
- Accounts Base URL (optional, OAuth only) — Base URL of the Priority accounts app, e.g.
https://your-server.com. Leave it empty and Willow derives it from the service root by taking everything before the/odatasegment.
Where to find your Service Root URL
Your Priority system administrator can produce it with the Send Program Activation Link program. The URL is made up of:
https://<host>[/ui]/odata/Priority/<tabula ini file>/<company>
To access a multilingual installation in a specific language, append the language code to the ini file name, e.g. .../Priority/tabula.ini,3/usdemo for American English.
Setting up API Key authentication
1. Create a Personal Access Token
-
Log in to Priority as an administrator
-
Open the REST Interface Access Tokens form (System Management → System Maintenance → Users)
-
Add a row for the user the integration should act as and generate a token
tipCreate a dedicated Priority user for the integration so its activity is easy to audit and its permissions can be scoped independently.
-
Copy the token
2. Configure in Willow
-
In Willow, go to Integrations → New → Built-in
-
Select Priority and click Use
-
Under Authentication Type, select API Key
-
Paste the token into the API key field
-
Under Configuration, set the Service Root URL
-
Click Save Changes
Using a classic API user instead
If your administrator prefers a plain API user over a token, paste the credentials as username:password — Willow detects the colon and sends them as standard Basic authentication.
- The username is the API User Name field of the user's Personnel File form, which is separate from their Priority UI login.
- Priority rejects Basic authentication while External ID access is enabled.
Setting up OAuth
OAuth 2.0 requires the External ID module. Only the Authorization Code flow with PKCE is supported.
1. Register an external application in Priority
-
Log in to the Priority UI
-
Open the External Applications form (System Management → System Maintenance → Users → Manage IDs Externally → External Applications)
-
Add a new application and give it a name — the Application ID and Secret ID are generated automatically
-
In the Redirect URL subform, add the callback URL shown in Willow when configuring the connector
-
Save
2. Configure in Willow
-
In Willow, go to Integrations → New → Built-in
-
Select Priority and click Use
-
Under Authentication Type, select OAuth
-
Paste the Application ID as the Client ID and the Secret ID as the Client Secret
-
Confirm the scopes are
openidandrest_api -
Under Configuration, set the Service Root URL. Set the Accounts Base URL only if the accounts app is served from a different host than the OData service
-
Click Save Changes, then Connect to run the OAuth flow
Willow calls https://<accounts base>/accounts/connect/authorize and https://<accounts base>/accounts/connect/token. If your IdP setup exposes a discovery document, you can verify these endpoints at https://<accounts base>/accounts/.well-known/openid-configuration.
How the tools map to Priority
Priority's API is uniform, so the connector ships a small set of generic tools plus shortcuts for the forms most integrations touch.
| Priority concept | API concept | Tools |
|---|---|---|
| Form (e.g. ORDERS) | Entity set | Query Records, Get Record, Create Record, Update Record, Delete Record |
| Field (e.g. CUSTNAME) | Property | select, filter and orderby arguments |
| Subform (e.g. ORDERITEMS_SUBFORM) | Navigation property | List / Create / Update / Delete Subform Record, or the expand argument |
| Text form | Text subform | Get Record Text, Update Record Text |
| Attachments | EXTFILES_SUBFORM | Attach File |
Discovery first
Exposed forms and fields differ per installation, so start with:
- List Forms — every entity set this installation exposes
- Get Form Metadata — key fields, column types and available subforms for one form (Priority 25.0+)
- Get Priority Version — to check which version-gated features are available
Keys
Records are addressed by their business key, not their internal auto-numbered id (which is read-only and rejected on PATCH):
ORDERS('SO18000002')— keyed by ORDNAMECUSTOMERS('T000001')— keyed by CUSTNAMELOGPART('111-012')— keyed by PARTNAMEAINVOICES(IVNUM='T9696',IVTYPE='A',DEBIT='D')— composite key
Pass simple keys in the key argument and composite keys in key_expression.
Common Use Cases
Order to cash
- List Customers with a filter such as
CUSTDES eq 'ACME Inc.'to find the customer number - List Parts to find the parts to sell
- Create Sales Order with the customer number and the line items in one call
- Get Sales Order to read back the generated ORDNAME, prices and status
- List Invoices filtered on the customer to track the resulting invoices
Incremental sync
Use List Sales Orders (or Query Records) with since set to the last sync timestamp in UTC, e.g. 2024-01-01T07:25:00Z. Combine it with expand to bring changed orders and their lines back in a single call. The since option only works on forms that have business process management applied.
Working with any form
For forms without a dedicated tool — projects, receipts, warehouse balances, contacts (PHONEBOOK), or private customizations — use Query Records with the form name. Form names vary between installations, so confirm the exact name with List Forms and the column names with Get Form Metadata first.
Multi-step writes with error isolation
When creating a document plus its lines, Run Batch Request reports exactly which operation failed, which a single nested create cannot. A later request can reference an earlier one's result: give the order create id: "1" and set the line's url to $1/ORDERITEMS_SUBFORM.
Rate Limits
Priority Cloud enforces a fair use policy per tenant:
- 100 API calls per minute per user
- 10 concurrent requests, with 5 more queued (15 in flight total)
- Requests taking longer than 3 minutes are dropped
Throttled requests are rejected with HTTP 429.
Result sets are capped by the MAXAPILINES system constant (2,000 records by default in 25.1+; MAXFORMLINES in earlier versions), and responses are capped at 350 MB.
Best practices:
- Always pass
select— Priority returns every column of a form by default, and forms are wide - Page with
topandskipinstead of pulling whole forms - Prefer
sinceover re-reading everything on a schedule - Use
expandinstead of a follow-up call per record
Transaction Counting
Every record created or updated through the API counts as a transaction against your Priority license, purchased in packages of 10,000 per month. Creating an order with 5 lines costs 6 transactions; updating its status costs 1. Reads are free.
From version 25.1 all API users share one transaction pool; before that the monthly quota was divided equally between API users.
Troubleshooting
401 Unauthorized on every call
Cause: The credential type does not match how the installation is configured.
Solution:
- Confirm whether External ID is enabled — if it is, Basic authentication with username and password is rejected
- For a PAT, confirm the token exists in the REST Interface Access Tokens form and belongs to an active user
- For a classic API user, confirm you are using the API User Name from the Personnel File form, not the Priority UI login, and that you entered it as
username:password
404 Not found on a form that exists in the UI
Cause: Requests are case-sensitive, or the form is not exposed to the API.
Solution:
- Priority form and field names are uppercase (with rare exceptions such as
DOCUMENTS_p) — match them exactly - Run List Forms to confirm the entity set exists in this installation
- Verify the company and
tabula.inifile in the Service Root URL point at the environment you expect
A custom field is missing from the API
Cause: REST metadata for the form was built before the customization was added.
Solution: Run Refresh Form Metadata for that form (Priority 22.0+). Priority rebuilds it on the next request to the form. Subforms are refreshed with their parent.
400 Bad request on a filter
Cause: Filter syntax or value formatting.
Solution:
- Quote string values with single quotes:
CUSTNAME eq 'T000001' - Write decimals with a point, never a comma, regardless of locale
- Write dates as full ISO 8601 timestamps, e.g.
2018-02-23T09:59:00+02:00 - When combining
expandoptions with;, some proxies strip the semicolon — this shows up as a syntax error on a query that worked before you added the second option
Errors returned as XML with an InterfaceErrors section
Cause: This is not a transport failure — the Priority form itself rejected the values, exactly as it would in the UI.
Solution: Read the text inside InterfaceErrors; it is the same validation message a user would see. Fetch the form metadata to check mandatory columns (annotated from version 25.1) and allowed values.
A batch failed halfway
Cause: Priority commits each operation as it runs.
Solution: Batches do not roll back, so a partially applied batch leaves the earlier records saved. Re-run only the failed operations, and use dependsOn so dependent writes are skipped when their prerequisite fails.
The OAuth redirect fails or returns an invalid client error
Cause: The redirect URL or accounts base URL does not match.
Solution:
- Copy the callback URL from Willow exactly into the Redirect URL subform of the External Applications form
- If your accounts app lives on a different host from the OData service, set the Accounts Base URL in the connector configuration
- Confirm the External ID module is installed — without it the authorize endpoint does not exist
Application Licenses
If your Priority installation uses per-application licensing, requests must carry the X-App-Id and X-App-Key headers assigned by Priority Software. Add them under Custom Headers on the integration and they are sent with every tool call.
Additional Resources
- Priority REST API documentation
- Authenticating with the REST API
- Querying data (OData options)
- Modifying data
- OData v4 documentation
Need Help?
If you encounter issues not covered in this guide, please contact Willow support with:
- The exact error message, including any
InterfaceErrorstext - The tool you were using (e.g. Create Sales Order) and the form it targeted
- Your Priority version (from Get Priority Version) and whether it is cloud or on-premise
- The HTTP status code returned (if visible)