External stages
Durable stage jobs with an immutable input snapshot and a claim lease, one per stage in your pipeline.
Each of the three customer-meaningful steps has exactly one executor: prospex or external. Set them on the project's Connect page. The choice is snapshotted when work is created, so changing it affects the next cycle.
External execution uses durable jobs. The webhook announces that a job exists. You read and claim it through the API, then submit a result against the immutable input snapshot.
Stages
| Stage | The job carries | You return |
|---|---|---|
| qualification | The resolved company, the same fit document Prospex would grade, the offering revision, source provenance and your account relationships. | eligibility, fit, priority and readable reasons. |
| research | The confirmed company identity, the offering revision, provenance and the project's constraints. | qualification, identity, sourced facts and the evidence behind each one. |
| outreach | One accepted research revision with its evidence, the exact offering revision, the language, proof points and forbidden formulations. | subject, opener, angle_type, angle_explanation and claims. |
The job
{
"object": "prospect_stage_job",
"id": "stage_job_712",
"stage": "research",
"status": "pending",
"executor": "external",
"project_id": "project_128",
"prospect_id": "prospect_4815",
"cycle_id": "cycle_93",
"input_schema_version": "2026-08-01",
"input_fingerprint": "sha256:…",
"attempt": 1,
"created_at": "…",
"expires_at": "…",
"input": { }
}
Statuses
| Status | Meaning |
|---|---|
| pending | Available to an external worker (still holds the company) |
| claimed | Leased by one credential (still holds the company) |
| submitted | Result waiting for validation (still holds the company) |
| accepted | Result became a Prospect decision |
| rejected | Validation found correctable problems (still holds the company) |
| failed | The external worker could not complete it |
| expired | No acceptable result before the deadline |
| cancelled | Cancelled by the customer |
A claim lease lasts 15 minutes and can be extended by claiming again. A job's own deadline is 24 hours. rejected counts as open: a corrected result is welcome until the deadline.
Submitting
Claim before you submit. A result is accepted only from the credential holding a live lease on that job, so a submission against a job you have not claimed answers 409 job_not_claimed and one arriving after your lease lapsed answers 409 lease_expired. Both are fixed by claiming again.
POST /api/v1/prospect/projects/<project>/stage-jobs/<job>/results
Idempotency-Key: your-run-id
{
"stage_job_id": "stage_job_712",
"input_fingerprint": "sha256:…",
"result_schema_version": "2026-08-01",
"external_tool": "your-worker",
"external_run_id": "run_892",
"result": { }
}
- A rejected submission answers
422with categorical errors and mutates nothing. Correct it and submit again against the same job. - A result is refused when the fingerprint is stale, the offering or research revision it was built on has moved, the job has reached a terminal state, or a reference does not resolve.
Timing and fallback
A cycle does not wait for you. Dispatching a job completes the cycle's work for that step, and the cycle finishes with an external-pending count. The job stays open on its own clock, and the company is held out of later cycles for that step while it does.
There is no fallback. A failed, expired, cancelled or unclaimed job never starts the Prospex step instead. Retry the job explicitly, or change the executor on the Connect page and ask for new work.