> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neuraltrust.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Application integrations

> Call TrustGuard from your own code — the Python and Node SDKs, framework middleware, or the raw REST API — around your model calls.

When you own the application, integrate TrustGuard directly around your model calls. This
gives you full control over what to inspect and how to enforce, and works with any model
provider. Create an API key on the collector first.

Prefer the official SDKs over hand-rolled HTTP — they take the base URL and call
`/v1/evaluate` for you:

| Language          | Package                                    |
| ----------------- | ------------------------------------------ |
| Node / TypeScript | `@neuraltrust/trustguard-sdk`              |
| Python            | `neuraltrust-trustguard`                   |
| Go                | `github.com/NeuralTrust/trustguard-sdk/go` |

The response carries a `status` (`allow` / `report` / `transform` / `block`); the SDKs
expose `is_blocked` / `isBlocked` (true when `status == "block"`) and the
`transformed_payload` for masked content.

## Input vs output (`direction`)

TrustGuard does **not** infer whether a payload is a prompt or a completion. Every
`guard()` / `/v1/evaluate` call must set **`direction`**:

| `direction`  | When to call                                     | Policy rules that run                              |
| ------------ | ------------------------------------------------ | -------------------------------------------------- |
| **`input`**  | Before the model call (user prompt / request)    | Detector rules configured for the **Input** phase  |
| **`output`** | After the model responds (completion / response) | Detector rules configured for the **Output** phase |

A [policy](/trustguard/concepts/policies) can attach different detectors (and actions) to
each phase — for example jailbreak / prompt injection on **input**, and PII or toxicity
on **output**. Only rules whose phase matches the request's `direction` run; the other
phase is skipped for that call.

To cover both sides of a turn you call TrustGuard **twice**:

```text theme={null}
user → guard(direction="input") → model → guard(direction="output") → user
```

If you only send `input`, output-phase detectors never evaluate. If you omit
`direction`, it defaults to **`input`**.

When traffic goes through [TrustGate](/trustguard/integrations/gateway) instead of your
app, the gateway sets `direction` for you (`input` on the request path, `output` on the
response path). Application integrations must set it explicitly.

See [How it works](/trustguard/how-it-works) for how rules are filtered by direction.

## Python SDK

1. `pip install neuraltrust-trustguard`
2. Call `client.guard()` with `direction="input"` before the model and
   `direction="output"` on the completion.
3. Pass `consumer_id` and `session_id` for attribution.
4. Block when `is_blocked` is true; forward `transformed_payload` when present.

```python theme={null}
from trustguard import TrustGuard

client = TrustGuard("<your-trustguard-url>", "<collector-api-key>")

# 1) Prompt — runs Input-phase detector rules
inbound = client.guard(
    {"input": user_input},
    direction="input",            # required for prompt / request evaluation
    consumer_id="alex@acme.com",  # who: user id, email, or device fingerprint
    session_id="sess-123",        # which conversation the message belongs to
)
if inbound.is_blocked:
    raise PermissionError("Blocked by TrustGuard (input)")
prompt = inbound.transformed_payload or {"input": user_input}

# … call your model with prompt …

# 2) Completion — runs Output-phase detector rules
outbound = client.guard(
    {"input": model_completion},
    direction="output",           # required for completion / response evaluation
    consumer_id="alex@acme.com",
    session_id="sess-123",
)
if outbound.is_blocked:
    raise PermissionError("Blocked by TrustGuard (output)")
# outbound.transformed_payload carries masked content when a Transform rule ran
```

## Node.js SDK

1. `npm install @neuraltrust/trustguard-sdk`
2. Call `client.guard()` with `direction: "input"` before the model and
   `direction: "output"` on the completion.
3. Pass `consumerId` and `sessionId`.
4. Block when `isBlocked` is true; forward `transformedPayload` when present.

