Qlay AI Interview
A hiring tool where a candidate uploads a CV, passes a webcam check, and interviews with an AI on video, all in one browser tab.
- Next.js
- TensorFlow.js
- Socket.IO
- Sentry
An interview that stays in the browser
Asking a job candidate to install an app loses people before the interview starts. Qlay AI Interview keeps the whole session in one browser tab: a CV upload, a webcam check, and a recorded conversation with an AI interviewer.
The webcam check has to see the candidate's face and whether they are looking at the screen. That detection runs on their own laptop, in the page, using a small face-detection model. It reaches anyone with a browser. It also depends on that laptop having working graphics, and on the model file actually downloading. Both fail often enough on unfamiliar machines that the failure had to be part of the product.
What the candidate does
They open a link from an email and sign in with a code. They upload a CV, line their face up on screen, and follow a short eye-movement check. Then they join a recorded video call with the AI interviewer and answer questions about the role, including salary and availability. Each step unlocks the next. Typing a later address by hand sends them back to the step they are actually on.
What I built
I was the largest contributor, working across the interview product. The part I owned from scratch is what happens when the camera check fails, plus the logging that watches a live interview for silent problems.
I also led the shared request layer, the language setup, and contributed to creating the video room, the microphone test, form autosave, and the rules that keep a candidate on the right step. The face-calibration flow itself was mostly a colleague's. My part there was the retry, and the report, when the face model fails to load.
When the camera fails
Some candidates saw a blank camera and no error. Support could not ask them to open developer tools in the middle of an interview. I built a check that repeats what the browser is doing and explains the result in plain language. If the computer is drawing with the processor instead of the graphics card, face detection will be too slow, and the candidate is told that. If a company network or an ad blocker stopped the model from downloading, they are told that too.
Those checks run only after something has already failed, so the diagnosis never becomes the thing that makes the page slow. A support page runs the same checks one at a time, marks each pass, warning, or fail, and gives the candidate a report they can copy into a ticket.
How the product is put together
The site is one Next.js app. The AI interviewer's voice and conversation live in a separate Python service. The video call is hosted by Daily. The site sits in front of both, so the candidate's browser only ever talks to one address.
A phone can be used as a second camera. That link stays open for the whole check, because the phone's position has to keep updating while the laptop watches. It is the one part of the product that is a live stream rather than a normal request.
English and Japanese are separate running copies of the same app. The language is chosen when that copy is deployed, so a candidate never picks a language inside the interview.
Failures that used to be invisible
A slow face model is reported even when it eventually loads, so a pattern of slow laptops shows up instead of looking like a one-off. A detection error is reported once per page, not on every frame. Saving the recording is retried only for temporary problems, such as a timeout or a server error. A mistake like a bad password is not retried.
Two failures used to leave no trace. A candidate could sit in the room while no recording ever started. A candidate could close the tab halfway through. Both are reported now, including a last send as the page closes, so the report gets out before the tab is gone.
Profile answers save themselves shortly after the candidate stops typing, and only when something changed. An earlier version asked the server for the latest copy too soon and wiped what the person had just typed, because the save had not finished. While someone is editing, the screen is treated as the current version.
A tradeoff I kept
The rules for which step a candidate may see grew into one long chain. The order of the interview kept changing, and the server was the only place that could stop someone jumping ahead by URL. It works, and the diagnosis page stays reachable even when a session is stuck. Adding a step still means adding another branch.
The same profile open in two tabs can overwrite itself. The common case is covered. Two people editing the same profile at the same time is not.