# Add an SFTP key

Page: https://sandbox.myclaimhouse.com/docs/api/addSftpKey

`POST /api/v1/sftp-account/keys`

Adds a public key that may log in, under a label. Send the key as one OpenSSH line: ssh-ed25519, ecdsa-sha2-nistp256, -nistp384 or -nistp521, or ssh-rsa of at least 2048 bits; a comment after the key is dropped. An account takes at most 5 keys and a key once: either refusal is CONFLICT. The label is 1 to 64 characters with no control characters. Needs an Idempotency-Key header and a key with the submit permission.

Needs a key with `submit` permission.

## Request

### Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | Yes | Makes the request safe to repeat: a request with the same key and body returns the first answer (the reply has an idempotent-replayed header), and the same key with a different request is refused. 1 to 255 printable characters; a UUID is a good choice. At least 1 character. At most 255 characters. Matches `^[\x21-\x7e]{1,255}$`. |

### Body

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `label` | string | Yes | A name to tell the key by: 1 to 64 characters, no control characters. At least 1 character. At most 64 characters. |
| `public_key` | string | Yes | The public key as one OpenSSH line (ssh-ed25519, ecdsa-sha2-nistp256/384/521 or ssh-rsa of at least 2048 bits). A comment after the key is dropped. At most 8192 characters. |

## Response

The key. Status `201`.

| Name | Type | Description |
| --- | --- | --- |
| `id` | string | An ID that starts with sfk_. |
| `object` | string | Always `sftp_key`. |
| `label` | string | The name you gave the key. At most 64 characters. |
| `fingerprint` | string | The key's SHA256 fingerprint, as ssh-keygen -l shows it. |
| `added_at` | string (date-time) |  |

## Errors

| HTTP status | Code | What it means |
| --- | --- | --- |
| 401 | `UNAUTHORIZED` | A valid API key is required. Send it as "Authorization: Bearer <key>". |
| 403 | `PERMISSION_DENIED` | This API key is not allowed to do that. |
| 404 | `NOT_FOUND` | Not found. |
| 422 | `INVALID_REQUEST` | The request is not valid. |
| 400 | `IDEMPOTENCY_KEY_REQUIRED` | POST and PATCH requests need an Idempotency-Key header. |
| 422 | `IDEMPOTENCY_KEY_REUSED` | That Idempotency-Key was already used with a different request. |
| 409 | `IDEMPOTENCY_KEY_IN_USE` | A request with that Idempotency-Key is still running. Retry shortly. |
| 413 | `PAYLOAD_TOO_LARGE` | The request body is larger than 1 MB. |
| 504 | `TIMEOUT` | The request took too long to finish. It may still have taken effect: look it up before sending it again with a new Idempotency-Key. What it made is found with GET /api/v1/eligibility?request_id=<this request_id>, and the same filter on /api/v1/claims and /api/v1/attachments (a key with read permission). |
| 409 | `CONFLICT` | The resource is not in a state that allows this, or it changed while the request was handled. Read it, then decide whether to send the request again. |
| 500 | `INTERNAL` | Something went wrong on our side. Quote the request ID if you contact us. |

## Example

### Example request

```bash
curl -X POST "https://sandbox.myclaimhouse.com/api/v1/sftp-account/keys" \
  -H "Authorization: Bearer $CLAIMHOUSE_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "label": "Billing server",
  "public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl billing-server"
}'
```

### Example response: 201

```json
{
  "id": "sfk_01JM000000E00800000000008H",
  "object": "sftp_key",
  "label": "Billing server",
  "fingerprint": "SHA256:Nn0vBzE3Lx9sT2kqYw7dPfH5cRj8uAm1GoVtXiQ4eZs",
  "added_at": "2026-09-24T15:05:00+00:00"
}
```
