Skip to content

WW-81 (WING-78) — Search (BYO-key) vs Historic JOA (bulk) ingestion strategy

Spike research. Produced by fleet worker (grok kind, DESKTOP-D249KD4), 2026-07-24. Reviewed and committed by WT-2f62. Builds on WW-78.

Architecture ownership

Concern Owner
Live open jobs, ApplyURI, hiring-path filters, refresh-on-demand UsaJobsSource + user BYO Search key
Scheduled bulk, local index, demo fixtures, MOS→series examples WW-side Historic JOA ingest (optional Announcement Text for long text)
Codelists (hiring paths, series, opening statuses) Unauth codelist endpoints — cache on WW or per client
Apply path Deep-link only (WW-82)

Staleness policy (Historic)

Use Acceptable lag
Demo / screenshots / offline browse Days–weeks
MOS→series "example past roles" Quarterly OK
"What's open for me this week?" Not Historic — must be Search

Suggested WW schedule: daily or weekly delta by StartPositionCloseDate / open-date windows; store positionOpeningStatus; UI never promotes an "Accepting" Historic row to applyable.

Same pattern as an ATS/LinkedIn connection — never block first-run on it (kills GTM "value after install"). A 3-step wizard: open the USAJOBS developer API request form → fill the 6 fields (we suggest the "use description" text) → paste the key from email into WorkWingman. First Search run uses the user's confirmed skills/series/location + HiringPath metadata chips (never sort keys — WW-74/WW-79 Kerr rule). Deep-link out via ApplyURI/PositionURI; WW never Submits, never touches login.gov.

Card title: Connect USAJOBS (free API key)

Body:

To show open, applyable federal jobs, WorkWingman uses the official USAJOBS Search API with your free developer key — same idea as bringing your own data keys elsewhere. USAJOBS asks you to request a key on their site (name, email, phone, organization, a short use description, and their terms). It usually takes a few minutes once the key email arrives. We store the key only in your local vault and call USAJOBS from this machine.

What you get without a key:

You can still explore historical federal announcements for research and practice. Those are not live openings and cannot start an application here.

Suggested form "use description" snippet (≤255 chars):

Personal job search: find open federal roles matching my skills inside the WorkWingman desktop app on my computer; no redistribution.

Do not claim: "instant key," "no signup," or "we'll get the key for you." Do claim: free, official, public JOA data only; Public jobs by default; Status jobs may need extra USAJOBS authorization.

Go/no-go summary for P2

Decision Verdict
JSON-only Search discovery (no Playwright) GO — designed for it
Per-user BYO Search key for DISCOVERY GO — matches BYOK + ToS shape
Historic JOA for live applyable discovery NO-GO (product + missing ApplyURI + weak query surface)
Historic JOA for demo/offline/corpus GO — with non-applyable labeling
Block first-run on USAJOBS key NO-GO — kills GTM "value after install"
Connect-key step like other integrations GO — with honest multi-minute copy

Bottom line for GTM: A veteran should feel value from MOS translation immediately. Live federal openings wait on a ~5–15 minute (if email is fast) free key connect, framed honestly like other integrations — not a dark-pattern wall, and not replaced by Historic "fake open" jobs.

Open questions

# Question Why it matters How to close
Q1 Key email SLA — automated minutes vs human hours/days? Friction estimate floor vs worst case; GTM copy honesty One controlled key request, or email access@usajobs.gov
Q2 Request/min or day limits per key beyond 10k rows/query? Saved-search refresh budget, governor UI Empirical 429/header capture under load
Q3 WhoMayApply=Status/All authorization — how obtained? Veterans often need status/VEOA paths beyond Public Document Status-key path; help-desk note on API Request page
Q4 ToS "requesting company" + derivative works for desktop BYO vs optional WW-hosted cache Whether any server-side Search proxy is allowed Legal read of USAJOBS API ToS; default client-side BYO only
Q5 Should constructable GetJob/ViewDetails/{controlNumber} ever be used from Historic "Accepting" rows? Tempting loophole for zero-key discovery Recommend No for apply CTAs; optional "View on USAJOBS (verify status)" with strong offline labeling only after product review
Q6 Historic full-corpus size / refresh cost (~3.2M rows × pages of 500) Ops disk, first-sync time, CI fixtures Sample strategy: series+agency slices + date windows; not full 3.2M on day one
Q7 Announcement Text volume for corpus enrichment Storage vs value for federal-résumé practice Enrich on demand by control number, not full dump

Evidence appendix

Official docs (fetched 2026-07-24)

Live probes (this session, 2026-07-24)

Call Result
GET /api/search no headers 401
GET /api/search fake Authorization-Key 401
GET /api/historicjoa 200, totalCount 3,187,813, pageSize 500
Historic series 2210 closed Jan 2024 Statuses: Candidate selected / canceled / under review / closed; no ApplyURI
Historic open-date last 7 days Includes "Accepting applications" rows
GET /api/codelist/positionopeningstatuses Codes: Accepting applications, Job closed, Reviewing applications, Job canceled, Hiring complete
AnnouncementText by control number 200, long HTML text, no auth

In-repo context

  • docs/technical/veteran-vertical-design.md — P2 BYO Search; Phase-2 spikes WW-78..83
  • docs/technical/integration-keys.md — vault BYOK pattern for a new USAJOBS row
  • docs/technical/ww82-federal-apply-path-reality.md — apply = login.gov deep-link out only

Jira WING-78 · Vikunja · BOARD.md