Skip to main content
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 — the runtime injects the credential, so your code holds no API key.
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 bytesput stores the string you pass verbatim (no base64, no envelope); get returns it byte-for-byte.
  • Missing keys read as nullget 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.
  • Errors throw — a non-2xx from the store (other than the 404null 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:
interface KvGetTextOptions { type?: "text" }   // default
interface KvGetJsonOptions { type: "json" }    // JSON.parse the stored value
// 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.
interface KvPutOptions {
  expirationTtl?: number;   // seconds
  metadata?: unknown;
}
await env.MY_KV.put("user/123", JSON.stringify({ name: "Alice" }));
expirationTtl and metadata are accepted but not yet applied — they exist on the type so code that sets them keeps compiling, but the runtime currently ignores them. KV does support server-side TTL over REST (?ttl_secs=) and the CLI (--ttl); it’s only this binding option that isn’t wired yet. For expiry from the binding today, use the application-level pattern.

delete(key)

Remove a key. Idempotent — deleting a missing key resolves normally.
await env.MY_KV.delete("user/123");

list(options?)

Enumerate keys (names only — list does not return values).
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;
  metadata?: unknown;
}
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.
KvKeyInfo.metadata is reserved for forward compatibility — KV has no per-key metadata today, so it is never populated. (The underlying REST list returns size_bytes and updated_at per key, which this binding does not currently surface.)
  • Overview — the KV Runtime API surface at a glance
  • Quick Start — declare the binding and generate types
  • REST API — the same operations over HTTP