> For the complete documentation index, see [llms.txt](https://docs.layerlens.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.layerlens.ai/more-in-this-section-4/calling-stratix-from-a-backend.md).

# Calling Stratix from a backend

Stratix API keys are server-side credentials. They must never be sent to the browser. Production frontends call **your backend**, which calls Stratix.

## The pattern

```
[Browser] → [Your backend] → [Stratix API]
 key in env X-API-Key header
```

Your backend holds `LAYERLENS_STRATIX_API_KEY` in environment variables (or a secrets manager). The browser never sees it.

## Next.js (TypeScript)

`app/api/evaluation/route.ts`:

```typescript
import { NextRequest, NextResponse } from "next/server";

export async function POST(req: NextRequest) {
 const body = await req.json();

 const stratix = await fetch("https://stratix.layerlens.ai/api/v1/evaluations", {
 method: "POST",
 headers: {
 "X-API-Key": process.env.LAYERLENS_STRATIX_API_KEY!,
 "Content-Type": "application/json",
 },
 body: JSON.stringify({
 model_id: body.model_id,
 benchmark_id: body.benchmark_id,
 }),
 });

 return NextResponse.json(await stratix.json(), { status: stratix.status });
}
```

**Critical:** the env var name is `LAYERLENS_STRATIX_API_KEY` — never prefix with `NEXT_PUBLIC_` (that exposes it to the browser bundle).

## Express (Node)

```typescript
import express from "express";

const app = express();
app.use(express.json());

app.post("/api/evaluation", async (req, res) => {
 const r = await fetch("https://stratix.layerlens.ai/api/v1/evaluations", {
 method: "POST",
 headers: {
 "X-API-Key": process.env.LAYERLENS_STRATIX_API_KEY!,
 "Content-Type": "application/json",
 },
 body: JSON.stringify(req.body),
 });
 res.status(r.status).json(await r.json());
});
```

## Go (net/http)

```go
package main

import (
 "bytes"
 "encoding/json"
 "io"
 "net/http"
 "os"
)

func evaluationHandler(w http.ResponseWriter, r *http.Request) {
 body, _ := io.ReadAll(r.Body)
 req, _ := http.NewRequest("POST", "https://stratix.layerlens.ai/api/v1/evaluations", bytes.NewReader(body))
 req.Header.Set("X-API-Key", os.Getenv("LAYERLENS_STRATIX_API_KEY"))
 req.Header.Set("Content-Type", "application/json")
 resp, err := http.DefaultClient.Do(req)
 if err != nil {
 http.Error(w, err.Error(), 500)
 return
 }
 defer resp.Body.Close()
 out, _ := io.ReadAll(resp.Body)
 var v any
 json.Unmarshal(out, &v)
 w.Header().Set("Content-Type", "application/json")
 w.WriteHeader(resp.StatusCode)
 w.Write(out)
}
```

## Python (FastAPI)

```python
from fastapi import FastAPI, Request
from layerlens import Stratix
import os

app = FastAPI()
stratix = Stratix(api_key=os.environ["LAYERLENS_STRATIX_API_KEY"])

@app.post("/api/evaluation")
async def create_evaluation(req: Request):
 body = await req.json()
 e = stratix.evaluations.create(model_id=body["model_id"], benchmark_id=body["benchmark_id"])
 return {"id": e.id}
```

## Why not call Stratix directly from the browser?

* **Key exposure.** Anything in browser source is public. A Stratix API key in browser code = a leaked key.
* **CORS.** Stratix does not return CORS headers. Browsers will reject direct API calls anyway.
* **Audit trail.** Backend-mediated calls give you one place to log, rate-limit, and authorize per-user.

## Per-user authorization

The browser doesn't have a Stratix key — that's good. Your backend authorizes the **user**, then makes the Stratix call on their behalf. Map your user's permissions to the right Stratix-side action; never expose a raw "create-anything" endpoint to anonymous browsers.

## Streaming responses to the browser

If you want live progress to the browser, your backend can stream Stratix's polling result via SSE or WebSocket to your client.

## CORS guidance

Stratix's API does **not** emit CORS headers. Browser-direct calls will fail preflight. Always proxy through your backend. If you need CORS on your own proxy endpoints, that's between your backend and your browser — Stratix is unaffected.

## See also

* [Surfaces: REST API](/13.2-surfaces/rest-api.md)
* [Cookbook: Vercel AI SDK instrumentation](/6.-build-wire-your-code/instrument-vercel-ai-sdk.md)
* [Authentication](/more-in-this-section-9/authentication.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.layerlens.ai/more-in-this-section-4/calling-stratix-from-a-backend.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
