Self-hosting Currai: your first agent conversation
Set up your own Currai instance, connect a working agent, and verify one real conversation from the user exchange to its model and tool events.
The first useful result from a self-hosted Currai instance is a conversation you can recognize. You ask your agent a question, see its answer, and find the same exchange in your workspace alongside the operations that produced it.
This guide takes you from a fresh checkout to that result. Start with a test application and synthetic messages. Once capture works, you can decide which production workflows to instrument.
What you need
Prepare Node.js 22.12 or newer, pnpm 9.12.0, and your own Convex and Clerk projects. Currai uses Next.js for the application, Convex for its backend, and Clerk for authentication. Intent and violation classification also requires a TypeSafe API key.
You need a working chat or agent application to connect. Keep it separate from the Currai application, including its environment file and development port. Your agent's model-provider credentials belong in that application's server environment.
Self-hosting gives you an instance to operate. It still uses these services; starting Next.js locally does not make the whole system run offline.
1. Get the self-hosted edition
Start from the Currai repository and use the self-hosted edition described in its README. Its repository includes the application, ingestion code, and integration helpers.
Use .env.example as the configuration inventory. The repository's development
guide is the reference for setup details when upgrading to a different release.
2. Configure authentication and the backend
Create a Clerk application for this test environment. Put its publishable and
secret keys in apps/web/.env.local, using the variable names in the example
file. Configure a Clerk JWT template named convex with audience convex.
From apps/web, initialize your Convex development project:
This writes the deployment and public backend URL into the local environment
file. Set CLERK_JWT_ISSUER_DOMAIN in the Convex deployment environment to your
Clerk issuer URL. If Convex requests this value during initialization, configure
it and run the command again.
Create a Clerk webhook that sends user.created and user.updated to:
Store its signing secret as CLERK_WEBHOOK_SECRET in Convex. This synchronizes
Clerk users with Currai's backend. If you created a user before configuring the
webhook, resend the relevant event or update the user in Clerk.
The Next.js environment file and Convex environment are separate configuration
locations. Putting a backend secret in .env.local does not configure the remote
Convex deployment.
3. Start Currai and create a workspace
Set NEXT_PUBLIC_APP_URL to http://localhost:3000 in the Next.js environment
and APP_URL to the same origin in Convex. Set TYPESAFE_API_KEY in Convex for
intent and violation classification.
After backend setup, return to the repository root and initialize the model catalog against your development deployment:
Open http://localhost:3000, sign up, and create a workspace. Create an ingestion
key during onboarding or in Workspace Settings → API Keys. You will use its
public and secret keys to authenticate capture requests.
4. Point your agent at your instance
In the application you want to instrument, set these server-side environment variables:
Keep the keys out of browser code. For a Next.js agent application, do not prefix
them with NEXT_PUBLIC_. Restart the agent application after changing its
environment.
The base URL is essential: the integration skill defaults to hosted Currai when
you do not set it. If the agent runs in a container or on another machine,
localhost refers to that environment. Use an address that can reach your Currai
server instead.
5. Instrument the conversation path
You can install the Currai integration skill in the agent application's project:
Ask your coding agent:
Connect this application's real chat or agent path to my self-hosted Currai instance using CURRAI_BASE_URL. Capture the session and agent events through native HTTP, include model and tool events where available, and verify one real interaction. Keep the workspace keys server-side.
For a manual integration, use POST /api/v1/capture-session to create or update
the conversation and POST /api/v1/capture-event for its operations. Native
capture uses HTTP Basic authentication, with the workspace public key as the
username and secret key as the password. The
streaming chatbot integration guide
walks through the payloads and server-side helper.
Use one stable session ID across the conversation. Give each operation its own event ID and use parent IDs to connect model and tool events to the agent turn. Start a new session when the user begins a new conversation.
Capture the actual input and output from execution. A canned demo event can confirm connectivity, but it does not show that your application's conversation path is instrumented.
6. Send one real message and inspect it
Use your agent's normal interface to send a recognizable test request, such as:
Summarize our fictional return policy: unopened items can be returned within 30 days with a receipt.
Wait for the answer, then open your Currai workspace. Find the session and check that the user request and agent response match what you just saw. Inspect the agent event and any model or tool events your integration captures.
Send a follow-up in the same conversation. It should reuse the session ID and add a new turn. Start a new conversation and confirm it gets a different session.
If you want to examine intent or violation findings, configure rules appropriate to the test and confirm the classification credentials are present in Convex. Ingestion and classification are separate checks: an imported conversation does not by itself prove that classification is configured.
If the conversation does not appear
Check the destination first. Confirm the running agent process has your local
CURRAI_BASE_URL, rather than the hosted default, and can reach that address.
Then inspect capture responses and the Next.js and Convex logs.
An authentication failure can mean the keys belong to another workspace or instance. If sign-in works but onboarding fails, check Clerk's user-sync webhook and Convex configuration. If only the demo appears, inspect whether capture runs inside the real chat handler.
For voice-provider webhooks, the local application needs a reachable public HTTPS address. Follow the repository's connector and tunnel instructions; provider webhook URLs target the Next.js application, while the Clerk user-sync webhook targets Convex.
Before moving to production
Create separate production Convex and Clerk projects, configure your deployed application origin, and repeat the same conversation check. Assign responsibility for updates, credentials, backups, and retention. The self-hosted edition removes application subscriptions and event quotas; you still operate the infrastructure and pay its service and model costs.
If you are deciding who should operate that system, read Open-source vs hosted Currai: choosing what fits your team.
