# End-to-End Valiron Middleware Integration

This guide helps API teams integrate Valiron middleware from the first incoming
agent request through the downstream action they want to take. Start with the
agent identity, choose the trust signals that match your policy, then use the
gate result to protect an endpoint, vary access, attach pricing context, or
record the decision.

```text
Incoming request
  -> identify the agent
  -> evaluate selected trust signals
  -> receive an allow/deny decision, score, tier, and route
  -> apply your API policy
  -> serve, limit, sandbox, price, or deny
```

## Before you start

1. Create an operator account in the [Dashboard](./DASHBOARD.md).
2. Copy an operator API key (`val_op_...`) if you will use Pro trust signals,
   operator usage logging, or hosted products.
3. Install the SDK:

```bash
npm install @valiron/sdk
```

4. Choose the identity format your agent callers will send.

## 1. Identify every agent

Valiron middleware supports both identity paths automatically. Send one of the
following headers on the request to your API:

| Agent type | Header | Value | Setup |
| --- | --- | --- | --- |
| ERC-8004 EVM agent | `x-agent-id` | ERC-8004 token ID | Agent is registered on-chain |
| Solana agent | `x-agent-id` | Metaplex Core asset pubkey or supported indexed ID | Use `chain: "solana"` |
| Local, Web2, or non-ERC-8004 agent | `x-agent-address` | Persistent Ethereum-style address | Complete [key-based challenge-response](https://www.valiron.co/auth.md) first |

Do not send a local agent name to `x-agent-id`. Key-based agents must prove
ownership of their persistent address before they can pass an identity-aware
policy.

> **Hosted wrapper note:** Valiron-hosted API Scaffolding currently requires
> `x-agent-id` when its trust check is enabled. Use the SDK middleware in your
> own backend for a policy that accepts either identity path.

## 2. Choose trust signals

Pass `trustSignals` to the middleware configuration. Start with the default
baseline, then add signals only when they are meaningful for the action you are
protecting.

| Signal | What it contributes | Availability |
| --- | --- | --- |
| `8004` | Registry-backed on-chain identity and reputation | All plans |
| `sandbox` | Behavioral evaluation and route readiness | All plans |
| `world` | World ID proof-of-personhood linkage | Pro |
| `self` | Self eligible-human verification | Pro |
| `icebreaker` | Human-to-agent attestation | Pro |
| `wallet` | Explainable wallet-history risk, confidence, and hard flags | Pro |

For example, a high-value endpoint might require on-chain reputation,
behavioral evidence, and wallet intelligence:

```typescript
import { ValironSDK, createValironGate } from "@valiron/sdk";

const valiron = new ValironSDK({
  apiKey: process.env.VALIRON_API_KEY,
  chain: "base",
});

const trustGate = createValironGate({
  sdk: valiron,
  trustSignals: ["8004", "sandbox", "wallet"],
  minScore: 80,
});
```

If a wallet-history provider is unavailable or a network is unsupported, its
result is neutral and excluded from the composite score rather than treated as
malicious. See [Trust Model](./TRUST-MODEL.md) for the complete signal model.

## 3. Choose the downstream behavior

The middleware attaches a normalized result to the request after a successful
check. It includes `allow`, `score`, `tier`, `riskLevel`, `route`, and the
resolved `agentId`, regardless of which supported identity header the agent
used.

Choose the behavior that fits the endpoint:

| Goal | Use the decision for |
| --- | --- |
| Trust gate | Allow trusted agents and return a denial before your handler runs |
| Graduated access | Serve full access for `prod`, apply limits for `prod_throttled`, and use test data for sandbox routes |
| Trust-aware pricing | Read the result in your handler and apply your own price or entitlement policy |
| Monetized endpoint logging | Use `ValironOperator.paywall()` to gate access, attach a configured per-call price, and record usage |
| Agent profile lookup | Retrieve a profile when your product needs to display or review trust evidence |
| Predictive risk | Use dashboard/API forecasts as an additional operational signal; do not replace the runtime gate with a forecast |
| Audit and operations | Capture the result in your logs or use dashboard call logs and evaluation history |

Valiron does not itself settle a payment or choose a dynamic price table. It
provides the verified trust context that your payment and application policy
can use.

## 4. Put the gate in front of your handler

Here is a complete Express example that supports both agent identity paths and
uses the route decision for graduated access:

```typescript
import express from "express";
import { ValironSDK, createValironGate } from "@valiron/sdk";

const app = express();
const valiron = new ValironSDK({
  apiKey: process.env.VALIRON_API_KEY,
  chain: "base",
});

app.use("/api/research", createValironGate({
  sdk: valiron,
  trustSignals: ["8004", "sandbox", "wallet"],
  minScore: 65,
}));

app.get("/api/research", (req, res) => {
  const trust = (req as typeof req & { valiron: {
    route: "prod" | "prod_throttled" | "sandbox" | "sandbox_only";
    score: number;
    tier: string;
  } }).valiron;

  if (trust.route === "prod_throttled") {
    res.set("X-Rate-Limit-Policy", "reduced");
  }

  if (trust.route === "sandbox") {
    return res.json({ mode: "sandbox", results: [] });
  }

  return res.json({
    mode: "production",
    trust: { score: trust.score, tier: trust.tier },
    results: [/* your production response */],
  });
});

app.listen(3000);
```

The middleware checks `x-agent-id` first, then `x-agent-address`. If there is
no supported identity, the agent is denied. If an agent is pending its first
behavioral evaluation, it receives a retryable denial while sandbox evaluation
runs.

## 5. Add a pricing or payment policy

For a server-side endpoint with a fixed price and usage logging, use the
operator SDK. It gates the route, makes the decision available as
`req.valiron`, and records the configured price only for successful allowed
calls.

```typescript
import { ValironOperator } from "@valiron/sdk";

const operator = new ValironOperator({
  apiKey: process.env.VALIRON_API_KEY!,
  chain: "base",
});

app.use("/api/premium", operator.paywall({
  pricePerCall: 0.05,
  minTrustScore: 65,
  trustSignals: ["8004", "sandbox", "wallet"],
}));
```

If your payment provider supports multiple prices, select the price in your
handler from `req.valiron.tier`, `score`, or `route`. Keep payment settlement
in that provider; use Valiron first to decide whether the caller is eligible
to reach it.

## 6. Test the complete request path

Test each case before production:

1. A registered agent using `x-agent-id`.
2. A verified key-based agent using `x-agent-address`.
3. A request without either identity header.
4. An agent below your `minScore`.
5. A new agent pending sandbox evaluation.
6. A production-eligible agent on every protected route.
7. A paid or priced request, verifying that trust denial happens before your
   payment or application handler.

Use the [Dashboard Playground](./DASHBOARD.md#api-playground) to inspect
decisions and the Dashboard's call logs to review outcome, latency, price, and
trust context after launch.

## Next steps

- [Quickstart](./QUICKSTART.md) — protect a first endpoint quickly
- [SDK Reference](./SDK-REFERENCE.md#middleware) — Express, Fastify, Next.js,
  and generic middleware APIs
- [Identity](./IDENTITY.md) — registry and key-based identity details
- [Trust Model](./TRUST-MODEL.md) — signals, tiers, and routes
- [API Scaffolding](./AGENT-READY-APIS.md) — hosted x402/MPP wrappers for an
  existing API
