ATS
All work · 02

A recruiting operation run from Telegram, with AI that never acts alone

Client:
A premium spirits brand
Industry:
Recruiting operations
Status:
In production
Stack:
Python · FastAPI · Claude · Google Sheets · Apps Script · Playwright · Railway

A national brand hires field ambassadors continuously: posting across as many as eight job portals, screening high volumes of applicants, scheduling interviews, and keeping a pipeline moving with a very lean team. The work was drowning the people responsible for it.

We built them a recruiting operations system the team runs entirely from Telegram. The source of truth is deliberately boring: a fourteen-status candidate state machine in Google Sheets that the operations team can open, read, and trust. On top of it sits an AI coordinator that scores candidates, drafts outreach, and answers questions, and a distributed browser worker that posts jobs across the portals.

The system

TELEGRAMoperator consoleAPPS SCRIPT JOBSreminders · ats sync8 JOB PORTALSautomated at peak
Hover or focus a node for the engineering note.
fig. 02 · recruiting operations, system architecture

Three decisions that mattered

01

The state machine is the system; the AI is staff

Candidate state lives in a deterministic fourteen-status pipeline the client can audit in a spreadsheet. Claude reads it, summarizes it, and proposes moves, but state only changes through defined transitions. The trade-off is that the AI feels less magical; the return is that nobody ever has to wonder what the system did or why.

02

The decisions that matter pass a human

Job posts, group-call advancement, and hires all stop at a Telegram approval with inline edit before anything leaves the building. Routine invite emails run on rails the team defined; the gates guard what cannot be recalled. Approval takes seconds; a bad job post or a wrong hire cannot be taken back. We chose the seconds.

03

Split the runtime where the failure modes split

Webhooks, scheduling, and chat run as a lightweight Railway service; browser automation runs on a dedicated worker that claims queued jobs one at a time. Browser sessions crash, get challenged, and need retries; the coordinator should never go down with them.

The AI layer, honestly

The coordinator is a tool-using Claude agent with a small set of typed tools: candidate lookup, status updates, scheduling, posting queues, and long-term notes. Cost engineering is part of the architecture: the persona and roster live in cached prompt blocks, volatile pipeline counts stay uncached, and routine turns run on a fast model with escalation to a stronger one logged and keyword-gated. The agent drafts and recommends; the state machine and the human decide.

What broke, and what we changed

Production taught us where the paper cuts were: reminder timing that operators found noisy, sync mismatches with the client ATS, and portals behind aggressive bot protection that needed stealth sessions and persistent cookie jars. The fixes shipped as operator-reported issues within days, which is the real benefit of the approval-gate design: humans in the loop notice drift before it becomes damage.

Results, and how they were measured

14

statuses in the candidate state machine

The auditable source of truth the whole system moves through.

8

job portals automated over the engagement

Built and run with browser workers at peak; two portals post today, one via API, one via a stealth-hardened worker.

100%

of job posts and hires human-approved

By architecture, not by policy: posting and hiring have no code path around the gate.