Jobs & CPU workers API

Validate immutable JSONL inputs, manage owned CPU workers and control fenced jobs.

Jobs, attempts and validation reports

The version 1 job contract uses snake_case fields and integer epoch milliseconds. A job has an immutable specification and input digest, a stable source reference, an explicit state and revision, actual work units and fenced attempts, and immutable artifact metadata. Native corpus jobs retain their native phase; their miner work units and attempts are not yet exposed by this read adapter.

The first common executable workload is dataset_validation: bounded instruction, preference or corpus JSONL up to 32 KiB. Upload a private input, review its reference and submit the specification explicitly. Validation produces a canonical report with row counts and error codes; malformed input produces an invalid report, not an approved training dataset. The server independently verifies the worker report against the immutable bytes.

Use resources:read keys for owned CPU job reads and resources:write keys for CPU job, input and worker mutations. Submission and worker execution also require active dataset or training approval. Browser routes use the existing session and XSRF transport. API keys cannot read or control native operator jobs; those browser operations retain fresh administrator wallet authorization.

Create and control requests use a UUID Idempotency-Key. Controls also require the reviewed revision in the body and X-Resource-Revision. An ambiguous response requires reconciliation or an explicit retry using the original key. Pause holds new admissions; active CPU attempts can finish, cancellation drains the current attempt, and expired leases retry only within the original deadline and attempt bound.

Job, input and worker management share per-owner budgets across browser sessions and API keys: 240 reads and 120 writes per minute. A 429 response includes Retry-After; wait before reconciling or retrying the original request. Internal fenced worker execution uses its separate credential boundary.

Capabilities report submission availability, owner-scoped backlog and live versus server-verified workers. Enrollment or a heartbeat alone does not qualify capacity. CPU jobs have no incentive or billing charge; this contract does not enable GPU capacity, generation ordering or training execution.

Use the existing authenticated transport

import { createJobsClient } from '@reliquary/api/jobs';

const jobs = createJobsClient(request, { audience: 'key' });
const capabilities = await jobs.capabilities();
const page = await jobs.list({ limit: 25 });
// Review immutable input and specification before jobs.create(...).
// Keep worker credentials private; never place them in browser code.
Key routePurpose
GET /api/v1/jobs/capabilitiesAvailable workloads, controls, owner backlog and worker freshness.
POST /api/v1/job-inputsImport bounded immutable JSONL input without adding it to the training library.
GET, POST /api/v1/jobsCursor job history and explicit CPU validation submission.
GET /api/v1/jobs/:idOwned immutable specification, actual attempts and artifact metadata.
GET /api/v1/jobs/:id/eventsAppend-only state events with cursor pagination.
POST /api/v1/jobs/:id/pause|resume|cancelRevision-bound admission or drainage control.
GET /api/v1/jobs/:id/artifacts/:artifactIdOwned metadata and validation report with digest verification.
GET, POST /api/v1/job-workersList or enroll up to eight owner-scoped CPU workers; token returned once.
POST /api/v1/job-workers/:id/revokeRevoke a CPU worker credential and fence its execution.

Jobs OpenAPI contract — Download the contract shipped with this application build.

Run a CPU validation with HTTP

This example uses curl and jq with an existing resources:write key, an active dataset or training grant and available CPU workers. Set and retain two distinct UUIDs as INPUT_REQUEST_KEY and JOB_REQUEST_KEY before running. Keep the files and keys to reconcile any uncertain upload or submission; send each mutation once.

The example polls at most 30 times, waits three seconds between reads and limits each HTTP request to 15 seconds. It verifies the delivered report digest. Reaching the read limit leaves the original job running; inspect its saved ID rather than creating another job. CPU validation verifies format, not dataset quality or training gains.

Upload, submit, poll and verify an owned report

set -eu
: "${JOBS_API_KEY:?}" "${INPUT_REQUEST_KEY:?}" "${JOB_REQUEST_KEY:?}"
API=https://api.reliqua.ai
jq -n '{schema_version:1,format:"instruction",content:"{\"prompt\":\"One plus one?\",\"response\":\"Two.\"}\n"}' > upload.json
curl --fail-with-body -sS --max-time 15 "$API/api/v1/job-inputs" \
  -H "Authorization: Bearer $JOBS_API_KEY" -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $INPUT_REQUEST_KEY" --data-binary @upload.json > input.json
jq -n --slurpfile receipt input.json '{schema_version:1,spec:{kind:"dataset_validation",input:$receipt[0].input,limits:{deadline_seconds:300,max_attempts:2}}}' > spec.json
curl --fail-with-body -sS --max-time 15 "$API/api/v1/jobs" \
  -H "Authorization: Bearer $JOBS_API_KEY" -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $JOB_REQUEST_KEY" --data-binary @spec.json > job.json
JOB=$(jq -er '.job.id | @uri' job.json)
for attempt in $(seq 1 30); do
  curl --fail-with-body -sS --max-time 15 "$API/api/v1/jobs/$JOB" \
    -H "Authorization: Bearer $JOBS_API_KEY" > status.json
  STATE=$(jq -er '.job.state' status.json)
  case "$STATE" in succeeded|failed|cancelled) break ;; esac
  sleep 3
done
ARTIFACT=$(jq -er '.job | select(.state == "succeeded") | .artifacts[] | select(.kind == "validation_report") | .id | @uri' status.json)
curl --fail-with-body -sS --max-time 15 "$API/api/v1/jobs/$JOB/artifacts/$ARTIFACT" \
  -H "Authorization: Bearer $JOBS_API_KEY" > result.json
jq -cj '.report' result.json > report.json
test "$(shasum -a 256 report.json | cut -d ' ' -f1)" = "$(jq -er '.artifact.sha256' result.json)"
jq -e '.report.valid' result.json

Pagination, revisions and credentials

GET jobs and job events accept limit from 1 to 100 (default 25) and an opaque cursor. Continue with next_cursor until it is null. Do not construct, decode or reuse a cursor for a different query. Other product lists use different contracts.

CPU control revisions are decimal strings. Supply the same reviewed revision in the JSON body and X-Resource-Revision; a mismatched or changed revision is a conflict. This differs from numeric saved-resource revisions.

A worker enrollment uses a UUID Idempotency-Key and a lifetime from 300 to 86,400 seconds. Up to eight owner-scoped workers may be enrolled. The initial token is returned once; an idempotent replay returns token: null. Keep it server-side. Revocation prevents further use; it does not delete an existing result.

The application ships @reliquary/api 0.3.3 with Jobs OpenAPI info.version 0.2.0. Its browserSession scheme names the managed HTTPS __Host-reliquary_session cookie. Use the existing same-origin session transport and XSRF protection; do not manufacture cookies.