> ## Documentation Index
> Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# KV API Reference

> Complete REST API reference for Telnyx KV namespaces and keys, including endpoints, request parameters, and response formats.

Complete reference for the KV REST API. Base URL: `https://api.telnyx.com/v2/storage/kvs`

## Namespace Endpoints

| Method | Endpoint               | Description            |
| ------ | ---------------------- | ---------------------- |
| POST   | `/v2/storage/kvs`      | Create a new namespace |
| GET    | `/v2/storage/kvs`      | List all namespaces    |
| GET    | `/v2/storage/kvs/{id}` | Get namespace details  |
| DELETE | `/v2/storage/kvs/{id}` | Delete a namespace     |

## Key-Value Endpoints

| Method | Endpoint                          | Description   |
| ------ | --------------------------------- | ------------- |
| PUT    | `/v2/storage/kvs/{id}/keys/{key}` | Write a value |
| GET    | `/v2/storage/kvs/{id}/keys/{key}` | Read a value  |
| DELETE | `/v2/storage/kvs/{id}/keys/{key}` | Delete a key  |
| GET    | `/v2/storage/kvs/{id}/keys`       | List keys     |

***

## Namespace Operations

### Create Namespace

The `name` may contain only lowercase letters, numbers, and hyphens.

```bash theme={null}
curl -X POST https://api.telnyx.com/v2/storage/kvs \
  -H "Authorization: Bearer $TELNYX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-cache"}'
```

Response:

```json theme={null}
{
  "data": {
    "record_type": "storage_kv",
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "my-cache",
    "status": "pending",
    "created_at": "2024-01-15T10:30:00.000Z",
    "updated_at": "2024-01-15T10:30:00.000Z"
  }
}
```

### Namespace Status

Poll the namespace until status is `provision_ok`:

| Status             | Description                 |
| ------------------ | --------------------------- |
| `pending`          | Provisioning in progress    |
| `provision_ok`     | Ready to use                |
| `provision_failed` | Provisioning failed         |
| `deleting`         | Deletion in progress        |
| `delete_failed`    | Deletion failed             |
| `deleted`          | Fully removed (returns 404) |

***

## Key-Value Operations

### Keys

A key is a path-like string. Allowed characters: `a-z`, `A-Z`, `0-9`, and `-` `_` `/` `=` `.`. Use `/` to group related keys (for example `user/123`). A key with any other character (such as `:`) is rejected with `400` (error code `10015`).

### Write a Value

The request body **is** the value — KV stores the raw bytes you send, verbatim. There is no base64 encoding and no JSON envelope.

```bash theme={null}
curl -X PUT "https://api.telnyx.com/v2/storage/kvs/{id}/keys/my-key" \
  -H "Authorization: Bearer $TELNYX_API_KEY" \
  --data-binary "Hello World"
```

Returns `201` when the key is created and `200` when an existing key is updated; the response body is empty.

<Note>
  KV has no server-side TTL or per-key metadata. To expire keys, store an expiry timestamp inside the value and check it on read — see [Key expiration](/docs/edge-compute/kv/ttl-and-metadata).
</Note>

### Read a Value

```bash theme={null}
curl "https://api.telnyx.com/v2/storage/kvs/{id}/keys/my-key" \
  -H "Authorization: Bearer $TELNYX_API_KEY"
```

The response body is the raw stored value (`Content-Type: application/octet-stream`):

```
Hello World
```

A missing key returns `404`.

### Delete a Key

```bash theme={null}
curl -X DELETE "https://api.telnyx.com/v2/storage/kvs/{id}/keys/my-key" \
  -H "Authorization: Bearer $TELNYX_API_KEY"
```

### List Keys

```bash theme={null}
curl "https://api.telnyx.com/v2/storage/kvs/{id}/keys?prefix=user/&limit=100" \
  -H "Authorization: Bearer $TELNYX_API_KEY"
```

Query parameters:

* `prefix` — Filter keys by prefix
* `cursor` — Pagination cursor from a previous response's `meta.cursor`
* `limit` — Maximum keys to return, `1`–`1000` (default `1000`)

Response (keys only — list does not return values):

```json theme={null}
{
  "record_type": "storage_kv_key",
  "data": [
    {
      "key": "user/123",
      "size_bytes": 21,
      "updated_at": "2026-06-18T14:48:17.475129983Z"
    }
  ],
  "meta": {
    "has_more": false
  }
}
```

When `meta.has_more` is `true`, the response includes `meta.cursor`; pass it back as the `cursor` query parameter to fetch the next page.

***

## Bindings Configuration

Connect your function to a KV namespace using bindings in `func.toml`:

```toml theme={null}
[edge_compute]
func_name = "my-function"

[storage.kv.MY_CACHE]
id = "550e8400-e29b-41d4-a716-446655440000"

[storage.kv.SESSION_STORE]
id = "660f9500-f39c-51e5-b817-557766551111"
```

The binding name (e.g., `MY_CACHE`) is surfaced to your function as an environment variable:

* `KV_MY_CACHE_ID` — The namespace ID
