# Report the server's host key

Stores the server's own SSH host key (K1) after the client replaced the bootstrap host key (K0) on the server, and forgets the bootstrap key. From then on `host_key_pub` is the only key clients should trust and `bootstrap_host_key_pub` is `null`. The server's state does not change.

The bootstrap key's private half reached the server through the provider's metadata, so it must not stay trusted. While the server is in `securing`, the client — connected and pinned to `bootstrap_host_key_pub` — waits for `/var/lib/forge/bootstrap.done`, reads the staged key from `/etc/ssh/forge_next_ed25519_key.pub` and pins it, runs `touch /var/lib/forge/host-key/commit` so the server switches to it, reconnects pinned to K1, and then calls this endpoint. [Mark a server ready](/docs/api-reference/forge-compute/report-ready) is refused until it has.

Reporting the same key again returns the server unchanged; reporting a different key later replaces the stored one; reporting the bootstrap key itself is refused. Allowed while the server is `awaiting_client`, `securing`, `installing` or `pairing`.

Requires a bearer token (or API key) whose principal holds the `use_forge` capability in the acting organization and created the server or holds `manage_forge`, and Forge cloud compute switched on for the organization.

#### Path Parameters

**`host_id`** string required

The server's id: the `fchost_` id returned in `id`, or the UUID sent when the server was created (any letter case, with or without hyphens).

#### Query Parameters

**`organization_id`** string optional

The organization the server belongs to: send its `organization.id` (from [List your servers in every organization](/docs/api-reference/forge-compute/list-my-hosts)). Defaults to your current organization, where a server of another organization is not found. You must be an active member of it, or the request is refused with `403 ORGANIZATION_ACCESS_DENIED`.

#### Headers

**`X-Organization-Id`** string optional

The same as `organization_id`, as a header. When both are sent, the query parameter wins.

#### Body Parameters

**`host_key_pub`** string required

The public half of the server's new host key, as one OpenSSH line: `ssh-ed25519`, `ecdsa-sha2-nistp256/384/521`, or `ssh-rsa` of 3072 to 16384 bits. Security-key types are refused because an SSH server cannot use them as host keys. No options prefix and no certificates; a comment is kept, reduced to letters, digits and `@._-`.

Unknown fields are refused.

## Returns

