Create or Import SSH Key Pair
POST /v2.1/{project_id}/os-keypairs
Create (generate) a brand new key pair or import an existing public key. If you provide a public_key, it is imported. If you omit it, the service generates a new key pair and returns the private key material once in the response. You must store it securely; it cannot be retrieved again.
Source
Request
Body Structure
Top-level JSON object must contain a single keypair object with the attributes below.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| project_id | path | string | The UUID of the project (tenant). |
| keypair | body | object | Wrapper object containing key pair attributes. |
| keypair.name | body | string | A name for the key pair (unique per user). Required. |
| keypair.public_key (Optional) | body | string | Public key material to import (e.g. starts with ssh-rsa, ssh-ed25519, or PEM for x509). If omitted, a new key pair is generated and private_key is returned. |
| keypair.user_id (Optional) | body | string | User ID that will own the key pair (admin-only to create for another user). New in version 2.10 |
| keypair.type (Optional) | body | string | Key type: ssh (default) or x509. New in version 2.2 |
Sample Requests
Generate a key pair
curl -ks -X POST \
-H 'Content-Type: application/json' \
-H 'X-Auth-Token: gAAAAA<...>' \
-H 'X-OpenStack-Nova-API-Version: 2.72' \
-d '{
"keypair": {
"name": "apikey1"
}
}' \
https://api.vietnix.cloud:8774/v2.1/{project_id}/os-keypairs
Import an existing public key (with optional description suffix)
You may append a description after the key (for bookkeeping) – ensure it does not alter the key material itself. Example uses a comment-style suffix VSTOR-KEY-DESC:Key3 description.
curl -ks -X POST \
-H 'Content-Type: application/json' \
-H 'X-Auth-Token: gAAAAA<...>' \
-H 'X-OpenStack-Nova-API-Version: 2.72' \
-d '{
"keypair": {
"name": "apikey2",
"public_key": "ssh-rsa AAAA<...> VSTOR-KEY-DESC:Key2 description"
}
}' \
https://api.vietnix.cloud:8774/v2.1/{project_id}/os-keypairs
Replace
{project_id}with your actual project UUID.
Response
On success returns a single keypair object.
Response Body Fields
| Name | In | Type | Description |
|---|---|---|---|
| keypair | body | object | The created (or imported) key pair wrapper object. |
| keypair.name | body | string | Name of the key pair. |
| keypair.public_key | body | string | Public key material. Generated-by-Nova comment may be appended for generated keys. |
| keypair.private_key (Only when generated) | body | string | Private key (PEM) returned only once when no public_key was provided. Store securely. |
| keypair.fingerprint | body | string | MD5 fingerprint (colon-delimited). |
| keypair.user_id | body | string | Owning user ID. |
| keypair.created_at | body | string | Creation timestamp (ISO 8601). |
| keypair.type | body | string | Key type: ssh or x509. |
Status Codes
Success
| Code | Reason |
|---|---|
| 200 - OK | Request successful (import may return 200). |
| 201 - Created | New key pair generated or imported. |
Error
| Code | Reason |
|---|---|
| 400 - Bad Request | Invalid request body or parameters. |
| 401 - Unauthorized | Authentication failed or missing. |
| 403 - Forbidden | Policy does not allow this operation. |
| 409 - Conflict | Name already exists or conflicting operation. |
Sample Responses
Generated Key Pair
{
"keypair": {
"private_key": "-----BEGIN RSA PRIVATE KEY-----\nMII<...>\n-----END RSA PRIVATE KEY-----\n",
"name": "apikey1",
"public_key": "ssh-rsa AAAA<...> Generated-by-Nova",
"fingerprint": "67:c0:a2:8a:b4:c8:50:de:80:91:ed:79:14:17:37:90",
"created_at": "2025-10-08T08:49:39.071378",
"user_id": "64166c7effeb4a89b59c073588099640"
}
}
Imported Public Key
{
"keypair": {
"name": "apikey2",
"public_key": "ssh-rsa AAAA<...>",
"fingerprint": "67:c0:a2:8a:b4:c8:50:de:80:91:ed:79:14:17:37:90",
"created_at": "2025-10-08T08:53:28.769149",
"user_id": "64166c7effeb4a89b59c073588099640"
}
}
Notes & Best Practices
- Always store the returned
private_keysecurely (e.g. withchmod 600). It cannot be retrieved later. - Fingerprint comparisons help verify key integrity after upload.
- Use descriptive names; they are referenced when creating servers (
key_name). - For Ed25519 or other modern key types, ensure your cloud deployment supports them—otherwise import may fail with 400.
- Limit administrative usage of
user_idto necessary cases; audit such operations.