Call Agentuity services (key-value, AI Gateway, queues) from Next.js App Router route handlers. Use agentuity build to inspect the package, then deploy with agentuity deploy.
Create a Starter
The quickest way to start is with the Agentuity CLI:
npm create agentuity -- --name my-next-app --framework nextjs --services keyvalue
cd my-next-appThe starter includes a working translation demo: a React page that calls an API route using AIGatewayClient. Adding --services keyvalue installs @agentuity/keyvalue and updates the starter checklist, but it does not add another route by itself. The key files:
| File | Purpose |
|---|---|
src/app/page.tsx | Client UI that calls the API route |
src/app/api/translate/route.ts | Route handler that calls the AI Gateway |
package.json | dev, build, and deploy scripts pre-wired |
Add to an Existing App
Install the CLI as a dev dependency, then import the project:
npm install -D @agentuity/cli
npx agentuity project import --validate-only # dry run: checks config only
npx agentuity project import # registers the project and writes agentuity.jsonnpm install -D installs the CLI as a project-local dev dependency, not a global install. Use npx to run that local CLI. For Bun, pnpm, and Yarn equivalents, see Local versus global CLI.
agentuity project import writes the local project metadata that agentuity deploy expects. Run it once before the first deploy.
See Add Agentuity to an existing app for the import flow, the Invalid project folder deploy case, and the first deploy command.
What Agentuity adds
| Area | Next.js keeps | Agentuity adds |
|---|---|---|
| routing | App Router pages and app/api/**/route.ts handlers | service clients you import in server code |
| local dev | next dev | agentuity dev supplies service credentials |
| build | next build and standalone output | agentuity build runs the build and packages launch metadata |
| deploy | the generated standalone server | agentuity deploy ships the packaged app |
Service Client Example
Route handlers use standalone service clients. They do not need an Agentuity-owned router or createApp().
npm install @agentuity/keyvalueimport { KeyValueClient } from '@agentuity/keyvalue';
import { NextResponse } from 'next/server';
interface Note {
readonly id: string;
readonly text: string;
readonly createdAt: string;
}
// Instantiated once at module load; reads AGENTUITY_SDK_KEY from the environment
const kv = new KeyValueClient();
export async function POST(request: Request): Promise<NextResponse> {
const body: unknown = await request.json();
if (typeof body !== 'object' || body === null || !('text' in body)) {
return NextResponse.json({ error: 'text is required' }, { status: 400 });
}
const { text } = body;
if (typeof text !== 'string' || !text.trim()) {
return NextResponse.json({ error: 'text must be a non-empty string' }, { status: 400 });
}
const note: Note = {
id: crypto.randomUUID(),
text: text.trim(),
createdAt: new Date().toISOString(),
};
await kv.set('notes', note.id, note, { ttl: 60 * 60 * 24 * 7 }); // 7-day TTL
return NextResponse.json({ note });
}
export async function GET(request: Request): Promise<NextResponse> {
const { searchParams } = new URL(request.url);
const id = searchParams.get('id');
if (!id) {
return NextResponse.json({ error: 'id query param is required' }, { status: 400 });
}
const result = await kv.get<Note>('notes', id);
if (!result.exists) {
return NextResponse.json({ error: 'not found' }, { status: 404 });
}
// result.data is typed as Note because of the generic
return NextResponse.json({ note: result.data });
}KeyValueClient reads AGENTUITY_SDK_KEY from the environment. Run the app with agentuity dev so the linked project key is available during local development.
AI Gateway Route Example
Use AIGatewayClient for generic model calls. The project SDK key authenticates the request, and the model ID is app configuration or request input.
npm install @agentuity/aigateway zodimport { AIGatewayClient } from '@agentuity/aigateway';
import { NextResponse } from 'next/server';
import { z } from 'zod';
const DEFAULT_MODEL = 'openai/gpt-5.4-mini';
const gateway = new AIGatewayClient();
const requestSchema = z.object({
message: z.string(),
model: z.string().optional(),
});
export async function POST(request: Request): Promise<NextResponse> {
const body: unknown = await request.json();
const parsed = requestSchema.safeParse(body);
if (!parsed.success) {
return NextResponse.json({ error: 'message is required' }, { status: 400 });
}
const { message } = parsed.data;
const model = parsed.data.model ?? DEFAULT_MODEL;
const result = await gateway.completeText({
model,
messages: [{ role: 'user', content: message }],
});
if (!result.hasText) {
return NextResponse.json({ error: 'model returned no text' }, { status: 502 });
}
return NextResponse.json({
reply: result.text,
model,
});
}Use the model id exactly as it appears in the AI Gateway model catalog. Use a provider SDK directly only when the route depends on provider-specific APIs such as OpenAI Responses state or Anthropic tool_use blocks.
Agentuity does not require createApp() or an Agentuity-owned router for Next.js projects. Standard App Router route handlers work as-is.
Run Locally
Start the app with agentuity dev. When the linked project key is available, the CLI supplies AGENTUITY_SDK_KEY to the Next.js process:
agentuity devSmoke-test the route:
curl http://localhost:3000/api/chat \
-H "content-type: application/json" \
-d '{"message":"Hello"}'Deployed Environment Variables
Configure the variables your deployed app needs. Direct AIGatewayClient calls use AGENTUITY_SDK_KEY; the model ID in this example is normal app configuration or request input.
| Variable | Used by |
|---|---|
AGENTUITY_SDK_KEY | Agentuity service clients and @agentuity/aigateway |
DATABASE_URL | database routes |
AWS_* | object storage routes; see Object Storage for exact variables |
Validate Before Deploy
Run the framework build when you want Next.js-only feedback, then run the Agentuity build. agentuity build runs the framework build during packaging and produces .agentuity/launch.json with the start command for the deployed container.
npm run build
npx agentuity build
cat .agentuity/launch.json # verify the command points at the standalone serverThe agentuity build adapter sets NEXT_PRIVATE_STANDALONE=true at build time so Next.js produces .next/standalone/. Adding explicit output: 'standalone' to next.config.ts is safer: it works regardless of the adapter's env injection and makes the intent visible in your config file.
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
output: 'standalone', // produces .next/standalone/ with a minimal server.js
};
export default nextConfig;With standalone output, a valid package contains the standalone server, .next/static/, and public/. The launch command must reference the generated server.js. In monorepos or nested workspaces, that file may be under the traced project path instead of the output root.
Deploy only after the framework build, Agentuity build, and a local packaged validation of / and at least one route handler pass:
agentuity deploy --confirmCommon Gotchas
| Symptom | Check |
|---|---|
| Service client returns 401 or auth errors | Run with agentuity dev, or set AGENTUITY_SDK_KEY manually |
| Model call returns an auth error | Verify AGENTUITY_SDK_KEY is available to the route handler. See AI Gateway |
launch.json starts node node_modules/.bin/next start | Do not deploy that package. Rebuild after the adapter writes a command that starts the standalone server.js output |
.next/standalone is empty after build | Confirm Next.js version is 12+; older versions do not support standalone output |
| Files outside the app root are missing in the standalone bundle | Set outputFileTracingRoot in next.config.ts to include monorepo paths |
Framework Docs
- Next.js Route Handlers: current App Router route handler shape and HTTP method exports
- Next.js Standalone Output: how
output: 'standalone'works and what it produces
Next Steps
- Key-Value Storage: TTL semantics, namespaces, and type-safe reads
- AI Gateway: supported providers and how environment injection works
- Deployment: CLI deploy flags and lifecycle hooks
- App Configuration: project IDs, domains, and environment files