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

# API reference overview

> Base URL, authentication, rate limits, error envelope, and endpoint index for the peaqOS MCR API.

The peaqOS MCR API is a read-only HTTP/JSON service that exposes Machine Credit Ratings, machine profiles, operator fleet data, NFT metadata, and Machine Cards. All data originates from on-chain contracts on peaq chain. The API does not perform writes; write operations happen via the [peaqOS SDK](/peaqos/sdk-reference/sdk-js) and smart contracts.

## Quick start

Pick the setup that matches your workflow: an AI-driven flow via the peaqOS skill, or direct HTTP calls.

<Tabs>
  <Tab title="Agent skill">
    ```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
    pip install peaq-os-cli
    npx skills add peaqnetwork/peaq-os-skills
    ```

    Auto-detects Claude Code, Cursor, or Windsurf. Then invoke `/peaqos` in Claude Code and ask for an MCR score, machine profile, or operator fleet — the skill picks the right CLI command and the CLI hits this API for you. To target a specific runtime, add `--agent claude-code | cursor | windsurf` — see the [peaqOS AI page](/peaqos/peaqos-ai).
  </Tab>

  <Tab title="cURL">
    ```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
    curl https://mcr.peaq.xyz/mcr/did:peaq:0xabc123...
    ```

    Endpoint index below. No API key required: MCR data is public.
  </Tab>

  <Tab title="ROS 2">
    ```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
    ros2 service call /peaqos_node/mcr/query \
      peaq_ros2_interfaces/srv/PeaqosQueryMcr \
      "{did: 'did:peaq:<MACHINE_EVM_ADDRESS>'}"
    ```

    `peaq_ros2_peaqos` exposes the MCR API as ROS 2 services. Full reference on [SDK: ROS 2](/peaqos/sdk-reference/ros2/overview); MCR-specific services are listed under [Services → MCR queries](/peaqos/sdk-reference/ros2/services#mcr-queries).
  </Tab>
</Tabs>

## Base URL

Set the environment variable `PEAQOS_MCR_API_URL` to the root of the MCR API server:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
export PEAQOS_MCR_API_URL=https://mcr.peaq.xyz
```

For local development against a self-hosted server, use `http://127.0.0.1:8000`.

All endpoint paths in this reference are relative to that base URL.

## Authentication

The MCR API is a **public read API**. No API keys, tokens, or signatures are required. MCR scores, machine profiles, and metadata are public on-chain data.

## Rate limits

The API enforces a limit of **90 requests per minute per IP address**. Requests that exceed the limit receive a `429 Too Many Requests` response. For production deployments with multiple workers, the rate limiter backend can be swapped to Redis.

## Server configuration

When self-hosting the MCR API, these environment variables tune caching, storage, and test-mode behavior. Typical deployments only need the contract addresses and RPC; the rest have sensible defaults.

| Variable                    | Default                 | Purpose                                                                                                                                                                                                                                                                               |
| :-------------------------- | :---------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `IDENTITY_REGISTRY_ADDRESS` | n/a                     | Primary contract address. When empty, the server boots in test mode: `/ready` returns 503 with `rpc_connected: false` and all `contracts.*` (including `admin_flags`) reported as `false`.                                                                                            |
| `ADMIN_FLAGS_ADDRESS`       | n/a                     | Optional `AdminFlags` contract. Influences MCR responses via `negative_flag` and admin trust overrides. When the service is initialised but this address is unset, `contracts.admin_flags` on `/ready` is **`true`**: the probe skips the optional check and the service stays ready. |
| `MCR_CACHE_TTL`             | `3600`                  | MCR response cache TTL in seconds. Set to `0` to disable caching entirely.                                                                                                                                                                                                            |
| `EVENT_STORE_DB_PATH`       | `/tmp/peaqos_events.db` | SQLite path for the delta-sync event cache. Must resolve under `/tmp`, `/data`, or `/var/lib/peaqos`.                                                                                                                                                                                 |
| `SKIP_PROVISIONED_GATE`     | `false`                 | Dev/demo toggle that short-circuits the "must be bonded" gate on scoring. **Never enable in production.**                                                                                                                                                                             |

## Error envelope

Every error response uses the same JSON shape:

```json theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
{
  "detail": "<human-readable message>"
}
```

The `detail` string describes the cause. Common values:

| `detail` value                      | Meaning                                                      |
| :---------------------------------- | :----------------------------------------------------------- |
| `"Service not initialised"`         | Server started without contract addresses (test mode)        |
| `"Chain unavailable"`               | RPC call to the node or a contract failed                    |
| `"Empty DID"`                       | DID path parameter is empty                                  |
| `"Invalid Ethereum address format"` | DID or address does not match `^0x[a-fA-F0-9]{40}$`          |
| `"Machine DID not found"`           | DID address has no `machineId` attribute in the DID registry |
| `"Machine not registered"`          | Machine ID is not present in the IdentityRegistry contract   |
| `"Machine not found"`               | Machine ID does not exist (machines endpoint)                |
| `"Machine wallet not found"`        | Machine wallet is the zero address                           |
| `"Token not found"`                 | NFT token ID does not map to any machine in MachineNFT       |
| `"Internal server error"`           | Unhandled exception (logged server-side)                     |

## Status codes

| Code                        | Meaning                                                                                                                    |
| :-------------------------- | :------------------------------------------------------------------------------------------------------------------------- |
| `200 OK`                    | Request succeeded; JSON body returned                                                                                      |
| `400 Bad Request`           | DID is empty or the address does not match `^0x[a-fA-F0-9]{40}$`                                                           |
| `404 Not Found`             | The requested DID, machine ID, or token ID does not exist on-chain                                                         |
| `422 Unprocessable Entity`  | Path or query parameter failed validation (FastAPI auto-generated)                                                         |
| `429 Too Many Requests`     | Rate limit exceeded. Responses include slowapi headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`) |
| `500 Internal Server Error` | Unhandled server exception                                                                                                 |
| `503 Service Unavailable`   | Service not initialised or chain/RPC call failed                                                                           |

## DID format

Endpoints that accept a DID path parameter support two formats:

* Full DID: `did:peaq:0xabc123...`
* Raw address: `0xabc123...`

The server strips the `did:peaq:` prefix internally before querying the chain.

## Endpoints

<CardGroup cols={2}>
  <Card title="GET /mcr/{did}" icon="gauge" href="/peaqos/api-reference/get-mcr">
    Machine Credit Rating score, rating, bond status, event counts, and revenue trend for a single machine.
  </Card>

  <Card title="GET /machine/{did}" icon="robot" href="/peaqos/api-reference/get-machine">
    Full machine profile with data visibility-dependent fields (private, onchain, or public).
  </Card>

  <Card title="GET /operator/{did}/machines" icon="users" href="/peaqos/api-reference/get-operator-machines">
    Paginated list of machines registered under an operator, with per-machine MCR scores.
  </Card>

  <Card title="GET /metadata/{token_id}" icon="image" href="/peaqos/api-reference/get-metadata">
    NFT metadata for a MachineNFT token. Same response shape as /machine/{did}.
  </Card>

  <Card title="GET /machines/{machine_id}" icon="id-card" href="/peaqos/api-reference/get-machine-card">
    peaqOS Machine Card for a machine, including services, registrations, and operator info.
  </Card>

  <Card title="GET /health and /ready" icon="heart-pulse" href="/peaqos/api-reference/health">
    Liveness and readiness probes for health checks and monitoring.
  </Card>
</CardGroup>
