---
title: "Tdx Preflight"
method: POST
path: "/servers/tdx/preflight"
tags: ["Servers"]
---

# Tdx Preflight

`POST /servers/tdx/preflight`

## Request

- Base URL: `https://api.chutes.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.chutes.ai/servers/tdx/preflight`
- Auth: API key in header `Authorization`

Can this exact image boot on this host? The one call a launch/upgrade preflight makes.

A check against both a host profile and the measurement set, so it hangs off neither. The API
fingerprints the submitted profile and answers whether a published measurement for the caller's
`(version, rc)` carries that fingerprint -- the whole launch decision in one boolean:

  * `launchable: true`  -> the VM will attest; launch.
  * `launchable: false` -> register the class (POST /servers/tdx/host_profiles), then retry once
    Chutes publishes its measurement.

Stores nothing and reveals nothing beyond the answer -- not the full measurement set, not
whether a profile row exists. Signed by the miner hotkey, so the signature covers the body.

## Query parameters

- `version` string, required: VM image version the caller intends to boot.
- `rc` boolean: Whether that image is a release-candidate (debug) build.

## Headers

- `X-Chutes-Hotkey` string, nullable
- `X-Chutes-Signature` string, nullable
- `X-Chutes-Nonce` string, nullable
- `Authorization` string, nullable

## Request body

- HostProfile: One host class, as chutes-cvm's ``HostProfile.to_api_profile()`` submits it. A direct translation of the client's own model: the RTMR0 determinants and nothing else. Stored == hashed == required, one set. An unhashed field stored beside a hashed one would re-split the class at the byte level -- two hosts that measure identically would differ in the stored row, and first-write-wins would silently drop one of them. That is why host RAM, BDFs, DMI strings and the lspci tree are absent rather than merely excluded. Every block forbids extras, so a client that adds a key 422s until the API models it: add the field here, deploy, then roll out the client.
  - `gpus` HostProfileGpuDevice[], required
    - `vendor` string, required
    - `device_id` string, required
    - `pci_class` string, required
    - `numa_node` integer, required
    - `bars` HostProfilePciBar[], required
      - `index` integer, required
      - `size_mb` integer, required
      - `kind` string, required
  - `nvswitches` HostProfileNvswitchDevice[]
    - `vendor` string, required
    - `device_id` string, required
    - `pci_class` string, required
    - `numa_node` integer, required
    - `bars` HostProfilePciBar[], required
      - `index` integer, required
      - `size_mb` integer, required
      - `kind` string, required
  - `ib_devices` HostProfileIbDevice[]
    - `vendor` string, required
    - `device_id` string, required
    - `pci_class` string, required
    - `numa_node` integer, required
    - `bars` HostProfilePciBar[], required
      - `index` integer, required
      - `size_mb` integer, required
      - `kind` string, required
    - `is_bridge_pf` boolean
    - `is_vf` boolean
  - `cpu` HostProfileCpu, required: The host CPU facts that reach RTMR0: the guest -smp and the SMBIOS Type-4 identity. Mirrors chutes-cvm's `HostCpu` field for field. `processor_id` is nullable -- CPUID leaf-1 is unreadable on some hosts -- but the key is required, and generation refuses a null rather than measuring its own host's CPU.
    - `count` integer, required
    - `sockets` integer, required
    - `vendor` string, required
    - `processor_id` string, nullable, required
  - `memory` HostProfileMemory, required: Guest RAM, as the client resolved it. Not host RAM: the sizing rules are per-GPU-profile and live in chutes-cvm, so the client sends the answer. Storing the host total instead would split hosts that measure identically -- 2007 and 2011 GB are one H200 class.
    - `guest_gb` integer, required
  - `numa` HostProfileNuma, required: Host NUMA node count: it picks the guest's memory-map and PXB-PCIe grouping.
    - `node_count` integer, required
  - `qemu` HostProfileQemu, required: The QEMU that builds the guest ACPI measured into RTMR0.
    - `qemu_version` string, required

## Response `200`

Successful Response

- string

## Other responses

- `422`: Validation Error

## Changes

- **2026-10-16** `23e8895b217d`: 4 breaking, 2 info
  - the response's body type changed from `object` to `string` for status `200`
  - removed the required property `detail` from the response with the `200` status
  - removed the required property `fingerprint` from the response with the `200` status
  - removed the required property `launchable` from the response with the `200` status
  - …2 more
- **2026-09-20** `6543e32b21d3`: 7 breaking, 18 warning, 2 info
  - added the new required request property `cpu/count`
  - added the new required request property `cpu/processor_id`
  - added the new required request property `cpu/vendor`
  - added the new required request property `gpus`
  - …23 more
- **2026-09-15** `fe1de11b2a0e`: 2 info
  - added the new optional request property `gpu/pci_bars`
  - added the new optional request property `gpu/pci_class`
- **2026-08-27** `7be1aa2fe1a0`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/chutes/apis/chutes-api/changes/servers/tdx/preflight/post.md)

---

[API](https://skmtc.dev/chutes/apis/chutes-api.md) - [All operations](https://skmtc.dev/chutes/apis/chutes-api/llms.txt) - [OpenAPI document](https://skmtc.dev/chutes/apis/chutes-api/revisions/8add5b0e22da?raw)
