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

# Example implementation

> A minimal endpoint that satisfies the contract, plus a checklist for testing it before you enable the source.

The contract is small enough that a working endpoint is a few dozen lines. The examples below check the auth header, validate the request, look up an answer, and always return valid JSON.

<Tabs>
  <Tab title="Node (Express)">
    ```js theme={null}
    import express from 'express'

    const app = express()
    app.use(express.json({limit: '16kb'}))

    const SECRET = process.env.ANAGRAM_KNOWLEDGE_SECRET

    app.post('/anagram/knowledge', async (req, res) => {
      if (req.get('authorization') !== `Bearer ${SECRET}`) {
        return res.status(401).json({error: 'unauthorized'})
      }

      const {version, question} = req.body ?? {}
      if (version !== 1 || typeof question !== 'string' || question.length === 0) {
        return res.status(400).json({error: 'bad request'})
      }

      const guidance = await lookupGuidance(question) // your system
      if (!guidance) {
        return res.json({version: 1, status: 'no_answer'})
      }

      res.json({
        version: 1,
        status: 'answer',
        answer: guidance.text,
        citations: guidance.sources.slice(0, 8).map((s) => ({title: s.title, url: s.url})),
        products: guidance.handles.slice(0, 8).map((handle) => ({kind: 'handle', value: handle})),
      })
    })

    app.listen(3000)
    ```
  </Tab>

  <Tab title="Python (FastAPI)">
    ```python theme={null}
    import os
    from fastapi import FastAPI, Header, HTTPException
    from pydantic import BaseModel

    app = FastAPI()
    SECRET = os.environ["ANAGRAM_KNOWLEDGE_SECRET"]


    class Request(BaseModel):
        version: int
        question: str


    @app.post("/anagram/knowledge")
    async def knowledge(body: Request, authorization: str = Header(default="")):
        if authorization != f"Bearer {SECRET}":
            raise HTTPException(status_code=401)
        if body.version != 1 or not body.question:
            raise HTTPException(status_code=400)

        guidance = await lookup_guidance(body.question)  # your system
        if guidance is None:
            return {"version": 1, "status": "no_answer"}

        return {
            "version": 1,
            "status": "answer",
            "answer": guidance.text,
            "citations": [{"title": s.title, "url": s.url} for s in guidance.sources[:8]],
            "products": [{"kind": "handle", "value": h} for h in guidance.handles[:8]],
        }
    ```
  </Tab>
</Tabs>

A few details matter more than they look:

* Return `no_answer` as a `200`, not a `404`. A `404` is a failure and gets logged as one.
* Keep the whole handler under a couple of seconds. The 8-second timeout includes network time in both directions.
* Use a dedicated secret for Anagram so you can rotate it without touching anything else. Paste the full header value (`Bearer abc123`) into Studio; Anagram sends it verbatim.

## Testing before you enable

Work through this with the source saved but disabled. Nothing reaches shoppers until you flip the switch.

<Steps>
  <Step title="Send a request from your own machine">
    ```bash theme={null}
    curl -s https://api.example.com/anagram/knowledge \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer <secret>' \
      -d '{"version":1,"question":"Which glove fits wet spring touring?"}'
    ```

    Confirm you get a `200` and a body that matches one of the two shapes.
  </Step>

  <Step title="Test from Studio">
    Open the card in **Brain → Knowledge** and use **Test a question** with a few questions your system should answer and one it should not. You will see the outcome, elapsed time, and for failures the reason and HTTP status. An expected question should come back as an answer well under 8 seconds; the off-topic one should come back as no answer.
  </Step>

  <Step title="Break it on purpose">
    Temporarily change the secret in Studio to something wrong and test again. You should see `http error (HTTP 401)`. Change it back. This confirms your endpoint actually checks auth.
  </Step>

  <Step title="Check product references">
    If you return `products`, confirm the handles or GIDs belong to the store connected to this project. A reference to another store resolves to nothing and is dropped silently, so a wrong-store bug is invisible unless you check.
  </Step>

  <Step title="Enable and watch a real conversation">
    Flip the switch on, open the agent preview in Studio, and ask a shopper-style question your description covers. The agent should cite your source by name and show product cards from the catalog.
  </Step>
</Steps>

## Writing the expertise description

The **When should the agent ask it?** field is the routing rule. The agent reads it on every turn to decide whether to call you. Vague descriptions cause either too many calls (wasted budget, slower replies) or too few (your expertise never surfaces).

Weak:

```text theme={null}
Product recommendations.
```

Better:

```text theme={null}
Which gloves, mitts, and shells suit a given activity (resort, backcountry, splitboarding, park), climate, temperature range, and precipitation. Fit and layering advice. Does not cover prices, stock, shipping, returns, or kids' sizing.
```

Say what you cover and what you don't. The exclusions are as useful as the inclusions.
