The orders API returns open orders on `GET /orders`. Anonymous callers get 401. `GET /` is a short HTML index and stays open.

Clone [starters/express](https://github.com/authdog/samples/tree/main/starters/express). SDK reference: [Express](/docs/backend/express).

`attachSession` records context. `requireAuth` on `GET /orders` is the identity gate. A signed-in session is not a permission grant. Apply [authorization](/docs/concepts/authorization) after the gate.

## What you need

| Requirement | Detail |
| --- | --- |
| Public key | `pk_...` from the [console](https://console.authdog.com) |
| Environment | Copy `.env.example` to `.env` and set `PK_AUTHDOG` |
| Secret key | Never put `sk_...` in the service |
| Return URL | Account portal back to this app |
| Request | Hosted sign-in stays in a browser. Call `/orders` with the `authdog-session` cookie or `Authorization: Bearer` |

## Run

```bash
npm install
npm run dev
```

Open http://localhost:3000. `GET /orders` with no session returns 401. With a valid session it returns `ord_1042` (Northwind, picking) and `ord_1043` (Contoso, shipped), plus the Authdog user.

## Orders

```ts
// src/index.ts
import express from "express"
import { createAuthdog } from "@authdog/express"

const app = express()
const authdog = createAuthdog({ publicKey: process.env.PK_AUTHDOG! })

app.use(authdog.attachSession())

app.get("/orders", authdog.requireAuth, (req, res) => {
  res.json({
    caller: req.authdog!.user,
    orders: [
      { id: "ord_1042", customer: "Northwind", total: 1280, status: "picking" },
      { id: "ord_1043", customer: "Contoso", total: 640, status: "shipped" },
    ],
  })
})
```

`GET /session` is informational. It does not reject anonymous callers. `GET /me` returns the same user without the orders. Logout clears the local cookie and redirects. It does not revoke a bearer token.
