Documentation Index
Fetch the complete documentation index at: https://docs.jelou.ai/llms.txt
Use this file to discover all available pages before exploring further.
Wrap an external API by injecting credentials from secrets. The client calls your function, and your function calls the real API with the correct keys.
Pattern: route with parameters + authentication injection + response transformation.
import { define, z } from "@jelou/functions";
export default define({
name: "api-proxy",
description: "Proxy to an external API with injected authentication",
input: z.object({
fields: z.array(z.string()).optional().describe("Fields to include in the response"),
}),
config: {
path: "/users/:id",
methods: ["GET"],
cors: {
origin: "https://app.example.com",
credentials: true,
},
},
handler: async (input, ctx) => {
const apiKey = ctx.env.get("INTERNAL_API_KEY");
const baseUrl = ctx.env.get("API_BASE_URL");
ctx.log("Proxy request", {
userId: ctx.params.id,
fields: input.fields,
});
const res = await fetch(
`${baseUrl}/api/users/${ctx.params.id}`,
{ headers: { Authorization: `Bearer ${apiKey}` } },
);
if (!res.ok) {
ctx.log("Upstream error", { status: res.status, userId: ctx.params.id });
return { error: "not_found", status: res.status };
}
const user = await res.json();
const result: Record<string, unknown> = {
id: user.id,
name: user.name,
email: user.email,
};
if (input.fields?.includes("address")) {
result.address = user.address;
}
if (input.fields?.includes("orders")) {
result.recentOrders = user.orders?.slice(0, 5);
}
return result;
},
});
Local testing
curl "http://localhost:3000/users/42?fields=address,orders"
Why it works this way
config.path: "/users/:id" — the :id is captured in ctx.params.id.
- Credentials are never exposed to the client; they live in secrets.
cors.origin restricts which domains can call the proxy from the browser.
- You can transform or filter the response before returning it.