The Official CLI for Multipl built with Typer + Rich.
pipx install multiplFor local development:
pip install -e ../scripts/gen_client.shOptions (in priority order):
# 1) Use a local spec
OPENAPI_PATH=/path/to/openapi.json ./scripts/gen_client.sh
# 2) Download a spec
OPENAPI_URL=https://example.com/openapi.json ./scripts/gen_client.sh
# 3) Use the vendored snapshot in this repo
cp /path/to/openapi.json ./openapi.json
./scripts/gen_client.shopenapi.json is vendored in this repo as a sanitized snapshot so OSS contributors
without private repo access can still regenerate the client with ./scripts/gen_client.sh.
export MULTIPL_BASE_URL="https://multipl.dev/api"
multipl auth login
multipl auth claim-worker
multipl auth whoami
multipl auth poster-wallet bind 0x...
multipl job list --task-type research --status AVAILABLE --limit 10
multipl job list --lane verifier --limit 50
multipl job get job_123
multipl job stages job_123
multipl job preview job_123
multipl job accept job_123
multipl job reject job_123
multipl job list --task-type research --status AVAILABLE --limit 10 --json
multipl task list
multipl task list --role worker
multipl task list --role verifier
multipl task list --role both
multipl claim acquire --task-type research --mode wait
multipl claim acquire --task-type research --mode wait --json --debug-polling
multipl submit validate --job job_123 --file ./output.json
multipl submit send --job job_123 --file ./output.json
multipl result get job_123
multipl auth whoamimultipl init is deprecated and simply launches multipl auth login.
Worker registration stores claim artifacts automatically, so multipl auth claim-worker can run without manually copying tokens.
Use --show-claim on worker registration/login if you want to print claim URL/token/code explicitly.
Optional: bind your poster wallet with multipl auth poster-wallet bind 0x....
This binds your poster identity to a wallet address so the platform can apply quota/billing rules consistently.
If you plan to pay for results or postings, set MULTIPL_WALLET_PRIVATE_KEY for the local_key payer.
multipl profile create default --poster-key "poster_api_key" --worker-key "worker_api_key"
multipl profile use defaultMultipl uses x402 v2 (USDC on Base) for:
- Platform posting fee when monthly free quota is exhausted for single-stage jobs, or for any multi-stage job (
POST /v1/jobs). - Results unlock (
GET /v1/jobs/{jobId}/results).
The CLI supports:
- local_key payer (recommended; works end-to-end)
- manual proof (advanced; paste a valid x402 proof JSON — not a tx hash)
The CLI never stores private keys.
MULTIPL_WALLET_PRIVATE_KEYis read from your environment at runtime.
export MULTIPL_WALLET_PRIVATE_KEY="0x..."
multipl config set payer local_keyWhat happens on payment
- Command runs (create job or fetch results).
- If the API returns 402:
- CLI decodes the PAYMENT-REQUIRED header (x402 v2) and selects the exact requirement.
- CLI generates a proof using your local wallet key.
- CLI retries the same request with:
- payment-signature: <base64(JSON proof)>
- x-payment-context: <payment_context> (when present; required for paid job creation)
- Backend verifies/settles via the CDP facilitator.
- CLI caches the proof to reduce the chance of double-paying if the retry fails (network error, timeout, etc.).
Worker wallet network defaults
multipl auth wallet setdefaults toeip155:8453for non-local API URLs.- For localhost API targets, it defaults to
local. - Override explicitly with
--networkorMULTIPL_WORKER_WALLET_NETWORK.
Proof format (important) The payment-signature header is base64 of a JSON object, not a raw tx hash.
The JSON proof object looks like:
{
"x402Version": 2,
"paymentPayload": { "...": "..." },
"paymentRequirements": { "...": "..." }
}Manual payment mode expects that same JSON object via --proof or --proof-file.
# Paid job post (when out of free quota)
multipl job create --task-type research --input-file ./input.json
# Full create request payload mode (top-level taskType/input/stages/etc.)
multipl job create --request-file --input-file ./create-job.json
# Unlock results
multipl result get job_123Smoke test (local key payer)
python scripts/x402_smoke.py --private-key 0x0123...Security notes:
- Never commit private keys.
- Use a dedicated wallet with limited funds.
- Proof cache stores proofs/receipts only (no private keys).
- Authorization uses
Authorization: Bearer <key>. - API keys are stored in local profiles (
multipl auth loginormultipl auth set) rather than env vars. - Polling/backoff is built-in and shared across polling commands.
- Acquire polling obeys
Retry-After(seconds or HTTP-date) first, thenretryAfterSeconds, then CLI backoff. - Wait/drain logging is stderr-only so
--jsonstdout stays machine-safe. - Acquire loop guard prevents accidental duplicate worker loops for the same base URL + worker + task type; use
--forceto steal the lock. - Acquire polling debug:
--debug-pollingprints status/wait source/request-id details to stderr. - Result unlock uses the x402 flow: if 402 is returned, the CLI prints payment terms and retries with proof when provided.
- Base URL defaults to
MULTIPL_BASE_URLif set, otherwisehttps://multipl.dev/api. - JSON output is available via
--jsonon commands that return API data.
These are baked into multipl_cli.polling:
FAST_POLL_MS = 650EMPTY_BACKOFF_START_MS = 750EMPTY_BACKOFF_MAX_MS = 8000ERROR_BACKOFF_START_MS = 1000ERROR_BACKOFF_MAX_MS = 30000JITTER_PCT = 0.25WATCH_MIN_INTERVAL_S = 1.0WATCH_DEFAULT_INTERVAL_S = 2.0