Server Proxy Setup
Proxy DuckViz AI calls through your backend with @duckviz/sdk.
When you use DuckViz packages in your own app, AI features (widget recommendations, report generation, log detection) need to call DuckViz API endpoints. The @duckviz/sdk package lets you proxy these calls through your own backend, so you can control authentication, rate limiting, and access.
Scaffolding from scratch?
npx duckviz create-app my-app ships this proxy + the customFetch rewrite already wired into Explorer / Report / Deck. The rest of this guide is for adding the same plumbing to an existing Next.js / Hono / Fastify / Express app.
Why use a proxy?
- Token security — your DuckViz API token stays on the server, never exposed to the client
- Access control — add your own auth checks before forwarding requests
- Path flexibility — mount the proxy at any path in your API
- Request logging — log and monitor DuckViz API usage
Getting a token
- Go to app.duckviz.com/settings/tokens
- Click Create Token
- Copy the token (format:
dvz_live_...) - Store it as a server-side environment variable
# .env.local (or your server env)
DUCKVIZ_API_TOKEN=dvz_live_abc123...Next.js setup
1. Create the proxy route
Use createDuckvizHandlers from @duckviz/sdk/next:
// app/api/duckviz/[...route]/route.ts
import { createDuckvizHandlers } from "@duckviz/sdk/next";
const handler = createDuckvizHandlers({
token: process.env.DUCKVIZ_API_TOKEN!,
});
export const GET = handler;
export const POST = handler;This creates a catch-all route that forwards requests to DuckViz:
POST /api/duckviz/widget-flow/fast-recommend→ DuckViz widget generationPOST /api/duckviz/widget-flow/classify→ domain classificationPOST /api/duckviz/detect-log-format→ log format detection- etc.
2. Configure the Explorer
Pass a customFetch function that rewrites API paths to your proxy:
const customFetch = (input: RequestInfo | URL, init?: RequestInit) => {
if (typeof input === "string" && input.startsWith("/api/")) {
input = input.replace(/^\/api\//, "/api/duckviz/");
}
return fetch(input, init);
};
<Explorer
customFetch={customFetch}
authenticated={true}
// ... other props
/>The Explorer internally calls /api/widget-flow/fast-recommend. The customFetch rewrites this to /api/duckviz/widget-flow/fast-recommend, which hits your proxy route.
How SSE pass-through works
Several DuckViz API endpoints use Server-Sent Events (SSE) for streaming responses (widget generation, report sections). The SDK proxy handles this transparently:
- Client sends a POST request
- Your proxy forwards it to DuckViz with the bearer token
- DuckViz responds with
text/event-stream - The proxy streams the response body back to the client
The customFetch on the client handles the SSE parsing via @duckviz/shared's apiSSE helper.
Adding access control
You can add your own authentication before the proxy forwards requests. Wrap the handler:
// app/api/duckviz/[...route]/route.ts
import { createDuckvizHandlers } from "@duckviz/sdk/next";
import { NextRequest, NextResponse } from "next/server";
const duckvizHandler = createDuckvizHandlers({
token: process.env.DUCKVIZ_API_TOKEN!,
});
async function withAuth(req: NextRequest) {
// Add your own auth check
const session = await getServerSession(req);
if (!session) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
// Forward to DuckViz
return duckvizHandler(req);
}
export const GET = withAuth;
export const POST = withAuth;Express setup
For Express backends, use the middleware adapter:
import express from "express";
import { duckvizExpressMiddleware } from "@duckviz/sdk/express";
const app = express();
app.use(express.json()); // required for body forwarding
app.use(
"/api/duckviz",
duckvizExpressMiddleware({
token: process.env.DUCKVIZ_API_TOKEN!,
}),
);
app.listen(3000);Error handling
The proxy forwards DuckViz error responses to the client:
| Status | Error | Meaning |
|---|---|---|
| 401 | DuckvizAuthError | Invalid or expired token |
| 402 | DuckvizQuotaExceededError | No credits remaining |
| 429 | DuckvizRateLimitError | Too many requests |
| 5xx | DuckvizServerError | DuckViz server error |
The Explorer handles these errors gracefully — showing appropriate messages to the user.