Skip to main content

What you’ll build

An authenticated chat where every Supabase user has filterable Polpo sessions and analytics. Your Next.js app verifies the Supabase session on the server, then forwards the user’s ID to Polpo on every chat call. You get:
  • Per-user session history and filtering
  • Per-user analytics (filter dashboard by user)
  • Audit trail (every session, task, run carries the user id)
  • A stable external identifier for downstream metering

Prerequisites

1

Supabase project with auth enabled

Email/password, OAuth, magic links — any Supabase auth method works. You only need the server-side helper to read the current user.
2

Polpo project + API key

Follow the quickstart to create a project and grab a service-role API key (sk_live_...). Server-side only — never ship it to the browser.
3

Next.js 14+ App Router

Examples below use Route Handlers and Client Components. The same pattern works in Hono, Express, or any server you control.

How it fits together

Supabase Auth lives in your app. Polpo never sees the JWT. Your server is the trust boundary: it verifies the session, then calls Polpo with your API key and a user field.

Step 1 — Install

Step 2 — Verify the session and call Polpo

Server-side route handler. Reads the Supabase session via cookies, rejects unauthenticated requests, and streams the chat completion back to the browser with user: user.id attached.
app/api/chat/route.ts
user.id is a UUID that’s stable for the lifetime of the Supabase user. Polpo treats it as an opaque string — pass anything that uniquely identifies the end-user (email, tenant id, internal user id) if you prefer.

Step 3 — Stream the response in your client

Plain fetch + the standard SSE parsing pattern. Replace this with @polpo-ai/react’s useChat hook once you wire PolpoProvider against /api/chat.
app/chat/page.tsx

Step 4 (optional) — List a user’s past sessions

Polpo auto-creates a session per chat and tags it with the user field. You can list a single user’s sessions from your server.
The typed polpo.getSessions() helper doesn’t currently take a user filter parameter. Until it does, hit the underlying endpoint directly — GET /v1/chat/sessions?user=<id> does support the filter server-side. We’ll add a typed param to the SDK in a later release.
app/api/sessions/route.ts

What this gives you

  • Per-user session history. Sessions can be filtered by the exact user.id value.
  • Per-user analytics. Filter completions, tasks, and runs by user in the dashboard.
  • Audit trail. Every session, task, and run row stores the user id — useful for support, abuse review, and compliance.
  • Metering identifier. The same user value can be correlated with your own billing and usage records.

What we deliberately don’t do

  • Polpo never verifies the Supabase JWT. Your API key is the trust anchor. Verify the session in your server, then forward user.id — Polpo trusts the caller because the caller has the API key.
  • We don’t compete with Supabase Auth. Bring your auth — we run the agents.

Troubleshooting

401 Unauthorized from Polpo

Check POLPO_API_KEY is set in the server environment and not prefixed with NEXT_PUBLIC_. The SDK sends it as Authorization: Bearer <key>.

user field shows up as null in the dashboard

The user field must be passed in the request body, not as a header. With the SDK, that’s polpo.chatCompletionsStream({ ..., user: user.id }). With raw fetch, include "user": "<id>" as a top-level body field.

Sessions aren’t being scoped per user

Confirm both @polpo-ai/sdk and the target runtime are on 0.15.35. Run pnpm why @polpo-ai/sdk to verify. Shared and per-agent memory endpoints remain project-scoped; the user field does not isolate /v1/memory content. Keep authorization and tenant isolation in your application server.