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

# POST /v1/verify/chip/challenge

> Issue the five-minute challenge that a machine chip signs for Verify chip intake.

## Endpoint

```http theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
POST /v1/verify/chip/challenge
```

Step 1 of [chip verification](/peaqos/functions/verify#verify-a-chip-end-to-end). Issues a single-use challenge for one machine: a 32-byte nonce, the machine's DID, its current DID controller, the chain ID and an expiry at most five minutes out. The machine's chip and its DID controller sign over this challenge, and [`POST /v1/verify/chip/evidence`](/peaqos/api-reference/post-verify-chip-evidence) consumes it.

Issuing a challenge does not check a chip, set a status or record an attestation. The route takes no certificate or signature.

<Warning>
  The route requires peaq's onboarding token (`Authorization: Bearer <token>`). Without a valid token every request answers `401 ONBOARDING_AUTH_REQUIRED`, before the body is read. Machine operators receive the challenge from peaq's onboarding service; they do not hold the token.
</Warning>

## Headers

| Header | Value |
| :- | :- |
| `Authorization` | Exactly one `Bearer <onboarding token>` |
| `Content-Type` | `application/json`, optionally with `charset=utf-8` |
| `Accept` | Omit, or a range that accepts `application/json` |
| `Content-Encoding` | Must be absent |

## Request body

<ParamField body="machineId" type="string" required>
  Decimal machine ID as a string, `1` to `2^256-1`, no sign, whitespace or leading zeros. A JSON number, a DID or an address returns `400 INVALID_REQUEST`.
</ParamField>

The body is a closed object with exactly this one field and at most 1024 bytes. Duplicate keys and extra fields return `400 INVALID_REQUEST`. The server resolves the DID, controller and chain ID itself and generates the nonce and expiry.

## Response

**201 Created**, `Content-Type: application/json; charset=utf-8`, `Cache-Control: no-store`.

| Field | Type | Description |
| :- | :- | :- |
| `chainId` | string | Decimal chain ID of the machine's home chain (`"3338"` on peaq mainnet) |
| `didController` | string | The effective DID controller as an EIP-55 address: the controller set in MachineRegistry, or the machine NFT owner when none is set. This address signs the controller proof |
| `expiresAt` | string | Unix time in seconds; at most 300 seconds after issuance |
| `machineDid` | string | `did:peaq:<machineId>` |
| `machineId` | string | The requested machine ID |
| `nonce` | string | 32 random bytes as lowercase `0x` hex. Returned once; the challenge record keeps only its SHA-256 hash |
| `profile` | string | Always `infineon-optiga-trust-m-express-ca306/1` |
| `protocol` | string | Always `peaq.verify.chip-proof/1` |
| `verifier` | string | Always `peaq.verify` |

The challenge is single use. The DID controller in the challenge must still be the machine's controller when the evidence is submitted; a change in between gets the evidence rejected.

## Error responses

Errors use the coded envelope:

```json theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
{ "detail": { "code": "MACHINE_NOT_FOUND", "message": "machine not found" } }
```

| Status | `code` | Condition |
| :- | :- | :- |
| 400 | `INVALID_REQUEST` | Wrong media type, body over 1024 bytes, invalid JSON shape or `machineId` |
| 401 | `ONBOARDING_AUTH_REQUIRED` | Missing, malformed, repeated or invalid token |
| 404 | `MACHINE_NOT_FOUND` | No machine with this ID in MachineRegistry |
| 404 | `VERIFY_ROUTE_NOT_FOUND` | Unknown path under `/v1/verify/` |
| 405 | `METHOD_NOT_ALLOWED` | Any method other than `POST` |
| 406 | `NOT_ACCEPTABLE` | `Accept` excludes JSON |
| 409 | `MACHINE_DEACTIVATED` | The machine is administratively deactivated |
| 413 | `REQUEST_TOO_LARGE` | Rejected as too large before parsing |
| 429 | `RATE_LIMITED` | Per-IP limit, or too many open challenges for this machine or in total |
| 500 | `INTERNAL_ERROR` | Unhandled server error |
| 503 | `CHAIN_UNAVAILABLE` | The machine's owner, controller or the chain ID could not be read |
| 503 | `VERIFY_STORE_UNAVAILABLE` | The challenge could not be stored |
| 503 | `VERIFY_CLOCK_INVALID` | The server clock is invalid |

Branch on `code`, never on `message`. Errors never echo the token, the nonce or the request body.

## Example

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
curl --request POST "https://mcr.peaq.xyz/v1/verify/chip/challenge" \
  --header "Authorization: Bearer $VERIFY_ONBOARDING_TOKEN" \
  --header "Content-Type: application/json" \
  --header "Accept: application/json" \
  --data '{"machineId":"123"}'
```

**Illustrative response.** `123` is a placeholder machine ID.

```json theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
{
  "chainId": "3338",
  "didController": "0x8617E340B3D01FA5F11F306F4090FD50E238070D",
  "expiresAt": "1791279319",
  "machineDid": "did:peaq:123",
  "machineId": "123",
  "nonce": "0x5f0c3e0b8a3a4bd2c8f1e6d77a9b0c1d2e3f405162738495a6b7c8d9eaf0b1c2",
  "profile": "infineon-optiga-trust-m-express-ca306/1",
  "protocol": "peaq.verify.chip-proof/1",
  "verifier": "peaq.verify"
}
```

## Related endpoints

* [POST /v1/verify/chip/evidence](/peaqos/api-reference/post-verify-chip-evidence) submits the signed evidence for this challenge.
* [GET /v1/verify/machines/\{machineId}](/peaqos/api-reference/get-verify-machine) reads the machine's KYB and chip status.


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