serverConvex
Call Convex from a Nitro request with explicit authentication policy and request-scoped state.
serverConvex(event) creates one request-scoped caller with query, mutation, and action methods.
import { api } from '#convex/api'
import { serverConvex } from '#convex/server'
export default defineEventHandler(async (event) => {
return await serverConvex(event, { auth: 'required' }).query(api.projects.list, {})
})Authentication modes
| Mode | Cookie behavior |
|---|---|
required | Exchange the request session; throw if no valid identity exists |
optional | Use identity when valid, otherwise call anonymously |
none | Do not inspect or exchange auth cookies |
The server default is optional when no explicit principal is supplied.
Caller lifetime
One caller lazily owns:
- one token-resolution promise;
- one official
ConvexHttpClient; - one current request identity snapshot.
Do not store a caller in module scope or on a cross-request cache. Create it inside the handler.
Explicit principal
An operator-controlled server workflow may provide an already obtained Convex JWT:
const caller = serverConvex(event, {
authToken: trustedToken,
})Or exchange an explicit Better Auth cookie/bearer credential:
const caller = serverConvex(event, {
credential: { type: 'bearer', value: sessionToken },
})authToken and credential are mutually exclusive. Either one forces required auth. Combining an explicit principal with optional or none is a synchronous programming error.
Never accept these values from an untrusted request body and forward them blindly.
Errors
Calls reject with ConvexCallError for classifiable auth, transport, and structured Convex server failures. Invalid options throw ServerConvexValidationError before network access.
A rejected caller keeps its rejected token/client state. Create a new caller for an intentional retry.
No client hydration
A serverConvex result returned from your API route is ordinary route data. It does not seed useConvexQuery or establish a subscription.
Use a composable directly in a page for normal SSR-to-live data. Use a server route when a real server boundary is required.