> ## Documentation Index
> Fetch the complete documentation index at: https://docs.parallaxprotocol.org/llms.txt
> Use this file to discover all available pages before exploring further.

# API

> Hashwarp's JSON API, Prometheus metrics and JSON-RPC interface.

Hashwarp serves the [dashboard](/hashwarp/dashboard), a JSON API, Prometheus metrics and a JSON-RPC interface on one TCP port, when started with `--api-bind`:

| Option | Meaning |
| - | - |
| `--api-bind address:port` | Listen on this address and port, such as `127.0.0.1:21550` (this computer only) or `0.0.0.0:21550` (every network interface) |
| `--api-token secret` | Require this secret: `Authorization: Bearer secret` on HTTP, `api_authorize` on JSON-RPC |
| `--api-allow-control` | Allow clients to pause, resume and restart the GPUs and to change pools |

Without `--api-allow-control` the API is read only. Control on an address other than `127.0.0.1` requires `--api-token`: anyone able to change pools could send your hashrate elsewhere. The API has no TLS: the token travels in clear text, so use a VPN or an SSH tunnel rather than exposing the port to the internet. Requests from web pages of other sites are refused.

The `--api-port N` option of Hashwarp 1.x and ethminer still works, and listens on `127.0.0.1:N`, read only.

***

## HTTP API

### GET /api/v1/summary

The rig's current state:

```bash theme={null}
curl -s http://127.0.0.1:21550/api/v1/summary
curl -s -H "Authorization: Bearer secret" http://127.0.0.1:21550/api/v1/summary
```

```json theme={null}
{
    "control": false,
    "miner": { "name": "hashwarp", "version": "2.0.0", "algorithm": "xhash", "uptime": 3600 },
    "pool": {
        "connected": true,
        "host": "pool.example.com:3333",
        "url": "stratum+tcp://0xYourParallaxAddress.rig1:***@pool.example.com:3333",
        "difficulty": 4294967296.0,
        "epoch": 83,
        "block": -1,
        "switches": 1,
        "warning": ""
    },
    "hashrate": { "now": 115480000.0, "60s": 115400000.0, "15m": 115210000.0, "effective": 112300000.0 },
    "shares": { "accepted": 42, "rejected": 1, "failed": 0 },
    "gpus": [
        {
            "index": 0,
            "name": "NVIDIA GeForce RTX 4090",
            "pci": "01:00.0",
            "backend": "cu",
            "hashrate": { "now": 115480000.0, "60s": 115400000.0, "15m": 115210000.0 },
            "shares": { "accepted": 42, "rejected": 1, "failed": 0 },
            "paused": false,
            "pause_reason": "",
            "temperature": { "core": 65, "hotspot": 0, "memory": 0 },
            "fan": 70,
            "power": 280.5,
            "power_limit": 450.0,
            "clocks": { "core": 2790, "memory": 10501 }
        }
    ]
}
```

* Hashrates are in hashes per second. `effective` is what the accepted shares of the last 15 minutes are worth, 0 during the first 2 minutes.
* `difficulty` is the expected number of hashes per share.
* `block` is the height being mined, -1 when the pool doesn't send it.
* `warning` is set when the pool finds most of the network's blocks (see [Pool Mining](/hashwarp/pool-mining#pools-with-the-majority)), empty otherwise.
* `failed` counts solutions the CPU check found wrong, which weren't submitted.
* Sensors are 0 when the GPU doesn't report them. `pause_reason` is empty while a GPU mines.
* The pool password is never shown.

### GET /api/v1/rigs

