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

# Next.js Middleware

> Trust-gating middleware for Next.js edge runtime

## Installation

```bash theme={null}
npm install @cred-protocol/nextjs @cred-protocol/sdk
```

## Quick Start

Create `middleware.ts` in your project root:

```typescript theme={null}
// middleware.ts
import { credGates } from '@cred-protocol/nextjs'

export const middleware = credGates({
  apiKey: process.env.CRED_API_KEY!,
  policy: 'standard',
  matcher: ['/api/:path*'],
})

export const config = {
  matcher: ['/api/:path*'],
}
```

Every request to `/api/*` is evaluated before reaching your route handler. Wallets that fail the trust check receive a 402 or 403 response at the edge — your API handlers only see trusted traffic.

## Configuration

```typescript theme={null}
credGates({
  // Required
  apiKey: process.env.CRED_API_KEY!,

  // Policy (pick one)
  policy: 'standard',
  // gates: ['human', 'verified'],
  // operator: 'AND',

  // Route matching
  matcher: ['/api/:path*'],        // Only gate these routes

  // Dynamic pricing
  pricing: {
    enabled: true,
    curve: 'step',
    basePriceUsdc: 0.01,
  },

  // Failure handling
  on402: 'challenge',              // 'challenge' (402), 'deny' (403), 'pass'

  // Custom wallet extraction
  extractWallet: (req) => req.headers.get('x-agent-wallet'),
})
```

## Wallet Address Extraction

By default the middleware checks:

1. `X-Wallet-Address` request header
2. `?wallet=` query parameter

Override with `extractWallet`:

```typescript theme={null}
credGates({
  apiKey: process.env.CRED_API_KEY!,
  policy: 'standard',
  matcher: ['/api/:path*'],
  extractWallet: (req) => {
    return req.headers.get('x-agent-wallet')
      || req.nextUrl.searchParams.get('address')
  },
})
```

## Response Headers

Requests that pass trust checks get these headers set on the response:

| Header                    | Example        | Description                           |
| ------------------------- | -------------- | ------------------------------------- |
| `X-Cred-Trust-Score`      | `75`           | 0–100 composite score                 |
| `X-Cred-Trust-Tier`       | `verified`     | Trust tier classification             |
| `X-Cred-Request-Id`       | `a1b2c3d4-...` | Request ID for debugging              |
| `X-Cred-Price-Multiplier` | `0.25`         | Price multiplier (if pricing enabled) |

Read these in your API route handlers:

```typescript theme={null}
// app/api/resource/route.ts
import { NextRequest, NextResponse } from 'next/server'

export async function GET(req: NextRequest) {
  const trustScore = req.headers.get('x-cred-trust-score')
  const trustTier = req.headers.get('x-cred-trust-tier')

  return NextResponse.json({
    data: '...',
    trustScore,
    trustTier,
  })
}
```

## Route Matching

The `matcher` option controls which routes are trust-gated. Routes that don't match pass through without evaluation.

```typescript theme={null}
credGates({
  apiKey: process.env.CRED_API_KEY!,
  policy: 'standard',
  matcher: [
    '/api/:path*',          // All API routes
    '/protected/:path*',    // Protected pages
  ],
})
```

<Info>
  Also set `config.matcher` in your `middleware.ts` export so Next.js only runs the middleware on matching routes. This avoids unnecessary edge function invocations.
</Info>

## Failure Responses

| Response | When                                                         |
| -------- | ------------------------------------------------------------ |
| `400`    | No wallet address found on the request                       |
| `402`    | Gates failed, `on402: 'challenge'` — includes challenge body |
| `403`    | Gates failed with `on402: 'deny'`, or wallet is `blocked`    |
| `429`    | Cred API rate limit exceeded                                 |
| `502`    | Upstream gate provider error                                 |
