jobs.read searches the open listings. A company with jobs.write publishes its own. A pilot app with a grant that holds jobs.match asks which open jobs fit that pilot.
Search the open jobs
page_size goes up to 50. GET /v1/partner/jobs/{job_id} reads one listing; a listing that is not active answers 404 not_found.
Publish a job
MyPilotIndex binds your partner to your company, and the job is published in that company’s name. Without the binding the answer is403 forbidden with reason partner_not_bound.
title and position_type are required. status is active, which goes live at once, or draft, which nobody reads until a change makes it active. The API reference lists every field; a member outside that list, such as company_id or featured, answers 400 invalid_request.
client_ref works as it does for publishing: a retry with the same body answers 200 with replayed: true and publishes nothing. A partner publishes at most 50 jobs in 24 hours; past that the answer is 429 rate_limited with reason publication_throttled and Retry-After.
Change or close a job
PATCH /v1/partner/jobs/{job_id} changes the members you send and answers the job. POST /v1/partner/jobs/{job_id}/close archives it, and closing a closed job answers 200.
You change only the jobs you created, for the company you are bound to. Anything else answers 404 not_found, exactly like a job that does not exist.
Moving a closed job back to active reopens it for 30 more days, unless you send your own expires_at.
Show a pilot the jobs that fit
limit goes up to 20.
The match is the one the pilot sees on MyPilotIndex, under the pilot’s own plan. A free pilot’s match carries overall, matchLabel and detail: "plan_required". A paying pilot’s replaces detail with breakdown and missingRequirements. match is null for a job the engine does not score, such as one for mechanics, and those jobs come last.
