> ## 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.

# KvNamespace

> The KV binding surface exported from @telnyx/edge-runtime — get, put, delete, and list on env.<BINDING>, with option and result types and their runtime behavior.

`env.<BINDING>` (a `KvNamespace`) is the in-function handle to a KV namespace. It's a thin, pre-authenticated wrapper over the [KV REST API](/docs/edge-compute/kv/quick-start#path-b-the-rest-api) — the runtime injects the credential, so your code holds no API key.

```ts theme={null}
interface KvNamespace {
  get(key: string, options?: KvGetTextOptions): Promise<string | null>;
  get<T>(key: string, options: KvGetJsonOptions): Promise<T | null>;
  put(key: string, value: string, options?: KvPutOptions): Promise<void>;
  delete(key: string): Promise<void>;
  list(options?: KvListOptions): Promise<KvListResult>;
}
```

Key behaviors:

* **Values are opaque bytes** — `put` stores the string you pass verbatim (no base64, no envelope); `get` returns it byte-for-byte.
* **Missing keys read as `null`** — `get` resolves to `null` for a key that doesn't exist, not an error.
* **`delete` is idempotent** — deleting a missing key succeeds.
* **Read-your-writes** — a read after a successful `put` from the same location reflects it. See [Consistency](/docs/edge-compute/kv/concepts/how-kv-works#consistency-and-regionality).
* **Errors throw** — a non-2xx from the store (other than the `404`→`null` on `get`) rejects the promise with an `Error` describing the operation and status.

## `get(key, options?)`

Read a value. Two overloads, selected by `options.type`:

```ts theme={null}
interface KvGetTextOptions { type?: "text" }   // default
interface KvGetJsonOptions { type: "json" }    // JSON.parse the stored value
```

```ts theme={null}
// Text (default) -> string | null
const raw = await env.MY_KV.get("user/123");

// JSON -> T | null (JSON.parse applied; an empty stored value yields null)
const user = await env.MY_KV.get<{ name: string }>("user/123", { type: "json" });
```

Returns `null` if the key does not exist. With `{ type: "json" }`, a malformed stored value throws from `JSON.parse`.

## `put(key, value, options?)`

Write a value. `value` is a string, stored verbatim. Resolves once the write is acknowledged.

```ts theme={null}
interface KvPutOptions {
  expirationTtl?: number;   // seconds until the key expires server-side
  /** @deprecated Not supported by the API. Accepted but ignored. */
  metadata?: unknown;
}
```

```ts theme={null}
await env.MY_KV.put("user/123", JSON.stringify({ name: "Alice" }));

// Expire automatically after one hour
await env.MY_KV.put("session/abc", token, { expirationTtl: 3600 });
```

`expirationTtl` maps to the REST API's `?ttl_secs=` parameter: the key is deleted server-side roughly that many seconds after the write. The value is floored to a whole number of seconds; anything below `1` is not sent — the write succeeds without a TTL. See [Key Expiration](/docs/edge-compute/kv/ttl-and-metadata).

<Note>
  `expirationTtl` requires `@telnyx/edge-runtime` **≥ 0.2.2** — earlier versions accept it but silently ignore it. `metadata` is ignored on every version (KV has no per-key metadata); it remains on the type, deprecated, so code that sets it keeps compiling.
</Note>

## `delete(key)`

Remove a key. Idempotent — deleting a missing key resolves normally.

```ts theme={null}
await env.MY_KV.delete("user/123");
```

## `list(options?)`

Enumerate keys (names only — `list` does not return values).

```ts theme={null}
interface KvListOptions {
  prefix?: string;
  limit?: number;
  cursor?: string;   // from a previous result's `cursor`
}

interface KvListResult {
  keys: KvKeyInfo[];
  list_complete: boolean;
  cursor?: string;   // present when list_complete is false
}

interface KvKeyInfo {
  name: string;
  sizeBytes?: number;   // stored value size, from the API's size_bytes
  updatedAt?: Date;     // last write time, from the API's updated_at
  /** @deprecated Not populated by the API. Always undefined. */
  metadata?: unknown;
}
```

```ts theme={null}
const { keys } = await env.MY_KV.list({ prefix: "user/" });
// [{ name: "user/123", sizeBytes: 21, updatedAt: 2026-06-18T14:48:17.475Z }, …]
```

<Note>
  `list()` requires `@telnyx/edge-runtime` ≥ 0.2.1 — on 0.2.0 it throws `Unexpected KV list response shape`, because that release's parser predates the current API list format. `sizeBytes` and `updatedAt` are populated from **0.2.2**; on 0.2.1 entries carry only `name`.
</Note>

`KvKeyInfo.metadata` is never populated — KV has no per-key metadata. It remains on the type, deprecated, so code that reads it keeps compiling.

## Related

* [Overview](/docs/edge-compute/kv/reference) — the KV Runtime API surface at a glance
* [Quick Start](/docs/edge-compute/kv/quick-start#path-a-the-function-binding) — declare the binding and type it
* [REST API](/docs/edge-compute/kv/quick-start#path-b-the-rest-api) — the same operations over HTTP