This rig (unless it runs with `--monitor`) and the [`--rig` rigs](/hashwarp/dashboard#all-your-rigs-in-one-dashboard), as the dashboard shows them:

```json theme={null}
{
  "mining": true,
  "rigs": [
    {"name": "rig1", "host": "", "local": true, "online": true, "error": "", "age": 0, "summary": {...}},
    {"name": "rig2", "host": "10.0.0.12:21550", "online": true, "error": "", "age": 3, "summary": {...}},
    {"name": "rig3", "host": "10.0.0.13:21550", "online": false, "error": "Connection refused", "age": 120, "summary": {...}}
  ]
}
```

`summary` is the rig's last `/api/v1/summary`: kept while the rig is unreachable, absent if it never answered. `age` is the seconds since then (-1: never), and `error` why the last attempt failed.

### POST /api/v1/control

Needs `--api-allow-control` (403 otherwise):

```bash theme={null}
curl -s -X POST -H "Content-Type: application/json" -d '{"action":"pause","gpu":1}' http://127.0.0.1:21550/api/v1/control
curl -s -X POST -H "Content-Type: application/json" -d '{"action":"resume"}' http://127.0.0.1:21550/api/v1/control
curl -s -X POST -H "Content-Type: application/json" -d '{"action":"restart"}' http://127.0.0.1:21550/api/v1/control
```

`action` is `pause` or `resume` (one GPU with `gpu`, every GPU without), or `restart` (every GPU: the DAGs are rebuilt, the pool connection stays). The answer is `{"result":true}`, or 400 with the reason.

### Errors

| Status | Meaning |
| - | - |
| 400 | Malformed request or JSON body |
| 401 | Missing or wrong token |
| 403 | Control not allowed, or a request from another site's web page |
| 404 | Unknown path, or a path a `--monitor` instance doesn't serve |
| 405 | Wrong method (GET or POST) |

`GET /getstat1` serves the HTML statistics page of Hashwarp 1.x.

***

## Prometheus

`GET /metrics` serves the metrics in Prometheus' text format:

```yaml theme={null}
scrape_configs:
  - job_name: hashwarp
    static_configs:
      - targets: ["rig1:21550", "rig2:21550"]
    # with --api-token:
    # authorization:
    #   credentials: secret
```

| Metric | Labels | Meaning |
| - | - | - |
| `hashwarp_hashrate` | `window` (`now`, `60s`, `15m`), `gpu`, `name` | Hashes per second, total (no `gpu` label) and per GPU |
| `hashwarp_effective_hashrate` | | What the accepted shares are worth |
| `hashwarp_shares_total` | `result` (`accepted`, `rejected`, `failed`), `gpu`, `name` | Shares |
| `hashwarp_gpu_paused` | `gpu`, `name` | 1 when paused |
| `hashwarp_gpu_temperature_celsius` | `gpu`, `name`, `sensor` (`core`, `hotspot`, `memory`) | Temperatures reported by the GPU |
| `hashwarp_gpu_fan_percent`, `hashwarp_gpu_power_watts`, `hashwarp_gpu_power_limit_watts` | `gpu`, `name` | Fan, power draw and power limit |
| `hashwarp_gpu_clock_mhz` | `gpu`, `name`, `clock` (`core`, `memory`) | Clocks |
| `hashwarp_pool_connected` | `host` | 1 when connected |
| `hashwarp_pool_difficulty_hashes` | | Expected hashes per share |
| `hashwarp_pool_switches_total` | | Pool switches |
| `hashwarp_epoch`, `hashwarp_block_height` | | XHash epoch and height being mined |
| `hashwarp_uptime_seconds`, `hashwarp_info` | `version` | Uptime, and the version as a label |
| `hashwarp_rig_up` | `rig` | With `--rig`: 1 when the rig's API answers |
| `hashwarp_rig_hashrate`, `hashwarp_rig_power_watts` | `rig` | A rig's hashrate and GPU power draw |
| `hashwarp_rig_shares_total` | `rig`, `result` | A rig's shares |

***

## JSON-RPC

The JSON-RPC interface of ethminer and Hashwarp 1.x, which some monitoring tools use, is on the same port. Send JSON-RPC 2.0 requests, one per line:

```bash theme={null}
echo '{"id":1,"jsonrpc":"2.0","method":"miner_ping"}' | nc 127.0.0.1 21550
```

With `--api-token`, send `api_authorize` first on each connection:

```json theme={null}
{"id":0,"jsonrpc":"2.0","method":"api_authorize","params":{"psw":"secret"}}
```

| Method | Params | Control | Result |
| - | - | - | - |
| `miner_ping` | | | `"pong"` |
| `miner_getstat1` | | | Claymore-compatible array: version, uptime (minutes), "total kh/s;accepted;rejected", kh/s per GPU, unused, unused, "temperature;fan" pairs, pool, "failed;switches;0;0" |
| `miner_getstatdetail` | | | Host, connection, mining and per GPU details |
| `miner_getconnections` | | | Pools (`index`, `active`, `uri` with the password masked) |
| `miner_getscramblerinfo` | | | Start nonce and segment width of each GPU |
| `miner_setactiveconnection` | `{"index": n}` or `{"URI": "regex"}` | yes | Switch to that pool |
| `miner_addconnection` | `{"uri": "stratum+tcp://..."}` | yes | Add a pool |
| `miner_removeconnection` | `{"index": n}` | yes | Remove a pool (not the active one) |
| `miner_pausegpu` | `{"index": n, "pause": true}` | yes | Pause or resume a GPU |
| `miner_restart` | | yes | Restart the GPUs (the DAGs are rebuilt, the pool connection stays) |
| `miner_reboot` | | yes | Run `reboot.sh` (`reboot.bat` on Windows) next to the executable, with `api_miner_reboot` as its argument |
| `miner_shuffle` | | yes | Pick a new random start nonce |
| `miner_setscramblerinfo` | `{"noncescrambler": n, "segmentwidth": w}` | yes | Set the start nonce and narrow the segments (10 to 63 bits) |
| `miner_setverbosity` | `{"verbosity": n}` | yes | Debug categories (sum of 1 json, 2 per GPU, 32 connect, 64 switch, 128 submit, 256 flow) |

Methods marked "yes" need `--api-allow-control`. Errors follow JSON-RPC 2.0: `{"error": {"code": ..., "message": ...}}`. A `--monitor` instance has no miner, and closes JSON-RPC connections.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.