```ts theme={null}
import { TrustGuard } from "@neuraltrust/trustguard-sdk";

const client = new TrustGuard({
  baseUrl: "<your-trustguard-url>",
  apiKey: "<collector-api-key>",
});

// 1) Prompt — runs Input-phase detector rules
const inbound = await client.guard({
  payload: { input: userInput },
  direction: "input",          // required for prompt / request evaluation
  consumerId: user.id,         // who: user id, email, or device fingerprint
  sessionId: conversationId,   // which conversation the message belongs to
});
if (inbound.isBlocked) throw new Error("Blocked by TrustGuard (input)");
const prompt = inbound.transformedPayload ?? { input: userInput };

// … call your model with prompt …

// 2) Completion — runs Output-phase detector rules
const outbound = await client.guard({
  payload: { input: modelCompletion },
  direction: "output",         // required for completion / response evaluation
  consumerId: user.id,
  sessionId: conversationId,
});
if (outbound.isBlocked) throw new Error("Blocked by TrustGuard (output)");
// outbound.transformedPayload carries masked content when a Transform rule ran
```

## REST API

Any language can call the guard endpoint directly (Go users: use the Go SDK instead of
hand-rolling). Set **`direction`** on every request — `"input"` for the prompt,
`"output"` for the completion — so TrustGuard applies the matching policy phase.

**Input (before the model):**

```bash theme={null}
curl -X POST "{TRUSTGUARD_URL}/v1/evaluate" \
  -H "Authorization: Bearer <collector-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "protocol": "llm",
    "direction": "input",
    "payload": { "input": "summarize this customer call" },
    "session_id": "sess-123",
    "consumer_id": "alex@acme.com"
  }'
```

**Output (after the model):**

```bash theme={null}
curl -X POST "{TRUSTGUARD_URL}/v1/evaluate" \
  -H "Authorization: Bearer <collector-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "protocol": "llm",
    "direction": "output",
    "payload": { "input": "Here is a summary of the customer call…" },
    "session_id": "sess-123",
    "consumer_id": "alex@acme.com"
  }'
```

```text theme={null}
# Response shape (both directions):
# { "status": "allow", "findings": [], "transformed_payload": null, "trace_id": "…", "request_id": "…" }
```

## Python middleware (FastAPI / Django / Flask)

Guard inbound user traffic in-process with a middleware in front of your AI routes.
Middleware typically covers the **request** path — set `direction="input"`. Guard the
model **response** in the route or service layer with `direction="output"`.

```python theme={null}
import json

from fastapi import FastAPI, Request
from starlette.responses import JSONResponse
from trustguard import AsyncTrustGuard

app = FastAPI()
client = AsyncTrustGuard("<your-trustguard-url>", "<collector-api-key>")

@app.middleware("http")
async def trustguard_middleware(request: Request, call_next):
    if request.method == "POST":
        body = await request.body()
        response = await client.guard(
            {"input": body.decode()},
            direction="input",  # Input-phase detectors only
            consumer_id=request.headers.get("x-user-id", ""),
            session_id=request.cookies.get("session_id", ""),
        )
        if response.is_blocked:
            return JSONResponse({"detail": "Blocked by TrustGuard"}, status_code=403)
        if response.transformed_payload:
            # Masked/rewritten content — forward it instead of the original body
            request._body = json.dumps(response.transformed_payload).encode()
    return await call_next(request)
```

## Node.js middleware (Express / Next.js)

Same pattern: middleware for **input**; call `guard` again with `direction: "output"`
after the model returns.

```ts theme={null}
import express from "express";
import { TrustGuard } from "@neuraltrust/trustguard-sdk";

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

const client = new TrustGuard({
  baseUrl: "<your-trustguard-url>",
  apiKey: "<collector-api-key>",
});

app.use(async (req, res, next) => {
  if (req.method !== "POST") return next();
  const response = await client.guard({
    payload: { input: JSON.stringify(req.body) },
    direction: "input", // Input-phase detectors only
    consumerId: req.get("x-user-id") ?? "",
    sessionId: req.cookies?.session_id ?? "",
  });
  if (response.isBlocked) {
    return res.status(403).json({ detail: "Blocked by TrustGuard" });
  }
  if (response.transformedPayload) {
    // Masked/rewritten content — forward it instead of the original body
    req.body = response.transformedPayload;
  }
  next();
});
```

## Tips

* Send documents/links via the `attachments` argument (folded into
  `payload.attachments`) to engage the
  [document and URL analyzers](/trustguard/detectors/content-security) — see the
  [Evaluate API](/trustguard/api/evaluate) for the attachment + SSRF rules.
* On a detector infrastructure error TrustGuard follows your deployment's fail-open /
  fail-closed setting — decide whether to hold traffic on errors accordingly.
