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

# x402 Sessions

> Template demonstrating payer-scoped session storage with x402 payment identity

<Info>**Source:** [`examples/x402-sessions`](https://github.com/AgentlyHQ/aixyz/tree/main/examples/x402-sessions)</Info>

## Overview

This template demonstrates `SessionPlugin` -- payer-scoped key-value storage gated by x402 payment identity. Each x402 signer gets isolated storage that persists across requests. Two different payers never see each other's data.

## Project Structure

```
x402-sessions/
├── aixyz.config.ts           # Agent metadata and skills
├── app/
│   ├── session.ts            # Custom session store (optional)
│   ├── agent.ts              # Agent definition
│   ├── accepts.ts            # Custom x402 facilitator
│   └── tools/
│       ├── put-content.ts    # Store content in session
│       └── get-content.ts    # Retrieve content from session
├── package.json
└── vercel.json
```

## Session Store

SessionPlugin is auto-registered by the build pipeline. To customize the store, create `app/session.ts`:

```typescript title="app/session.ts" theme={null}
import { defineSessionStore, InMemorySessionStore } from "aixyz/app/plugins/session";

// Use the built-in in-memory store. Replace with Redis, DB, etc. for production.
export default defineSessionStore(new InMemorySessionStore());
```

If `app/session.ts` is not present, the default `InMemorySessionStore` is used automatically.

## Using Sessions in Tools

Tools access the session via `getSession()` -- no need to pass payer identity manually:

```typescript title="app/tools/put-content.ts" theme={null}
import { tool } from "ai";
import { z } from "zod";
import { getSession } from "aixyz/app/plugins/session";
import type { Accepts } from "aixyz/accepts";

export default tool({
  description: "Store a key-value pair in the current user's session",
  inputSchema: z.object({
    key: z.string(),
    value: z.string().nullable(),
  }),
  execute: async ({ key, value }) => {
    const session = getSession();
    if (!session) {
      return { success: false, error: "No authenticated signer in context" };
    }

    if (value === null) {
      await session.delete(key);
      return { success: true, key, deleted: true };
    }

    await session.set(key, value);
    return { success: true, key };
  },
});

export const accepts: Accepts = { scheme: "exact", price: "$0.01" };
```

## Skills

| Skill         | Description                                     | Price   |
| ------------- | ----------------------------------------------- | ------- |
| `put-content` | Store key-value content in payer-scoped session | \$0.01  |
| `get-content` | Retrieve stored content from session            | \$0.001 |

## Running

```bash theme={null}
cd examples/x402-sessions
# create a .env file
bun install
bun run dev
```

<CardGroup cols={2}>
  <Card title="SessionPlugin API" icon="plug" href="/api-reference/session-plugin">
    Full API reference for SessionPlugin, Session, and SessionStore.
  </Card>

  <Card title="x402 Payments" icon="credit-card" href="/protocols/x402">
    Payment protocol that provides payer identity for sessions.
  </Card>
</CardGroup>
