Skip to content

Key Pair API Reference

Reference · Updated Sep 2026

Coming from another cloud?

▸AWS·EC2 Key Pairs

EC2 Key Pairshigh

  • Public key auto-injected to authorized_keys at boot.
  • Up to 5000 per region; AWS stores public key.
  • Supports import of external keys (RSA/ED25519).
  • No post-launch addition without userdata/SSM.
AWS docs ↗
▸Azure·SSH public keys

SSH public keyshigh

  • Managed as ARM resources (Microsoft.Compute/sshPublicKeys), reusable across VMs, vs OpenStack's keypairs injected only at boot.
  • API /providers/Microsoft.Compute/sshPublicKeys, supports ED25519/RSA, no private key storage.
  • Keys provided during VM create or via portal/CLI, not listed/injected separately post-boot like OpenStack.
  • No deletion/re-import of injected keys; new VM for changes.
Azure docs ↗
▸DigitalOcean·API

DigitalOcean APIhigh

  • Uses REST API over HTTPS with Bearer token authentication via personal access tokens, not OpenStack's Keystone token-based auth.
  • Base URL https://api.digitalocean.com/v2, incompatible with OpenStack APIs like Nova/Neutron.
  • Scoped permissions tied to granular API scopes based on team roles, unlike OpenStack role/project assignments.
  • Rate limits: 5000/hour, 250/minute.
DigitalOcean docs ↗
▸Google Cloud·SSH keys

SSH keyshigh

  • Managed in project/instance metadata or OS Login (IAM); no central 'keypairs' resource like Nova.
  • Auto-generates ephemeral keys for CLI/console; manual upload only in OpenStack.
  • Public key includes username suffix; injected differently.
Google Cloud docs ↗
▸Hetzner·Cloud API

Cloud APIhigh

  • Proprietary REST API over HTTPS with Bearer token auth, not OpenStack Identity API (keystone) endpoints or mechanisms.
  • Base URL https://api.hetzner.cloud/v1/ with resource-specific endpoints (e.g., /servers) vs OpenStack service endpoints (nova, cinder).
  • No multi-project handling in single auth; separate per-project tokens vs keystone scopes/projects.
  • Missing identity/catalog endpoints; no service discovery via API.
Hetzner docs ↗

Key pair API reference

See the upstream Nova API reference for the full specification.

In these methods, \{keypair_name\} is a placeholder for the name of the key pair. The API lists key pairs, shows the details of a single key pair, creates a new key pair or imports an existing one, and deletes a key pair. A create request returns the private key once in the response body; save it securely. An import request takes the public key in the request body.

List key pairs#

bash
GET /os-keypairs

Each array element wraps its fields in a nested keypair object. Read a name as keypairs[N].keypair.name, not keypairs[N].name.

Response (200 OK)

JSON
{
  "keypairs": [
    {
      "keypair": {
        "name": "deploy-key",
        "public_key": "ssh-ed25519 AAAA...EXAMPLE [email protected]",
        "fingerprint": "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff"
      }
    }
  ]
}

Show key pair details#

bash
GET /os-keypairs/{keypair_name}

The detail response wraps the key pair in a keypair object and adds user_id, created_at, updated_at, deleted, deleted_at, and a numeric id. The id field is the internal Nova database row, not the key pair name. A key pair created with a type field also returns that type.

Response (200 OK)

JSON
{
  "keypair": {
    "name": "deploy-key",
    "public_key": "ssh-ed25519 AAAA...EXAMPLE [email protected]",
    "fingerprint": "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff",
    "user_id": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
    "created_at": "2026-05-07T15:17:37.000000",
    "updated_at": null,
    "deleted": false,
    "deleted_at": null,
    "id": 2419
  }
}

Create or import a key pair#

bash
POST /os-keypairs

Request body (for creating a new key pair)

JSON
{
  "keypair": {
    "name": "deploy-key"
  }
}

Request body (for importing an existing key pair)

JSON
{
  "keypair": {
    "name": "deploy-key",
    "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ..."
  }
}

A default create or import request (no type field) returns 200 OK. A request that sets type requires Nova microversion 2.2 or higher and returns 201 Created. The create response includes private_key; the import response does not.

Response (200 OK, default create)

JSON
{
  "keypair": {
    "name": "deploy-key",
    "fingerprint": "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff",
    "public_key": "ssh-ed25519 AAAA...EXAMPLE",
    "private_key": "-----BEGIN PRIVATE KEY-----\n...EXAMPLE...\n-----END PRIVATE KEY-----\n",
    "user_id": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
  }
}

Response (201 Created, type set with microversion 2.2+)

JSON
{
  "keypair": {
    "name": "deploy-key",
    "type": "x509",
    "fingerprint": "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff",
    "public_key": "ssh-ed25519 AAAA...EXAMPLE",
    "private_key": "-----BEGIN PRIVATE KEY-----\n...EXAMPLE...\n-----END PRIVATE KEY-----\n",
    "user_id": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
  }
}

Delete a key pair#

bash
DELETE /os-keypairs/{keypair_name}

A successful delete returns 202 Accepted with an empty body.

Was this page helpful?