ATS / HRIS Connector Platform
One integration platform configured per client at runtime, instead of a fork per customer in code — and no engineering work required from the client to onboard.
Software Engineer, platform owner
2025, Integrity Asia
Spring Boot, Azure, Workday, Manatal
Zero client engineering to onboard
Two portals, one candidate
Background screening sits in the middle of someone else's hiring process. A recruiter moves a candidate to the background-check stage inside their own applicant tracking system, then opens a second portal and types the same details again. The duplicate entry is not only tedious — it is where the data drifts.
The obvious integration is a connector per client. That works exactly once. The second client has a different schema, a different set of stages, and a different view on which attachments may leave their system.
What shaped the design
No client engineering
Clients would not staff a project to integrate with us. Onboarding had to work from an API token or a permission-scoped service account under an agreed data-access policy.
Every client's schema differs
Each ATS or HRIS names and shapes its fields differently, and clients keep their own DTO schema. The mapping cannot be a compile-time decision.
Their rules, not ours
Which attachments may be included, and when a screening can still be withdrawn, are per-contract business rules — enforced by us, owned by them.
Platform, not per-client code
Mapping is configured through the UI rather than deployed. A new client is configuration, not a release — which is what keeps the connector count from becoming a maintenance burden.
Retries and duplicate webhooks are normal in other people's systems. The write path converges on the same state whether it runs once or five times, so the integration needs no deduplication logic of its own.
Client platforms have their own quotas and their own opinions about parallel writes. Both are handled inside the connector so the client never has to think about ours.
Stage-based rules decide whether a screening can still be withdrawn. When it cannot, the platform writes an explanatory note back into the client's ATS rather than failing silently in a system the recruiter never looks at.
Configuration is harder to reason about than code.
Runtime-configured mapping moves complexity from the repository into the database. A misconfigured client is now a support question rather than a compile error, which means validation and clear failure messages carry weight they would not carry in a per-client codebase.
It is the right trade when the alternative is a fork per customer — but it is a trade, not a free win, and it only pays off from the second client onward.
A delivery pipeline where a planner model scopes the ticket, cheaper models implement it, and the planner reviews the diff against its own plan — with a human gate where it belongs.