Skip to main content
Get up and running with KV by creating a namespace, binding it to your function, and reading/writing data.

1. Create a Namespace

telnyx-edge storage kv create --name my-cache
The namespace name may contain only lowercase letters, numbers, and hyphens. Namespace creation is asynchronous — poll the namespace endpoint until status changes from pending to provision_ok.

2. Add to Your Function

Configure the binding in func.toml:
[edge_compute]
func_name = "my-function"

[storage.kv.MY_CACHE]
id = "550e8400-e29b-41d4-a716-446655440000"  # Namespace ID returned by the create API (a UUID)

3. Access KV in Your Code

KV is accessed over HTTP (a native SDK is planned). A value is stored and returned verbatim — there is no base64 encoding and no JSON envelope, so you send the raw value as the request body and read the raw bytes back.
const KV_NAMESPACE_ID = process.env.KV_MY_CACHE_ID;
const API_KEY = process.env.TELNYX_API_KEY;
const BASE = `https://api.telnyx.com/v2/storage/kvs/${KV_NAMESPACE_ID}/keys`;

async function kvGet(key) {
    const res = await fetch(`${BASE}/${encodeURIComponent(key)}`, {
        headers: { "Authorization": `Bearer ${API_KEY}` }
    });
    if (res.status === 404) return null;             // Key not found
    if (!res.ok) throw new Error(`KV read error: ${res.status}`);
    return await res.text();                          // Value is the raw stored bytes
}

async function kvPut(key, value) {
    const res = await fetch(`${BASE}/${encodeURIComponent(key)}`, {
        method: "PUT",
        headers: { "Authorization": `Bearer ${API_KEY}` },
        body: value                                   // Stored verbatim — no base64, no envelope
    });
    if (!res.ok) throw new Error(`KV write error: ${res.status}`);
}

export async function handler(request) {
    // Write a value (UTF-8 is preserved as-is)
    await kvPut("user/123", JSON.stringify({ name: "Alice 👋" }));

    // Read it back -> '{"name":"Alice 👋"}'
    const user = await kvGet("user/123");

    return new Response(user);
}
A native SDK is planned. Until it ships, use the HTTP endpoints shown above.

Best Practices

Key Naming

Keys may contain a-z, A-Z, 0-9, and - _ / = . (no colons). Use / to group related keys:
user/123              # User data
session/abc           # Session data
cache/api/users       # Cached API response
flag/new-feature      # Feature flag

Value Serialization

KV stores values verbatim, so serialize complex values yourself (no base64 needed):
// Write
const value = JSON.stringify({ name: "Alice", age: 30 });
await kvPut("user/123", value);

// Read
const user = JSON.parse(await kvGet("user/123"));

Error Handling

Handle missing keys gracefully:
const value = await kvGet("possibly-missing-key");
if (value === null) {
    // Key doesn't exist
    return new Response("Not found", { status: 404 });
}