Back to Indeed
How the Indeed lane works
The operator manual for the inbound Indeed channel: what happens automatically, what the numbers mean, what you control, and the switches that take it live.
The pipeline at a glance
- A listing goes up on Indeed — either an evergreen always-on posting per region, or a branded posting chasing one live
creatorDemandrow (the same demand spine Handshake uses). Posting happens through the deployed browser service; the listing record here is our operational truth. - Applicants arrive and are screened instantly — the deterministic screener (no AI, same input → same verdict) runs knockouts first, then scores the rubric. Every applicant becomes a lead on the shared leads spine, deduped by email.
- The funnel moves on its own — passed applicants advance to
contactedand enroll in the follow-up cadence; benched applicants park on the bench; rejected stay atdiscovered. Nobody already further along is ever moved backwards. - Messaging runs automatically— Indeed's own automation sends the welcome (touch 1); our cadence sends touches 2–3. Applicant replies are read every 5 minutes: routine questions are auto-answered by the Mastra agent, edge cases escalate into the unified Inbox as Indeed threads you can answer directly.
- Spend is paced, watched, and clamped— a daily loop computes each branded listing's budget, never exceeding your ceiling; a reconcile loop reads Indeed's reported actuals and auto-pauses on drift.
- Conversion closes the loop — signups are detected by reading prod (email match), which stops the cadence and hands the lead off.
Reading the dashboard
- Applicants / Passed / Benched / Rejected
- Totals across all Indeed applications, by screen verdict.
- Live listings
- Listings currently up (status
live;wound_downones are closed on Indeed but kept for history). - Active demand
- Live
creatorDemandrows — programs currently recruiting. Branded listings must chase one of these. - Applicant rows
- Each shows the lead's email + funnel status, the listing it came from, the UGC score, and the verdict badge. A knockout failure shows its reason (e.g.
under_18,country_not_targeted). - Seed / Clear (dev only)
- Local-development buttons that fabricate a realistic sample through the REAL screener, and wipe it again. They never appear in production; real applicants arrive via the transport ingest.
The screener — exactly
Eight knockouts run first; any failure = instant reject, score 0:
- 18 or older
- country matches the listing's target countries (branded listings only)
- has a 1080p-capable smartphone (any brand — iPhone not required)
- valid email
- OK creating content without posting on their own socials
- understands this is paid work
- can commit monthly
- consents to contact
Survivors are scored on a 105-point rubric— experience, camera comfort, editing skill, equipment setup, start availability, a sample link (+15 when present), and the "why" blurb (0/4/8) — normalized to the 0–100 UGC score shown on the dashboard.
- Pass mark
- 40 for always-on listings · 55 for branded listings (a branded posting demands a stronger fit).
- Bench floor
- 20 — scores between the floor and the pass mark go on the bench (kept, not contacted, revisitable); below 20 rejects.
Messaging — what is automated
- Touch 1 is Indeed's own automation("message new candidates", the welcome with signup instructions) — we deliberately leave it on.
- Touches 2–3 are ours: +2 days and +5 days after enrollment, capped at 3 total, drafted per-applicant by the Mastra agent, respecting quiet hours and a 1-message/24h floor. Only passed applicants are enrolled.
- Replies are polled every 5 minutes.The agent classifies each one: anything answerable from our knowledge (device requirements, payment, how to sign up, "I sent my video") is auto-answered in-platform; genuine edge cases — complaints, legal topics, eligibility ambiguity, brand questions beyond the facts — escalate.
- Escalations land in the unified Inbox as Indeed-channel threads. Reply there like any thread — the send goes back through the Indeed transport. The applicant's cadence halts the moment they reply (they are in a conversation now).
- The agent's knowledge cannot drift: its FAQ is derived from the screener configuration itself, plus the operator-editable offer facts (Settings) and retrieval over past creator conversations. On any doubt or failure it escalates to a human — it never guesses.
- Suppressed, opted-out, or already-converted people are never auto-answered — that gate is deterministic code, before any model runs.
Spend — human ceilings, autopiloted pacing
- You set the ceiling; the loop never exceeds it. Daily budget = remaining quota ÷ remaining days × cost-per-apply (default $5), clamped between the $3 floor and your per-branded-posting daily ceiling. Ceilings are human-authored — the system never invents or raises one.
- Dry funnel guard: a listing live for 2+ days with zero applicants holds its budget at the floor — spend is never scaled into a channel that isn't proving intake.
- Reconcile every 6 hours: reported actual spend is compared to intent; a daily rate above 1.5× intent auto-pauses the listing (and zeroes its budget when live). Only a human un-pauses.
- Indeed's account-level budget cap (CSM-set) is the hard backstop underneath all of this.
The switches — what is live right now
Everything ships dry-run by default. Real effects require these, in order:
- INDEED_SERVICE_URL + INDEED_SERVICE_TOKEN
- Points Convex at the deployed browser service (the thing that actually drives the Indeed employer dashboard). Until set, external ops fail with a clear "not configured" error and the crons skip cleanly.
- STEEL_API_KEY + INDEED_STEEL_SESSION_CONTEXT
- On the service: the Steel browser session carrying the warm Indeed employer login (a human seeds it once).
- INDEED_DASHBOARD_VERIFIED
- Until
true, every dashboard-driving operation fails safe — flipped only after the selectors are confirmed against the live employer UI. - INDEED_MESSAGING_LIVE
- Until
true, the messaging lane is a full dry run: would-be auto-answers and cadence touches are recorded in the ledger, nothing is sent. - INDEED_SPEND_LIVE
- Until
true, the spend loop computes and records budgets but never moves a dollar. The only op that spends money sits behind BOTH this and the dashboard gate.
Per-listing kill switch: spendPaused (set automatically on drift, or by hand). The schedules: inbound poll + messaging drain every 5 min, spend pacing daily, reconcile every 6 h.
If something looks wrong
- Tiles all zero
- No applicants ingested yet — in dev, press Seed sample data; in prod, check the service env vars and that a listing is live.
- “Indeed transport is not configured”
- Expected until
INDEED_SERVICE_URL/TOKENare set on the Convex deployment. - An applicant appears twice on Indeed
- They can't here — ingest is idempotent on Indeed's application id (their 60-day replay changes nothing), and people dedup by email onto one lead.
- A listing stopped spending
- Check
spendPaused/pausedReason— reconcile likely detected drift, or the quota filled. Un-pausing is deliberately manual.