Quickstart — Next.js (App Router)
Zero to a billed charge in 5 steps.
1. Install and scaffold
bash
npm i @mythos-work/sdk
npx @mythos-work/sdk init
init creates the files below and adds env placeholders to .env.local. Or create them by hand:
2. Environment
bash
# .env.local
MYTHOS_LISTING_ID=your-listing-id # from the Mythos dashboard
# openssl rand -base64 32 (≥ 32 chars)
MYTHOS_SESSION_SECRET=
# Mythos dashboard → Settings → Mythos key
MYTHOS_KEY=
3. Server: one file, one route
Missing MYTHOS_KEY is soft in 0.5.0; static listing launches remain silent, while dynamic registration, handshake and callbacks warn once per process. It will be required in 0.6.0. Update deployment env after key regeneration. See the binding matrix.
| Troubleshooting code | Fix |
|---|---|
PRODUCER_MISMATCH | The MYTHOS_KEY in this deployment belongs to a different Producer, or was regenerated. Copy the current key from the dashboard and redeploy. |
typescript
// lib/mythos.ts
import { createMythos } from '@mythos-work/sdk';
export const mythos = createMythos();
typescript
// app/api/mythos/[...mythos]/route.ts
import { mythos } from '../../../../lib/mythos';
export const { GET, POST } = mythos.handlers;
javascript
// next.config.js — add these rewrites
async rewrites() { return [
{ source: '/.well-known/mythos-handshake', destination: '/api/mythos/handshake' },
{ source: '/.well-known/mythos-listing-registered', destination: '/api/mythos/listing-registered' },
]; }
4. Charge credits
typescript
// app/api/calculate/route.ts
import { MythosError } from '@mythos-work/sdk';
import { mythos } from '@/lib/mythos';
export async function POST(req: Request) {
const { a, b } = await req.json();
try {
await mythos.charge(req, { credits: 1, reason: 'calculate' });
return Response.json({ success: true, data: { result: a + b } });
} catch (err) {
if (err instanceof MythosError) return Response.json({ success: false, code: err.code }, { status: err.httpStatus });
throw err;
}
}
5. Page
tsx
'use client';
import { useMythos } from '@mythos-work/sdk/react';
export default function Calculator() {
const { status, session, fetch, confirmCharge, relaunch } = useMythos();
if (status === 'loading') return <p>Loading…</p>;
if (status === 'standalone') return <p>Open this app from Mythos.</p>;
if (status === 'expired') return <button onClick={relaunch}>Session expired — relaunch</button>;
if (status === 'error') return <p>Something went wrong.</p>;
async function calculate() {
const { approved } = await confirmCharge({ credits: 1, reason: '1 + 2' });
if (approved) await fetch('/api/calculate', { method: 'POST', body: JSON.stringify({ a: 1, b: 2 }) });
}
return <button onClick={calculate}>Hi {session?.displayName} — calculate (1 credit)</button>;
}
Check it
bash
npx @mythos-work/sdk doctor
Then launch your listing from the Mythos dashboard.