Rank the postings now, or re-rank the latest 100
const url = 'http://127.0.0.1:8765/api/postings/rank';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"mode":"latest"}'};
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/postings/rank \ --header 'Content-Type: application/json' \ --data '{ "mode": "latest" }'Rank now, or re-rank the latest 100: ask first (the calls), rank on approval. The ranking the Jobs page shows and starts; the same lane as gigai scout pipeline rank and the background rank, with its rules: one model call ranks up to 50 postings of one profile, every call is taken from the one daily allowance (calls_today: 100 a day for all profiles), live work (a sources update, an assess batch, a run) is yielded to, and the off switch is respected. Nothing is ranked without approve: true. {} reads the state and starts nothing: enabled (false: ranking is off, how_to_enable says how to turn it on, and an approval answers 409 rank_disabled), calls_today, ranking (as GET /api/postings: per active profile ranked of total, the ranked postings plus the unranked ones of the last window_days days, and stale_resume) and job (the rank job of this server: {job_id, mode, state: running | done, postings, planned_calls, calls, ranked, outcome, reason, retry_at, warning, started_at, finished_at}, null when none was started; outcome is the lane’s last state: ran, idle, waiting (the day’s calls are used up), yielded, busy_elsewhere (the background rank holds the lane), unavailable or disabled). With a mode and no approval the answer also has plan, THE COST BEFORE ANYTHING RUNS: postings and calls (the model calls it would make), per profile in by_profile, calls_left_today, allowed and, when it may not run, refusal (rank_disabled, rank_daily_cap or nothing_to_rank). No model call is made. mode: unranked ranks every in-window posting with no score, 50 a call, until none is left or the day’s calls are used up. mode: latest ranks the newest 100 in-window postings AGAIN, whether they have a score or not, in at most 2 calls (plan.max_calls); with several profiles a call ranks one profile’s postings, so the 2 calls hold the newest that fit. It is all or nothing against the day’s allowance: when it needs more calls than are left, an approval answers 409 rank_daily_cap and no call is made. With approve: true the job starts and the answer is 202 at once (started: true, job); it never waits for the model. A second approval while a job runs joins it (200, started: false, the running job). With nothing to rank the answer is 200, started: false and plan.refusal nothing_to_rank. Read the progress with {} and with GET /api/postings (ranking, and the rows’ rank_score): the rows get their scores after each turn of 2 calls. System data only: ids, counts and codes; no posting, resume or answer text.
Request Body
Section titled “Request Body”object
True: start ranking (model calls). Left out or false: only ask.
Unranked (“Rank now”: the postings of the last 7 days with no rank score) or latest (“Re-rank latest 100”: the newest 100 of them, ranked again). Left out: only the state is read.
Example
{ "mode": "latest"}Responses
Section titled “Responses”Success.
object
Example
{ "calls_today": { "day": "2026-10-06", "limit": 100, "reached": false, "used": 2, "warn_at": 60, "warning": false }, "enabled": true, "how_to_enable": null, "job": null, "plan": { "allowed": true, "batch_size": 50, "by_profile": [ { "calls": 2, "postings": 57, "profile_id": "prof_1" } ], "calls": 2, "calls_left_today": 98, "max_calls": 2, "mode": "latest", "postings": 57, "refusal": null, "window_days": 7 }, "ranking": { "by_profile": [ { "profile_id": "prof_1", "ranked": 57, "stale_resume": false, "total": 57 } ], "enabled": true, "in_progress": false, "stale_resume": false, "window_days": 7 }, "schema_version": "scout-rank-now:1", "source": "default", "started": false}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" }}Target_unavailable
object
object
Example
{ "error": { "code": "target_unavailable", "message": "..." }}Rank_disabled, rank_daily_cap, config_unavailable
object
object
Example
{ "error": { "code": "rank_disabled", "message": "..." }}Unsupported_media_type: writes need Content-Type: application/json.
object
object
Examplegenerated
{ "error": { "allowed_keys": [ "example" ], "code": "example", "message": "example" }}Invalid_value, wrong_type, unknown_key
object
object
Example
{ "error": { "code": "invalid_value", "message": "..." }}