Pick a job's resume again, make a draft, or take the proposed one
const url = 'http://127.0.0.1:8765/api/job-resumes/pick';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"action":"refresh","job_url":"https://boards.greenhouse.io/acme/jobs/101"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url http://127.0.0.1:8765/api/job-resumes/pick \ --header 'Content-Type: application/json' \ --data '{ "action": "refresh", "job_url": "https://boards.greenhouse.io/acme/jobs/101" }'Take one explicit step on a job’s resume: pick again, make a draft, or take or drop the proposed one. No model call in any form, and no page is counted: a pick holds its best lines, at most 20 bullets (picked.max_bullets), and the page is fitted by the spacing of POST /api/tailored-resumes/preview, never by the pick (picked.pages is null; a resume that prints on 3 pages is still ready). refresh picks again in code from the STORED assessment against the master as it is now; while that assessment is stale it answers 409 assessment_stale (a new selection never sits beside scores made on other evidence: re-assess with POST /api/assess). draft makes a draft for a job whose gate holds (409 draft_not_needed when a resume is suggested already). shorten is RETIRED in 0.1.11.5 (a pick has no page budget to tighten): it always answers 409 shorten_retired with one plain sentence (move the spacing slider of the preview, or remove a point with PUT /api/tailored-resumes/selection) and reads and writes nothing. A stored resume that is the user’s (edited, attached, a line choice, or made by the 0.1.10 tailoring; resume.replaceable false) is never replaced by any of them: the new selection waits as proposed, use_proposed is the one step that replaces the job resume and dismiss_proposed drops the proposal (404 no_proposed_resume when none waits). use_proposed takes a proposal only over the resume it was made beside: when the stored resume changed after the proposal was made it answers 409 proposal_stale and replaces nothing, and an edit of the stored resume drops the waiting proposal itself. A stored resume file that cannot be read is the user’s and is never written over: resume is null with resume_unreadable true, and refresh, draft and use_proposed answer 409 stored_resume_unreadable. The answer is what is stored after the step: the job resume (made_by is its producer, counts its Picked / Left out), who picked it (picked), what validation found (problems) and code added (added_by_code), the gate, the stale list (assessment_stale:<reason>, picked_line_changed, master_newer, selection_rules_changed, assessment_newer; stale_lines names the printed lines behind picked_line_changed) and the conflicts. basis is what a resume for this job is made from now (master, or profile_resume: nothing is picked, 409 no_master without a master and 409 profile_resume_in_use for a profile whose resume was put in by hand; master_stored tells them apart). A plain refresh of a job whose gate holds is 409 resume_held (make a draft); a pick that fails is 409 pick_failed. Every refusal’s message is for the user: what to do, in plain words.
Request Bodyrequired
Section titled “Request Bodyrequired”object
The step.
The posting’s link: the ONE job.
Optional and picks nothing (0.1.11.9: a job has one assessment, one suggestion record and one resume, whichever role asked).
Example
{ "action": "refresh", "job_url": "https://boards.greenhouse.io/acme/jobs/101"}Responses
Section titled “Responses”Success.
object
Example
{ "action": "refresh", "added_by_code": [], "basis": "master", "conflicts": [], "gate": { "decision": "suggest", "ready": true, "reasons": [] }, "job_identity": "https://boards.greenhouse.io/acme/jobs/101", "master_education": true, "master_stored": true, "picked": { "draft": false, "fallback": null, "made_at": "2026-10-05T10:07:00Z", "max_bullets": 20, "max_pages": 2, "pages": null, "pick_rules_version": "pick-rules:1", "picked_by": "model", "selector_version": "sel-7" }, "problems": [], "profile_id": "prof_1", "proposed": null, "resume": { "counts": { "cut_for_length": 0, "left_out": 30, "picked": 28 }, "edited": null, "folder_path": "~/Documents/GigAI/resumes/acme-software-engineer-2026-10-05.md", "lines": 41, "made_by": "scout.pick", "markdown": "## Summary\n\n- ...", "replaceable": true, "updated_at": "2026-10-05T10:07:00Z" }, "resume_unreadable": false, "schema_version": "scout-job-resume-pick:1", "selection_error": null, "stale": [], "stale_lines": [], "verdict": "matched_above_threshold"}Forbidden / forbidden_origin: loopback peer and Host 127.0.0.1:<port> or localhost:<port> only (Origin too on writes).
object
object
Examplegenerated
{ "error": { "allowed_keys": [ "example" ], "code": "example", "message": "example" }}Assessment_missing, no_proposed_resume, profile_not_found, target_unavailable
object
object
Example
{ "error": { "code": "assessment_missing", "message": "..." }}Proposal_stale, stored_resume_unreadable, assessment_stale, draft_not_needed, pages_unmeasured, no_master, profile_resume_in_use, resume_held, pick_failed, shorten_retired
object
object
Example
{ "error": { "code": "proposal_stale", "message": "..." }}Unsupported_media_type: writes need Content-Type: application/json.
object
object
Examplegenerated
{ "error": { "allowed_keys": [ "example" ], "code": "example", "message": "example" }}Unknown_key, wrong_type, invalid_value
object
object
Example
{ "error": { "code": "unknown_key", "message": "..." }}Pick_not_available
object
object
Example
{ "error": { "code": "pick_not_available", "message": "..." }}