pikeway run
Call an endpoint and get its output. Runs synchronously by default, or in the background with --async / --wait.
Synopsis
pikeway run -p <provider> -e <endpoint> [-m <method>]
[-i '<json>' | -i @input.json | -i -] [-o <file>]
[--async [--timeout <s>] | --wait [--timeout <s>]]
[--json] [--key pk-...]Description
Sends the call to POST /v1/run, which checks your input against the endpoint's schema, calls the upstream API, charges your balance and returns the result. You are charged only when the upstream call succeeds.
The status line (status, upstream HTTP code, cost, duration, run id) goes to stderr and the output to stdout, so pikeway run … | jq sees only the output. String outputs are printed as-is; JSON is pretty-printed.
The command exits 1 whenever the run's status is not COMPLETED (for example FAILED, STOPPED or TIMED_OUT), even though the output (for a failed call, the upstream's error body) is still printed.
--async. For those, use --wait (or --async and then pikeway runs get).Options
--provider, -pstringrequired--endpoint, -estringrequired--method, -mstring--input, -iJSON | @file | ---output, -opath--asyncboolean--waitbooleanGET /v1/runs/<id> every 0.5 s, doubling up to 8 s, until it finishes; prints the final run like a synchronous call. Needs a key.--timeoutseconds--async / --wait: how long the run may take. Server default 300, max 900. Ignored for synchronous runs.Input
Either split the input by location, or pass a flat object and let the gateway place each field (path parameter, query parameter, or body) using the endpoint's schema. pikeway inspect shows which fields exist and prints a working example.
{ "pathParams": { "protocol": "aave" }, "queryParams": { "limit": 10 }, "body": { "range": "30d" } }{ "address": "So11111111111111111111111111111111111111112" }Examples
# inline JSON
pikeway run -p birdeye -e /defi/price -i '{"address":"So11111111111111111111111111111111111111112"}'
# input from a file, output to a file
pikeway run -p birdeye -e /defi/price -i @input.json -o out.json
# input from stdin
echo '{"address":"So11111111111111111111111111111111111111112"}' | pikeway run -p birdeye -e /defi/price -i -
# path parameter + pipe the output
pikeway run -p defillama -e /tvl/aave | jq .
# long job: start in the background and wait for it (up to 10 minutes)
pikeway run -p someapi -e /reports -m POST -i '{"body":{"range":"30d"}}' --wait --timeout 600
# fire and forget, check later with pikeway runs get
pikeway run -p someapi -e /reports -m POST -i '{"body":{"range":"90d"}}' --async
# use a specific key for this call only
pikeway run -p coingecko -e /simple/price -i '{"ids":"bitcoin","vs_currencies":"usd"}' -k pk-...Output
COMPLETED · HTTP 200 · cost $0.001 · 214ms · run 0192f6b0-5e2a-7d40-b1c3-8f9e2a4d6c11
{
"success": true,
"data": { "value": 172.41, "updateUnixTime": 1761297120 }
}The first line is on stderr. With -o the output goes to the file and stderr gets output written to out.json instead. A failed upstream call looks like this (exit 1, cost $0):
FAILED · HTTP 400 · cost $0 · 188ms · run 0192f6af-11c4-7a0e-9b52-3d7e8f1a2c64
{
"success": false,
"message": "address is invalid"
}QUEUED · run run_5f0c2b7e9a4d4e1b8c3a6f2d1e0b9a87 · timeout 300s check: pikeway runs get -r run_5f0c2b7e9a4d4e1b8c3a6f2d1e0b9a87 stop: pikeway runs stop -r run_5f0c2b7e9a4d4e1b8c3a6f2d1e0b9a87
running…
COMPLETED · HTTP 200 · cost $0.01 · 41250ms · run run_5f0c2b7e9a4d4e1b8c3a6f2d1e0b9a87
{
"range": "30d",
"rows": 1240,
"url": "https://…/report.csv"
}While waiting, a queued… / running… progress line is rewritten on stderr.
--json
The full run object, same as /v1/run. With --async it's the 202 body (runId, status: "QUEUED", timeoutSeconds, pollUrl); with --wait, the final GET /v1/runs/<id> body.
{
"runId": "0192f6b0-5e2a-7d40-b1c3-8f9e2a4d6c11",
"provider": "birdeye",
"endpoint": "/defi/price",
"method": "GET",
"status": "COMPLETED",
"output": { "success": true, "data": { "value": 172.41, "updateUnixTime": 1761297120 } },
"providerResponse": { "httpStatus": 200, "contentType": "application/json", "cache": "" },
"price": { "type": "PER_CALL", "amount": { "value": 0.001, "currency": "USD" } },
"cost": { "value": 0.001, "currency": "USD" },
"durationMs": 214,
"hints": { "get": "curl -s https://gw.pikeway.ai/v1/runs/0192f6b0-… -H 'Authorization: Bearer $PIKEWAY_API_KEY'" }
}Errors and exit codes
| Exit | Message | When |
|---|---|---|
| 2 | missing --provider · missing --endpoint | A required flag was not given. |
| 2 | --input must be JSON (or @file.json, or - for stdin) | -i could not be parsed as JSON. |
| 2 | cannot read input.json: ENOENT | The file after @ doesn't exist or can't be read. |
| 3 | no API key: run `pikeway keys add --label main --key pk-...`, set PIKEWAY_API_KEY, or pass --key | No --key, no PIKEWAY_API_KEY and no saved active key. Checked before any request is sent. |
| 3 | invalid or revoked API key — add a key with `pikeway keys add --label main --key pk-...` (or use --x402) | The gateway answered 401 (unknown, revoked or expired key). A 403 also exits with 3. |
| 1 | missing required input | A required path or query parameter is missing. With --json, details.missing names it and details.input has the schema. |
| 1 | insufficient balance — top up your balance, or pay per call with --x402 | Your balance (or the key budget) is below the price of the call. |
| 1 | unknown endpoint /price on birdeye | No such provider or path. |
| 1 | FAILED · HTTP 400 · … | The run finished with a status other than COMPLETED. Nothing is charged for a failed upstream call. |
| 1 | cannot reach <gateway>: ECONNREFUSED | The gateway could not be reached (DNS, network, wrong PIKEWAY_API_BASE_URL). The code after the colon comes from Node. |
pikeway runs get can show the status and cost but not the output. Use -o when you need to keep it.