`200 OK` with the [server object](/docs/api-reference/forge-compute/get-host#returns): `host_key_pub` set, `bootstrap_host_key_pub` `null`.


```json
{
  "id": "fchost_5d0c2b9e7a414f3c9e8b1a6d2f4c7e90",
  "offering_id": "aitronos",
  "kind": "managed",
  "name": "build-box",
  "organization": {"id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c", "name": "Acme Engineering"},
  "user_id": "usr_7f3a9c2e1b8d4e6fa0c5b3d9e2f1a4c7",
  "project_group": {"id": "fpgrp_4b9e2c7a1d3f4e8a9c0b6d2e1f3a5b7c", "client_id": "grp-clients", "name": "Clients"},
  "location_id": "eu-central",
  "location_label": "Germany",
  "size_id": "std-16",
  "size_label": "16 vCPU · 64 GB",
  "state": "securing",
  "state_label": "Securing the connection",
  "transient": true,
  "step": "securing",
  "step_started_at": "2026-09-28T09:01:20.118532Z",
  "state_changed_at": "2026-09-28T09:01:20.118532Z",
  "failure": null,
  "ipv4": "203.0.113.24",
  "ipv6": "2001:db8:4f2a::1",
  "ssh_port": 22,
  "ssh_user": "forge",
  "bootstrap_host_key_pub": null,
  "host_key_pub": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleServerHostKeyForDocumentationOnly0000",
  "price": {
    "hourly": "0.83",
    "monthly_cap": "520.30",
    "currency": "CHF",
    "source": "aitronos",
    "includes_vat": false,
    "catalog_version": "fc-3b8e1f0a9c42",
    "quoted_at": "2026-09-28T09:00:00.184066Z",
    "parked_per_gb_month": "0.0269",
    "price_verified": true
  },
  "month_to_date": "0.83",
  "notice": null,
  "idle_reminder": null,
  "reconcile_flags": null,
  "actions": ["park", "delete", "revoke"],
  "created_at": "2026-09-28T09:00:00.184066Z",
  "ready_at": null,
  "parked_at": null,
  "parked_expires_at": null,
  "deleted_at": null,
  "revoked_at": null,
  "revoke_reason": null,
  "last_activity_at": null
}
```

## Errors

| Status | Code | When |
|  --- | --- | --- |
| 401 | `AUTHENTICATION_REQUIRED` | No valid credential. |
| 403 | `ORGANIZATION_ACCESS_DENIED` | `organization_id` or `X-Organization-Id` names an organization you are not an active member of. |
| 403 | `INSUFFICIENT_PERMISSIONS` | The caller does not hold `use_forge` in the acting organization. |
| 403 | `FORGE_COMPUTE_DISABLED` | Forge cloud compute is not switched on for the organization. |
| 404 | `FORGE_COMPUTE_HOST_NOT_FOUND` | No server with this id in the acting organization, or it was created by someone else and the caller does not hold `manage_forge`. |
| 409 | `FORGE_COMPUTE_INVALID_STATE` | The server is not being set up. `details.action` is `host_key`. |
| 422 | `FORGE_COMPUTE_INVALID_HOST_KEY` | Not one accepted OpenSSH public key, or still the bootstrap key. `details.reason` says why. |
| 422 | `VALIDATION_ERROR` | `host_key_pub` is missing or the body has an unknown field. |
| 422 | `INVALID_ID_FORMAT` | `host_id` is neither a UUID nor `fchost_<32 hex>`. |



```bash cURL
curl -X POST "https://api.aitronos.com/v1/forge/compute/hosts/fchost_5d0c2b9e7a414f3c9e8b1a6d2f4c7e90/host-key" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "host_key_pub": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleServerHostKeyForDocumentationOnly0000"
  }'
```


```python Python SDK
# pip install aitronos-sdk
#
# The Python SDK does not expose a typed `forge_compute` namespace yet, so call
# the endpoint directly with the same credential you would pass to `Aitronos(...)`
# — an API key or a bearer token, both sent as `Authorization: Bearer <value>`.
import httpx

API_KEY = "your-api-key"
# The line read from /etc/ssh/forge_next_ed25519_key.pub on the server,
# after reconnecting pinned to it.
staged_host_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleServerHostKeyForDocumentationOnly0000"

server = httpx.post(
    "https://api.aitronos.com/v1/forge/compute/hosts/fchost_5d0c2b9e7a414f3c9e8b1a6d2f4c7e90/host-key",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={"host_key_pub": staged_host_key},
).json()
print(server["state"], server["step"])
```


```python Python
import os
import requests

token = os.environ["AITRONOS_TOKEN"]
# The line read from /etc/ssh/forge_next_ed25519_key.pub on the server,
# after reconnecting pinned to it.
staged_host_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleServerHostKeyForDocumentationOnly0000"
response = requests.post(
    "https://api.aitronos.com/v1/forge/compute/hosts/fchost_5d0c2b9e7a414f3c9e8b1a6d2f4c7e90/host-key",
    headers={"Authorization": f"Bearer {token}"},
    json={"host_key_pub": staged_host_key},
)
if response.status_code == 409:
    print(response.json()["error"]["details"])
else:
    print(response.json()["state_label"])
```


```javascript JavaScript
// The line read from /etc/ssh/forge_next_ed25519_key.pub on the server.
const stagedHostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleServerHostKeyForDocumentationOnly0000";

const response = await fetch(
  "https://api.aitronos.com/v1/forge/compute/hosts/fchost_5d0c2b9e7a414f3c9e8b1a6d2f4c7e90/host-key",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.AITRONOS_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ host_key_pub: stagedHostKey }),
  },
);
const server = await response.json();
console.log(response.status, server.state);
```

**Response:**

200 OK

```json
{
  "id": "fchost_5d0c2b9e7a414f3c9e8b1a6d2f4c7e90",
  "offering_id": "aitronos",
  "kind": "managed",
  "name": "build-box",
  "organization": {"id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c", "name": "Acme Engineering"},
  "user_id": "usr_7f3a9c2e1b8d4e6fa0c5b3d9e2f1a4c7",
  "project_group": {"id": "fpgrp_4b9e2c7a1d3f4e8a9c0b6d2e1f3a5b7c", "client_id": "grp-clients", "name": "Clients"},
  "location_id": "eu-central",
  "location_label": "Germany",
  "size_id": "std-16",
  "size_label": "16 vCPU · 64 GB",
  "state": "securing",
  "state_label": "Securing the connection",
  "transient": true,
  "step": "securing",
  "step_started_at": "2026-09-28T09:01:20.118532Z",
  "state_changed_at": "2026-09-28T09:01:20.118532Z",
  "failure": null,
  "ipv4": "203.0.113.24",
  "ipv6": "2001:db8:4f2a::1",
  "ssh_port": 22,
  "ssh_user": "forge",
  "bootstrap_host_key_pub": null,
  "host_key_pub": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleServerHostKeyForDocumentationOnly0000",
  "price": {
    "hourly": "0.83",
    "monthly_cap": "520.30",
    "currency": "CHF",
    "source": "aitronos",
    "includes_vat": false,
    "catalog_version": "fc-3b8e1f0a9c42",
    "quoted_at": "2026-09-28T09:00:00.184066Z",
    "parked_per_gb_month": "0.0269",
    "price_verified": true
  },
  "month_to_date": "0.83",
  "notice": null,
  "idle_reminder": null,
  "reconcile_flags": null,
  "actions": ["park", "delete", "revoke"],
  "created_at": "2026-09-28T09:00:00.184066Z",
  "ready_at": null,
  "parked_at": null,
  "parked_expires_at": null,
  "deleted_at": null,
  "revoked_at": null,
  "revoke_reason": null,
  "last_activity_at": null
}
```

422 Unprocessable Entity

```json
{
  "success": false,
  "error": {
    "code": "FORGE_COMPUTE_INVALID_HOST_KEY",
    "message": "The server's host key was not accepted. Reconnect to the server and try again.",
    "system_message": "Invalid host public key: The reported host key is still the bootstrap key; rotate it first.",
    "type": "validation_error",
    "status": 422,
    "details": {
      "field": "host_key_pub",
      "reason": "The reported host key is still the bootstrap key; rotate it first."
    },
    "trace_id": "3f1c9a52-7d4e-4b8a-9c21-6e0d5f7a8b34",
    "timestamp": "2026-09-28T09:00:00Z"
  }
}
```

409 Conflict

```json
{
  "success": false,
  "error": {
    "code": "FORGE_COMPUTE_INVALID_STATE",
    "message": "This server cannot do that in its current state. Wait for it to finish and try again.",
    "system_message": "Action 'host_key' is not allowed while the host is 'parked'",
    "type": "client_error",
    "status": 409,
    "details": {"state": "parked", "action": "host_key"},
    "trace_id": "3f1c9a52-7d4e-4b8a-9c21-6e0d5f7a8b34",
    "timestamp": "2026-09-28T09:00:00Z"
  }
}
```

## Related Resources

- [Forge cloud compute overview](/docs/api-reference/forge-compute/introduction)
- [List billing organizations](/docs/api-reference/forge-compute/list-billing-organizations)
- [Choose the default billing organization](/docs/api-reference/forge-compute/choose-billing-organization)
- [List project groups](/docs/api-reference/forge-compute/list-project-groups)
- [Register or update a project group](/docs/api-reference/forge-compute/put-project-group)
- [Delete a project group](/docs/api-reference/forge-compute/delete-project-group)
- [List compute offerings](/docs/api-reference/forge-compute/list-offerings)
- [Get offering options](/docs/api-reference/forge-compute/get-offering-options)
- [Resolve a free size](/docs/api-reference/forge-compute/resolve-offering-size)
- [List connected accounts](/docs/api-reference/forge-compute/list-credentials)
- [Connect a cloud account](/docs/api-reference/forge-compute/put-credential)
- [Disconnect a cloud account](/docs/api-reference/forge-compute/delete-credential)
- [Create a server](/docs/api-reference/forge-compute/create-host)
- [List servers](/docs/api-reference/forge-compute/list-hosts)
- [List your servers in every organization](/docs/api-reference/forge-compute/list-my-hosts)
- [Get a server](/docs/api-reference/forge-compute/get-host)
- [Get a server's daily cost and uptime](/docs/api-reference/forge-compute/get-host-usage)
- [List a server's running intervals](/docs/api-reference/forge-compute/list-host-intervals)
- [List a server's event history](/docs/api-reference/forge-compute/list-host-events)
- [Report a setup step](/docs/api-reference/forge-compute/report-progress)
- [Report the server's host key](/docs/api-reference/forge-compute/report-host-key)
- [Mark a server ready](/docs/api-reference/forge-compute/report-ready)
- [Report activity](/docs/api-reference/forge-compute/report-activity)
- [Park a server](/docs/api-reference/forge-compute/park-host)
- [Resume a server](/docs/api-reference/forge-compute/resume-host)
- [Delete a server](/docs/api-reference/forge-compute/delete-host)
- [Revoke a server](/docs/api-reference/forge-compute/revoke-host)
- [Get compute settings](/docs/api-reference/forge-compute/get-settings)
- [Update compute settings](/docs/api-reference/forge-compute/update-settings)
- [Get spend limits](/docs/api-reference/forge-compute/get-limits)
- [Change the organization's limits](/docs/api-reference/forge-compute/update-organization-limits)
- [Set your own limit](/docs/api-reference/forge-compute/update-my-limit)
- [List member limits](/docs/api-reference/forge-compute/list-member-limits)
- [Set a member's limit](/docs/api-reference/forge-compute/update-member-limit)
- [Delete a leftover resource](/docs/api-reference/forge-compute/delete-orphan)