> ## 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.

# peaqID

> W3C DID for machines, portable across every chain peaqOS supports.

peaqID is a W3C DID that identifies a machine across every chain it transacts on.

## DID format

Every peaqID follows the format:

```
did:peaq:<0x-address>
```

The address is the machine's EOA (externally owned account) on peaq chain. The DID resolves to a flat key-value attribute store on the peaq DID precompile (`0x0000000000000000000000000000000000000800`). Any consumer can start from the DID and traverse to the machine's identity, financial history, and credit rating.

## Per-machine vs per-proxy

peaqOS assigns one DID per machine and one DID per proxy operator. The two serve different roles:

| DID type    | Registered by                                                        | Attributes                                                                                | Purpose                                                                  |
| :---------- | :------------------------------------------------------------------- | :---------------------------------------------------------------------------------------- | :----------------------------------------------------------------------- |
| Machine DID | `registerMachine` (self-managed) or `registerFor` (proxy delegation) | `machineId`, `nftTokenId`, `operator`, `documentation_url`, `data_api`, `data_visibility` | Identifies a single machine, links to its Machine NFT and event history  |
| Proxy DID   | `registerMachine`. The proxy itself is a registered machine.         | `machineId`, `machines`                                                                   | Identifies an operator, lists the machine IDs of all machines it manages |

A machine that self-manages has no `operator` attribute. A proxy operator's `machines` attribute is a JSON array of machine IDs (e.g., `[123, 456, 789]`).

<Warning>
  **DID writes always go to the caller's DID.** The DID precompile keys attributes by `msg.sender`. A proxy that calls `registerFor` mints the machine's identity NFT and pays the bond, but it cannot write attributes to the machine's DID; the machine must sign its own `writeMachineDIDAttributes` call. Skipping this leaves the machine unreachable through the MCR API.
</Warning>

## DID attribute table

After registration, the operator or machine must explicitly call `writeMachineDIDAttributes` (or `writeProxyDIDAttributes`) to write these attributes to the DID. Registration itself only mints the identity and creates the on-chain machine ID; the DID attribute writes are a separate transaction.

| Attribute           | Type                             | Description                                                                                                                                                                            |
| :------------------ | :------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `machineId`         | `uint256`                        | On-chain machine ID assigned by IdentityRegistry. Primary key for all queries.                                                                                                         |
| `nftTokenId`        | `uint256`                        | Token ID of the machine's Machine NFT. This is a separate ERC-721 token space and is not equal to `machineId`.                                                                         |
| `operator`          | `did:peaq:0x...`                 | Proxy operator's DID. Absent if the machine self-manages.                                                                                                                              |
| `documentation_url` | URL string                       | Link to machine documentation maintained by the project.                                                                                                                               |
| `data_api`          | URL string                       | Raw data API endpoint. The MCR API reads this when `data_visibility` is `public`.                                                                                                      |
| `data_visibility`   | `public` / `private` / `onchain` | Controls how the MCR API exposes raw event data. Unset or empty defaults to `private`.                                                                                                 |
| `machines`          | JSON array string                | Proxy operator DID only. List of managed machine IDs. The DID precompile stores the full JSON; the MCR API truncates to the first 100 valid IDs when reading the `machines` attribute. |

### Byte limits

Both SDKs enforce these constraints before any DID write reaches the chain:

| Constant              | Value | Applies to      |
| :-------------------- | :---- | :-------------- |
| `DID_MAX_NAME_BYTES`  | 64    | Attribute name  |
| `DID_MAX_VALUE_BYTES` | 2560  | Attribute value |

<Note>
  **Migration.** peaq chain has approximately 3.5 million existing peaqID holders. Existing holders retain their peaqIDs. A migration path to the current DID format is on the [roadmap](/roadmap); the new format is what onboards from peaqOS today.
</Note>

## Resolving a peaqID

<CodeGroup>
  ```typescript JS/TS theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
  import "dotenv/config";
  import { PeaqosClient } from "@peaqos/peaq-os-sdk";

  const client = PeaqosClient.fromEnv();

  // Fetch machine profile by DID
  const response = await fetch(
    `${client.apiUrl}/machine/did:peaq:0xMachineAddress`
  );
  const machine = await response.json();

  console.log(machine.peaqos.did);         // "did:peaq:0x..."
  console.log(machine.peaqos.machine_id);  // 123
  console.log(machine.peaqos.mcr);         // "BBB"
  ```

  ```python Python theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
  from dotenv import load_dotenv
  import requests
  from peaq_os_sdk import PeaqosClient

  load_dotenv() # load envs from .env file

  client = PeaqosClient.from_env()

  # Fetch machine profile by DID
  response = requests.get(
      f"{client.api_url}/machine/did:peaq:0xMachineAddress"
  )
  machine = response.json()

  print(machine["peaqos"]["did"])         # "did:peaq:0x..."
  print(machine["peaqos"]["machine_id"])  # 123
  print(machine["peaqos"]["mcr"])         # "BBB"
  ```
</CodeGroup>

## Data visibility modes

The `data_visibility` attribute controls how the MCR API handles raw event data for this machine:

| Mode      | MCR API behavior                                                                                                | Raw data location         |
| :-------- | :-------------------------------------------------------------------------------------------------------------- | :------------------------ |
| `public`  | Fetches from `data_api`, includes in response                                                                   | Project's API             |
| `private` | Returns the `data_api` URL only; consumer fetches directly                                                      | Project's API             |
| `onchain` | Parses JSON metadata from EventRegistry events into `event_data[]`, capped at the first 100 events per response | Onchain (higher gas cost) |

`private` is the default when `data_visibility` is unset or empty.

## Cross-links

* [Activate function](/peaqos/functions/activate) registers machines and writes DID attributes
* [GET /machine/{did}](/peaqos/api-reference/get-machine) returns the full machine profile, including DID-sourced metadata
* [Machine NFT](/peaqos/concepts/machine-nft) is linked to the peaqID via the `nftTokenId` attribute
