Skip to main content
Bite-sized code snippets for common edge function patterns. Each example is self-contained — copy, paste, deploy.

Return JSON

export async function handler(request) {
    const data = {
        success: true,
        data: { id: 123, name: "John" }
    };

    return new Response(JSON.stringify(data), {
        headers: { "Content-Type": "application/json" }
    });
}

Return HTML

export async function handler(request) {
    const html = `
        <!DOCTYPE html>
        <html>
            <body><h1>Hello from Edge</h1></body>
        </html>
    `;

    return new Response(html, {
        headers: { "Content-Type": "text/html" }
    });
}

Return Binary

export async function handler(request) {
    const imageResponse = await fetch("https://your-bucket.s3.amazonaws.com/logo.png");
    const imageData = await imageResponse.arrayBuffer();

    return new Response(imageData, {
        headers: { "Content-Type": "image/png" }
    });
}

Parse Query Parameters

export async function handler(request) {
    const url = new URL(request.url);
    const name = url.searchParams.get("name") || "World";

    return new Response(JSON.stringify({
        message: `Hello ${name} from Telnyx Edge Compute!`,
        status: "success"
    }), {
        headers: { "Content-Type": "application/json" }
    });
}

Handle HTTP Methods

export async function handler(request) {
    const { method } = request;

    let message;
    let status = 200;

    switch (method) {
        case "GET":
            message = "Hello from GET request!";
            break;
        case "POST":
            message = "Data received via POST!";
            break;
        default:
            message = "Method not supported";
            status = 405;
    }

    return new Response(JSON.stringify({ message, status: status === 200 ? "success" : "error" }), {
        status,
        headers: { "Content-Type": "application/json" }
    });
}

Read Request Body

export async function handler(request) {
    try {
        const body = await request.json();

        if (!body.email) {
            return new Response(JSON.stringify({ error: "Email is required" }), {
                status: 400,
                headers: { "Content-Type": "application/json" }
            });
        }

        return new Response(JSON.stringify({ status: "success", email: body.email }), {
            headers: { "Content-Type": "application/json" }
        });
    } catch {
        return new Response(JSON.stringify({ error: "Invalid JSON" }), {
            status: 400,
            headers: { "Content-Type": "application/json" }
        });
    }
}

Use Environment Variables

export async function handler(request) {
    const greeting = process.env.GREETING || "Hello";

    return new Response(JSON.stringify({
        message: `${greeting} from Telnyx Edge Compute!`,
        status: "success"
    }), {
        headers: { "Content-Type": "application/json" }
    });
}

Access Secrets

Secrets are injected as environment variables but stored encrypted. Use them for API keys, tokens, and credentials.
export async function handler(request) {
    const apiKey = process.env.EXTERNAL_API_KEY;

    if (!apiKey) {
        return new Response(JSON.stringify({ error: "API key not configured" }), {
            status: 500,
            headers: { "Content-Type": "application/json" }
        });
    }

    const response = await fetch("https://api.example.com/data", {
        headers: { "Authorization": `Bearer ${apiKey}` }
    });

    const data = await response.json();
    return new Response(JSON.stringify(data), {
        headers: { "Content-Type": "application/json" }
    });
}

KV Read/Write

Coming Soon — KV storage is in development. The examples below show the expected API pattern.
Access KV storage for low-latency key-value data.
const KV_ID = process.env.KV_MY_STORE_ID;
const API_KEY = process.env.TELNYX_API_KEY;
const BASE_URL = `https://api.telnyx.com/v2/storage/kvs/${KV_ID}`;

async function kvGet(key) {
    const response = await fetch(`${BASE_URL}/keys/${key}`, {
        headers: { "Authorization": `Bearer ${API_KEY}` }
    });
    if (response.status === 404) return null;
    const data = await response.json();
    return data.value;
}

async function kvPut(key, value, ttl) {
    await fetch(`${BASE_URL}/keys/${key}`, {
        method: "PUT",
        headers: {
            "Authorization": `Bearer ${API_KEY}`,
            "Content-Type": "application/json"
        },
        body: JSON.stringify({ value, ttl })
    });
}

