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

# Configuration Options Reference for Agent Feedback SDK

> Complete reference for all AgentFeedbackOptions fields: API key, endpoint, route filters, feedback mode, context extractors, and queue tuning.

Every Agent Feedback adapter accepts an `AgentFeedbackOptions` object when you mount the middleware. The options shape is defined in `core.ts` and is shared across Express, Fastify, and MCP adapters. Pass the object once at startup — the runtime validates your key format immediately and throws synchronously if the key cannot produce v2 capability tokens.

## Complete configuration example

<CodeGroup>
  ```ts Express theme={null}
  import { agentFeedback } from "@agent-feedback/node/express";

  app.use(agentFeedback({
    apiKey: process.env.AGENT_FEEDBACK_KEY,
    include: ["/api/search", "/api/docs/*"],
    exclude: ["/api/internal/*"],
    feedbackMode: "auto",
    customerRef: req => req.user?.accountId,
    sessionRef: req => req.headers["x-session-id"] as string | undefined,
  }));
  ```

  ```ts Fastify theme={null}
  import { agentFeedback } from "@agent-feedback/node/fastify";

  await fastify.register(agentFeedback, {
    apiKey: process.env.AGENT_FEEDBACK_KEY,
    include: ["/api/search", "/api/docs/*"],
    exclude: ["/api/internal/*"],
    feedbackMode: "auto",
    customerRef: req => (req.user as { accountId?: string })?.accountId,
    sessionRef: req => req.headers["x-session-id"] as string | undefined,
  });
  ```
</CodeGroup>

<Warning>
  Never commit your API key to source control. Always read it from an environment variable such as `process.env.AGENT_FEEDBACK_KEY`.
</Warning>

***

## Required options

<ParamField path="apiKey" type="string" required>
  Your product key. Keys follow the format `af_live_<32hex>_<secret>` where the 32-character hex segment is the public key ID and the remainder is the signing secret. The runtime derives an HMAC signing key from the full key value and stores nothing beyond that derivation.

  ```ts theme={null}
  apiKey: process.env.AGENT_FEEDBACK_KEY
  ```

  <Note>
    If you pass a key that does not match the v2 key format, the middleware throws at startup with the message: *"This product key cannot create v2 feedback receipts. Create a new key in Agent Feedback Setup."* Create a new product key in the dashboard rather than modifying an old one.
  </Note>
</ParamField>

***

## Endpoint

<ParamField path="endpoint" type="string">
  Override the Agent Feedback API base URL. Use this when you route traffic through a proxy or when testing against a staging backend.

  If omitted, the SDK checks the `AGENT_FEEDBACK_URL` environment variable, then falls back to the Agent Feedback hosted service.

  ```ts theme={null}
  endpoint: process.env.AGENT_FEEDBACK_URL // or set the env var directly
  ```
</ParamField>

***

## Route filtering

<ParamField path="include" type="string[]">
  An allowlist of URL path patterns to instrument. Supports single-segment wildcards (`*`) and multi-segment wildcards (`**`). For example, `/docs/*` matches `/docs/intro` but not `/docs/guides/setup`; `/docs/**` matches both.

  When `include` is omitted, the SDK instruments every route that isn't excluded. Start with a narrow list targeting your highest-value endpoints and expand once you've verified the contract with the doctor tool.

  ```ts theme={null}
  include: ["/api/search", "/api/docs/*", "/api/answers/**"]
  ```
</ParamField>

<ParamField path="exclude" type="string[]">
  A denylist of URL path patterns to skip. Your entries are merged with the SDK's built-in exclusions, which always cover:

  * `/health`, `/healthz`
  * `/metrics`
  * `/favicon.ico`, `/robots.txt`
  * `/_agent-feedback/*`
  * `/api/v2/outcomes`

  You cannot remove the built-in exclusions; you can only add to them.

  ```ts theme={null}
  exclude: ["/api/internal/*", "/api/admin/**"]
  ```
</ParamField>

