| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
Discuss (mail)
|
| Lines of code | 1992 |
| Technical Name |
eh_hero_base |
| License | OPL-1 |
| Website | https://www.erpheritage.com.au/ |
| Versions | 16.0 17.0 18.0 19.0 |
Employment Hero Connector Core
The transport, auth and endpoint foundation every Employment Hero module in this suite is built on.
Why this module
Employment Hero Connector Core
The right auth for each product
One connection model speaks both Employment Hero product families: API key Basic auth for the Payroll API, and OAuth2 Bearer with PKCE and lazy refresh for the HR platform. A static header token scheme covers the recruitment API. Sync jobs call one connection and never deal with auth themselves.
Endpoints are data, not Python
Every API path is a record in a registry. Add a new endpoint from the user interface, set its method, path template and pagination style, and it is immediately callable with no module upgrade. The connector ships a base catalogue of common HR and payroll reads to start from.
Resilient transport by default
Client side rate limiting, exponential backoff with jitter, and retry of transient failures only. A retried write carries an idempotency key so the vendor deduplicates it instead of creating a second record. Credentials are admin only, tokens are encrypted at rest, and every call is logged with secrets redacted.
Day in the life
What a working day looks like
An administrator creates a connection for the company, picks the product, and either pastes an API key or runs the OAuth2 authorisation in a new tab. The Test Connection button probes a known endpoint and reports success or the exact error. From then on the domain modules call the connection on a schedule. Under load the rate limiter holds calls under the vendor cap so 429 storms never start, transient failures retry quietly with backoff, and OAuth tokens refresh themselves before they expire. When something does fail, the redacted API log shows the endpoint, status, timing and a truncated body, so an integrator can see exactly what was sent and what came back without any credential ever landing in the log.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
A write carries an Idempotency-Key that stays the same across every retry of the call, so a create that is resent after a timeout is deduplicated by the vendor rather than creating a second record.
When several workers hit an expired OAuth token at once, the token row is locked FOR UPDATE in an autonomous transaction and the expiry rechecked after the lock, so only one worker POSTs the refresh and a rotated refresh token is never overwritten with a dead one.
The authorisation flow is claimed atomically by state with a single DELETE RETURNING, so a replayed or concurrent callback finds nothing and cannot redeem the same code twice. PKCE binds the request to the exchange.
The default rate limiter is a database backed token bucket metered against the database clock, so N Odoo workers draw from one shared budget per rate group instead of each running its own and multiplying the real request rate.
If the shared budget is spent after the maximum wait, the client refuses to send and raises a rate limit error rather than adding to the very 429 storm it exists to prevent, leaving the caller to retry with backoff.
A server Retry-After header is honoured on a 429, but clamped to five minutes so a hostile or buggy header cannot park a worker for hours.
Pagination supports OData skip and top, page index and cursor styles per endpoint. When a hard page cap is hit the results are truncated and a warning is logged rather than silently dropping records, with advice to narrow the query.
If a paginated endpoint returns an HTML error or maintenance page instead of JSON, the parser raises rather than yielding the text as if it were a record.
The audit log redacts sensitive keys, personal and financial identifiers, and bearer or basic tokens inside raw string bodies before storage, then truncates, so a chatty sync never leaks a credential or PII into the database.
OAuth tokens are encrypted with Fernet and tagged with the key fingerprint. If the cryptography package is missing, storing a token is a hard error, not a plaintext fallback, and a decrypt under a changed key fails with an actionable message and a rotation helper.
What is inside
Built to do the job, end to end.
- Connections and authentication. One connection record per Employment Hero product and company. API key Basic auth for the Payroll API, OAuth2 Bearer with PKCE and automatic refresh for the HR platform, and a static header token for the recruitment API. A Test Connection action probes a known endpoint and records the result. Credential fields are restricted to system administrators.
- Data driven endpoint registry. Every API path is an eh.endpoint record with its method, path template, pagination style and rate group. A shipped base catalogue covers common HR and payroll reads, and integrators add their own from the user interface with no module upgrade. Path placeholders such as the business or organisation id are filled automatically from the connection.
- Resilient transport. A single client carries every call with client side rate limiting, exponential backoff with jitter, retry of transient failures and 429 only, per request timing, and an idempotency key reused across retries of a write. Pagination handles OData, page index and cursor styles, reading either a bare list or a wrapped envelope.
- Rate limiting backends. A token bucket caps the request rate. A cross worker backend backed by a database row meters one shared budget per rate group against the database clock, the default so a multi worker deployment honours one cluster wide cap. A lighter in process bucket is available for single worker hosts by system parameter.
- Security and audit. OAuth tokens are encrypted at rest with Fernet, keyed from an environment variable or a generated system parameter, with key fingerprint tagging and a rotation helper. A redacting API log records every call with credentials and PII stripped, garbage collected on a configurable retention horizon. A separate append only log records deliberate reveals of sensitive fields.
- Multi company and scheduling. Connections and logs are isolated per company through global record rules, while the endpoint catalogue is shared. Two scheduled jobs ship enabled: a proactive OAuth token refresh and a purge of old API log rows. Sync jobs look up the default connection for their product and company automatically.
Honest about the edges
What this does not do, so nothing surprises you.
- This is a transport and configuration core. It does not by itself sync any HR, leave, attendance or payroll record into Odoo. The domain modules in the suite do that on top of the services it exposes.
- There is no field mapping, record matching or upsert logic in this module. Those live in the sync engine and domain modules.
- There is no webhook receiver or real time push. The connector pulls from the Employment Hero APIs on a schedule set by the domain modules; it does not accept inbound events.
- Sync is one direction, reading from Employment Hero into Odoo. This core does not perform two way sync or conflict resolution between the two systems.
- The shipped endpoint catalogue covers common HR and payroll reads. Other endpoints are added as registry records by an integrator; the connector calls any path you register but does not ship every Employment Hero endpoint.
- OAuth token encryption requires the Python cryptography package. Without it, storing a token is refused rather than downgraded to plaintext.
- Built and tested for Odoo 18 Community. Other series are not targeted by this build.
Employment Hero connector, Employment Hero Odoo integration, KeyPay API Odoo, Employment Hero HR platform API, OAuth2 Bearer PKCE Odoo, API key Basic auth connector, data driven endpoint registry, token bucket rate limiting Odoo, retry exponential backoff jitter, idempotency key API write, encrypted OAuth token storage, redacted API audit log, OData cursor pagination, multi company integration Odoo 18, Odoo 18 Community connector
Need this fitted to the way you work?
ERP Heritage delivers end to end Odoo work: Odoo Implementation, Customization and Development, Integration, Migration, Consultation, Support and Training. We help teams put this module into production, shape it to their process, and keep it running.
We work with businesses across Australia (Melbourne, Sydney, Brisbane, Perth, Adelaide, Canberra) and the Middle East (Dubai, Abu Dhabi, Riyadh, Jeddah, Doha, Kuwait City, Muscat). Start a conversation at erpheritage.com.au or email info@erpheritage.com.au.
Languages
Available in 19 languages
The interface ships translated out of the box. Switch language in Odoo and the fields, menus, and messages follow.
Modules teams pair with this one.
Premium ERP Heritage modules that extend the same stack, each built to the same engineering bar.
Bring Employment Hero onboarding workflows, employee goals and contractor flags into Odoo Community as real recor...
End to end French B2B and B2G electronic invoicing for the DGFiP reform, generating Factur-X PDF/A-3 with embedde...
Accept ZainCash wallet payments in Iraq at your Odoo checkout, on the ZainCash Payment Gateway v2 with OAuth2, re...
Sync Employment Hero ATS recruitment job openings into the standard Odoo Recruitment app, mapping each opening on...
The Singapore country pack for the ERP Heritage Employment Hero integration
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
Discuss (mail)
|
| Lines of code | 1992 |
| Technical Name |
eh_hero_base |
| License | OPL-1 |
| Website | https://www.erpheritage.com.au/ |
Odoo Proprietary License v1.0 This software and associated files (the "Software") may only be used (executed, modified, executed after modifications) if you have purchased a valid license from the authors, typically via Odoo Apps, or if you have received a written agreement from the authors of the Software (see the COPYRIGHT file). You may develop Odoo modules that use the Software as a library (typically by depending on it, importing it and using its resources), but without copying any source code or material from the Software. You may distribute those modules under the license of your choice, provided that this license is compatible with the terms of the Odoo Proprietary License (For example: LGPL, MIT, or proprietary licenses similar to this one). It is forbidden to publish, distribute, sublicense, or sell copies of the Software or modified copies of the Software. The above copyright notice and this permission notice must be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Please log in to comment on this module