export async function handler(request) {
    const cachedValue = await kvGet("user:123");

    if (cachedValue) {
        return new Response(cachedValue, {
            headers: { "Content-Type": "application/json" }
        });
    }

    const userData = JSON.stringify({ id: 123, name: "Alice" });
    await kvPut("user:123", userData, 3600);

    return new Response(userData, {
        headers: { "Content-Type": "application/json" }
    });
}

Cron Trigger

Coming Soon — Native cron triggers are planned. The examples below show the expected pattern. Until then, use an external scheduler (GitHub Actions, AWS EventBridge) to call your function’s HTTP endpoint.
Functions can be triggered on a schedule via cron triggers. The request includes cron metadata.
export async function handler(request) {
    const isCron = request.headers.get("X-Telnyx-Cron") === "true";
    const scheduleName = request.headers.get("X-Telnyx-Cron-Schedule");

    if (isCron) {
        console.log(`Cron job triggered: ${scheduleName}`);

        await cleanupExpiredSessions();
        await sendDailyReport();

        return new Response(JSON.stringify({ status: "cron completed" }), {
            headers: { "Content-Type": "application/json" }
        });
    }

    return new Response(JSON.stringify({ status: "ok" }), {
        headers: { "Content-Type": "application/json" }
    });
}

async function cleanupExpiredSessions() {
    // Your cleanup logic
}

async function sendDailyReport() {
    // Your reporting logic
}

WebSocket Handling

Coming Soon — WebSocket support is planned. The examples below show the expected pattern.
Handle WebSocket connections for real-time communication.
import (
    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool { return true },
}

func handler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        http.Error(w, "WebSocket upgrade failed", http.StatusBadRequest)
        return
    }
    defer conn.Close()

    conn.WriteJSON(map[string]interface{}{
        "type":      "connected",
        "timestamp": time.Now().Unix(),
    })

    for {
        var msg map[string]interface{}
        if err := conn.ReadJSON(&msg); err != nil {
            break
        }

        conn.WriteJSON(map[string]interface{}{
            "type":       "echo",
            "original":   msg,
            "serverTime": time.Now().Unix(),
        })
    }
}

Service-to-Service Calls

Call other edge functions or external services with proper error handling and timeouts.
const INTERNAL_SERVICE_URL = process.env.USER_SERVICE_URL;

export async function handler(request) {
    const { userId } = await request.json();

    try {
        const controller = new AbortController();
        const timeout = setTimeout(() => controller.abort(), 5000);

        const userResponse = await fetch(`${INTERNAL_SERVICE_URL}/users/${userId}`, {
            headers: {
                "Authorization": request.headers.get("Authorization"),
                "X-Request-ID": request.headers.get("X-Request-ID") || crypto.randomUUID()
            },
            signal: controller.signal
        });

        clearTimeout(timeout);

        if (!userResponse.ok) {
            return new Response(JSON.stringify({ error: "User service error" }), {
                status: userResponse.status,
                headers: { "Content-Type": "application/json" }
            });
        }

        const user = await userResponse.json();

        return new Response(JSON.stringify({ user }), {
            headers: { "Content-Type": "application/json" }
        });

    } catch (error) {
        if (error.name === "AbortError") {
            return new Response(JSON.stringify({ error: "Service timeout" }), {
                status: 504,
                headers: { "Content-Type": "application/json" }
            });
        }
        throw error;
    }
}

Connection Reuse

Initialize HTTP clients once at module level to reuse connections across requests.
// Module-level client (reused across requests)
const httpClient = {
    baseUrl: "https://api.example.com",
    headers: {
        "Authorization": `Bearer ${process.env.API_KEY}`,
        "Content-Type": "application/json"
    }
};

export async function handler(request) {
    const response = await fetch(`${httpClient.baseUrl}/data`, {
        headers: httpClient.headers
    });

    return new Response(await response.text(), {
        headers: { "Content-Type": "application/json" }
    });
}