***

## Feedback mode

<ParamField path="feedbackMode" type="&#x22;auto&#x22; | &#x22;ask&#x22; | &#x22;off&#x22;">
  Controls how the feedback instruction is phrased in every eligible response. Defaults to `"auto"`.

  | Value    | Behaviour                                                                                                                                              |
  | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
  | `"auto"` | Instructs the agent to submit autonomously before its final response. The `requested` flag in the envelope is `true`.                                  |
  | `"ask"`  | Requests feedback but does not command the agent — useful for sensitive product areas where you prefer a softer tone. The `requested` flag is `false`. |
  | `"off"`  | Disables the feedback contract entirely. No `_agentFeedback` field is appended and no telemetry is enqueued.                                           |

  ```ts theme={null}
  feedbackMode: "auto"
  ```

  <Tip>
    You can also disable instrumentation at the process level by setting `AGENT_FEEDBACK_ENABLED=false` in the environment without touching your code.
  </Tip>
</ParamField>

***

## Context extractors

These functions run per-request. If an extractor throws, the SDK logs a warning and continues — the product response is never affected.

<ParamField path="customerRef" type="(request: Request) => string | undefined | null">
  Returns an opaque string that identifies the customer account in your system — for example, an account ID or organization slug. This is your reference, not an agent identity; Agent Feedback never uses it to identify agents.

  The value is recorded in telemetry for your own cross-referencing. It is intentionally excluded from capability tokens so a customer-ref cannot be used to forge or correlate submissions.

  ```ts theme={null}
  customerRef: req => req.user?.accountId
  ```
</ParamField>

<ParamField path="sessionRef" type="(request: Request) => string | undefined | null">
  Returns a session continuity string. The SDK accepts only values that come from company-provided headers or MCP proof of continuity — it does not perform time-window grouping or infer sessions from timestamps.

  ```ts theme={null}
  sessionRef: req => req.headers["x-session-id"] as string | undefined
  ```
</ParamField>

<ParamField path="runtimeHint" type="(request: Request) => string | undefined | null">
  Returns a hint about the agent runtime making the request — for example `"claude"` or `"openai"`. The value is logged as explicitly unverified and is never presented as confirmed agent identity.

  ```ts theme={null}
  runtimeHint: req => req.headers["x-agent-runtime"] as string | undefined
  ```
</ParamField>

***

## Observability

<ParamField path="logger" type="Logger">
  A custom logger with `debug` and `warn` methods. The `Logger` type matches the subset of `Console` that the SDK uses, so you can pass `console` directly or any structured logger that implements the same interface.

  Defaults to `console`.

  ```ts theme={null}
  import pino from "pino";

  const logger = pino();

  app.use(agentFeedback({
    apiKey: process.env.AGENT_FEEDBACK_KEY,
    logger: {
      debug: (msg) => logger.debug(msg),
      warn: (msg) => logger.warn(msg),
    },
  }));
  ```
</ParamField>

***

## Telemetry queue tuning

Telemetry is sent on a background queue. Neither option affects product response latency — the response is sent before any network call is made.

<ParamField path="flushIntervalMs" type="number">
  How often (in milliseconds) the background queue is flushed to the telemetry endpoint. Defaults to `500` ms. The queue also flushes immediately when it accumulates 50 or more events, regardless of the timer.

  ```ts theme={null}
  flushIntervalMs: 2000
  ```
</ParamField>

<ParamField path="maxQueueSize" type="number">
  Maximum number of telemetry events to hold in memory. When the queue reaches this limit, the oldest event is dropped to make room for the new one. Defaults to `1000`. Events are never allowed to block or slow the product response.

  ```ts theme={null}
  maxQueueSize: 500
  ```

  <Note>
    Telemetry delivery failures do not affect your product responses. If the telemetry endpoint is unreachable, the SDK retries up to three times per event, logs a single warning, and then discards the batch rather than accumulating unbounded memory.
  </Note>
</ParamField>
