AQYR: one recruitment platform for agencies, employers, and the candidates between them
AQYR runs the whole hiring cycle. We built the platform behind it: the architecture, the access model between organisations, the engine that reads and scores CVs, the integrations, and the infrastructure it runs on.
- 21 modules, one codebase
- 6 user types
- 6 scoring dimensions
- 4 entry points, one path
- 1 candidate record per person
What the platform does
Follow one person through it and the product explains itself.
A recruiter enters a title, location, salary and requirements. The advertisement is drafted from that and one action publishes the role to several job boards, the company's careers page, and their existing recruitment software.
Their CV is stored, the application recorded, and the confirmation appears immediately. Nothing heavy happens while they are waiting.
By then every CV has been read and every applicant scored against the role, each with a breakdown of how the score was reached and which priority skills the person can actually evidence.
Candidates not right for this role are kept in a talent pool that stays current, so the next similar role starts with a warm list rather than a blank page.
- Client
- AQYR, a recruitment platform for agencies and in-house hiring teams
- Product
- Multi-tenant B2B SaaS with a candidate-facing portal
- Our scope
- Web application, backend platform, CV parsing and scoring engine, integrations, cloud infrastructure
The one fact that shaped everything
Most multi-tenant platforms are built around one rule: keep tenants apart. This one could not be.
AQYR has to let tenants across the boundary on purpose.
An external recruitment agency works a client company's roles. They need that client's jobs, candidates, notes and email history, and none of it for any other client on the platform. Two competing agencies can be working the same employer at the same time. The same agency can be working two employers who compete with each other.
The requirement is not isolation. Isolation is the easier problem. The requirement is permission that is granted deliberately, scoped narrowly, and withdrawn at three different levels, evaluated fresh rather than assumed from a session that started an hour ago.
The largest group of people on the platform are not the customers.
Candidates outnumber recruiters by orders of magnitude, and a CV is one of the densest personal records a person ever produces: full name, address, phone, email, every employer, every date, qualifications, work rights, salary expectation. Most of those people never signed up for anything. They applied for a job.
The four decisions that mattered
If you read nothing else on this page, read this.
An agency recruiter can reach a client's data because they were connected, approved and staffed onto that account, not because they hold a recruiter account.
Reading a CV and scoring a candidate happen on a queue, so a candidate gets an instant confirmation and a recruiter can post a job to thousands of people without the screen hanging.
Two independent methods, six visible dimensions, and a written explanation, because a recruiter has to justify a shortlist to a client.
Candidate data and client credentials are protected on the assumption that the likeliest threat already has a valid login.
Access between organisations is a grant
The platform recognises six kinds of user, and the difference between them is the access model rather than the interface. The hard row is the agency client: an external recruiter working a client's roles, needing scoped access into a different tenant's data. A role-based model fails here immediately. If access came from holding an agency account, every agency would reach every client.
A client decides whether agencies can find the company at all. An agency does not see, and so cannot request, a company it has not been permitted to find. This is the gate most platforms skip, and skipping it makes every customer permanently enumerable.
Each connection request is accepted or declined by the client itself, individually. There is no bulk state in which agencies are broadly trusted.
The agency names which of its own recruiters staff the account. Being employed by a connected agency does not grant access. Being staffed on the account does.
Access is evaluated against the connection as it currently stands rather than as it stood when the session began. A recruiter removed from an account loses it on their next request, not their next login.
Withdrawal works at three levels, each leaving the others intact: block one recruiter, disconnect the agency, or turn off discoverability entirely.
Two competing agencies can work the same employer without either learning the other is there.
Access ends when the relationship ends rather than when a session does.
The client holds the controls, not support. Discoverability, approval, per-recruiter blocking and disconnection are all client-side actions requiring no ticket.
Onboarding an agency became a scoped, revocable, individually staffed grant about a specific engagement.
Four gates is more machinery than a permission flag, and it shows up in three places: more steps to onboard an agency, more cost to evaluate per request than to trust a session claim, and an oversight view that somebody has to maintain. Each has a bounded answer. The onboarding steps are the product working, not friction. The per-request evaluation is a cached lookup. The oversight view pays for itself the first time someone asks who has access to a client's candidate data, which in recruitment is a question that arrives with a lawyer attached.
Nothing heavy runs where a person is waiting
Scoring is heavy and it arrives in waves. Post one job or change a role's requirements, and thousands of candidates need scoring in the same second. That load profile is not an edge case in recruitment. It is the normal shape of the work.
A candidate applies, a recruiter adds someone by hand, a batch of CVs is imported, or a role's requirements change and every applicant is re-scored. All four take the same path, which is why all four behave the same way under load.
The backend places one message per candidate on a queue and responds immediately. Workers pick the work up at their own pace. Throughput becomes a dial rather than a redesign: more speed means more workers on the same queue.
Handlers are idempotent. Completion is confirmed. Stalled work is recovered on a schedule. A candidate without a score is invisible to the recruiter, so a lost message is a missed match and a wrong shortlist.
Publishing one role to five boards creates one stream of traffic aimed at the same public job page at the same time, from candidates and board crawlers alike. High-repeat public reads are cached, so the same job page is served without reaching the application and database every time. It is the same principle as keeping heavy work off the request path, applied to traffic the product creates rather than traffic it receives.
Job posting and re-scoring return in milliseconds regardless of batch size.
A candidate gets an instant confirmation. The heaviest work in the product happens after the only moment a candidate is watching.
Heavy load stopped competing with the site. Bulk import and mass scoring run on separate machines.
Throughput became a capacity decision. Faster means more workers on the same queue.
A score has to be defensible
Two problems sit behind every ranked list, and most platforms solve only the first: reading the CV, and justifying the ranking. A score nobody can explain is a score nobody can defend, and a score that is fully explainable is usually keyword matching wearing a percentage.
Files with extractable text are read directly. Scanned pages are read optically. Documents that defeat both fall to a vision model reading the page image. Every rung exists because a real document failed the one above it. What reads the text is a model fine-tuned on resumes rather than ordinary prose, so it works out which names are employers and which are people, how dates attach to each role, and which skills the document can genuinely evidence rather than merely mention. The output is a structured profile, and that profile is what everything downstream searches and scores against.
Traditional matching compares the candidate against the role using two knowledge graphs covering job roles, skills and employers. A vector model lets the engine judge that two differently worded phrases mean the same thing, so a match does not depend on the candidate happening to use the recruiter's vocabulary. Alongside it, a language model reads the whole CV in context and produces a written recommendation in a consistent shape every time.
The two methods combine across six dimensions. The weights belong to the recruiter, adjustable per role, so the ranking reflects what matters for that hire rather than what mattered on average across a training set.
Protecting the people who never signed up
The largest group of people on this platform have no account on it. A CV is one of the densest personal records a person produces, and a recruitment database is a concentration of them. The person most likely to take it is not an outsider. It is somebody who already has a valid login.
Everything downstream searches, filters and scores against the structured profile. The source document stays out of most code paths that touch candidate data.
Keys managed separately from the data they protect. Reading the database is not the same as reading the candidate base.
No administrative credential exists in the application at all. An injection runs with the privileges of the credential it landed on, so the ceiling on the damage is set before the attack rather than negotiated after it.
Never embedded in code, images or configuration. A client's board or mailbox credential can be rotated without a deployment. Rotation you can actually perform is rotation that happens.
Candidate management, job management, communications and user activity each produce an entry with actor and timestamp, written in the background. Recruitment decisions get questioned months later, sometimes by a candidate and sometimes by a regulator. A trail assembled retrospectively is not a trail.
In a system holding this much personal data the threat that matters most is rarely an outsider breaking in. An insider event leaves no trace in an access control list, so watching behaviour rather than permissions is what makes it visible at all.
Security and confidentiality are the two anybody reaches for. The one that actually governs this product is privacy, and it is a different thing.
Privacy is about the people the data is about: whether they know what is held, whether they have a say, and whether a request about them can be answered. On a recruitment platform those people are candidates, who outnumber the paying users by orders of magnitude and mostly never signed up for anything.
That is why duplicate merging is a privacy control rather than a data quality one. A person fragmented across four records cannot be given a straight answer about what is held on them, or have it deleted on request, no matter how good the intent behind the reply.
The control set was designed against the criteria rather than mapped to them later. That is a statement about how it was built, not a claim to hold an attestation.
The constraints we designed around
Platforms that carry real volume across real integrations meet constraints. Some belong to partners who will not change their systems for you. Some appear when a threshold is crossed. Some come from the industry itself.
Building for all of them on day one is not prudence, it is waste. The work is knowing which to design for up front, which to instrument and address at the threshold, and which are somebody else's decision to be routed around cleanly.
Every job board wants the job differently
One role often needs to appear on five or six boards at once, and no two want it the same way. One insists on a salary range in its own format. Another wants a work type code from its own fixed list. Boards also expire ads, reject them, or take a while to put them up, so a job the system believes is live may not be live at all.
The recruiter fills the job in once and picks their boards. Per-board requirements are held per client and applied automatically. Each posting is checked on a short timer rather than assumed to have worked.
Advertising a job everywhere is one action. A failed or expired posting is visible immediately. A job can be pulled from a single board without touching the others. An application from an external board arrives as a full candidate record, already read and scored, in the same ranked list as a direct applicant.
One person can reach the platform through a job board application, an ATS sync, a bulk import, and a recruiter's mailbox, and rarely with the same details each time.
The people most exposed by this platform are the ones with no account on it. A CV carries contact details, address, employment history, qualifications, work rights and salary expectation.
People sign in with an existing work account, and every account also has to exist on the platform. Two systems that maintain their own records will eventually disagree.
Location search ran on services the provider then deprecated. That is not a defect to schedule around at leisure. It is a countdown attached to a filter used across the entire product.
What this means, depending on your job
The access model is what makes this a platform rather than a directory with scoring on top. Two competing agencies working the same employer without either learning the other is there is not a feature. It is the reason a company hands over its candidate data at all.
The talent pool compounds. A candidate database that keeps itself current turns sourcing cost into an asset, so the second hire in a role is cheaper than the first rather than the same price again.
Both sides are served without forcing either into a shape they do not work in. Agencies subcontract, employers work in teams, and a model that ignores either loses that side of the market to whoever does not.
The access model is the part worth your attention. Deliberate cross-organisation access is harder than isolation, and the four gates plus per-request evaluation are what make it a control rather than a policy. Work separated by what governs its duration, syncs that reconcile rather than overwrite, and a scoring path safe to retry because it was designed to be.
Per-board requirements are configuration rather than code. Four entry points into the scoring engine take one path, so all four behave the same under load. Reconciling syncs mean a failed run is retried rather than investigated. That is what keeps a team shipping features in year two instead of maintaining twenty-one special cases and a folder of one-off import scripts.
Recruiter time moves from reading to deciding. Every CV arrives read, scored and explained. The candidate database becomes an asset rather than an archive. Talent pools stay current as new people arrive. Advertising is one action rather than six. Throughput scales with workers rather than with engineering.
Built with
We name the layers rather than the suppliers on the candidate data path, because a supplier map is our client's exposure rather than our credential. Full detail available under NDA.
More case studies
View all case studiesBuilding a platform where the wrong person seeing the wrong record is not an acceptable outcome?
Tell us what you're building, and we'll tell you honestly how we'd approach it.