# AI interview recorder

> A small Next.js app: create an interview link, join a recorded 1:1 call, then replay it and export an MP4. The AI step is a stub you replace.

A recorded 1:1 interview on the published Synento SDKs. The interviewer creates
a link, the candidate joins in the browser, and after the call the app plays
the recording and can export an MP4. Recording is not a separate step: the
session is the recording.

The app is MIT licensed and published at
[Synento/ai-interview-recorder](https://github.com/Synento/ai-interview-recorder).
The same connection steps, for Claude Code, Cursor, Codex and other MCP clients,
are on [For agents](https://synento.com/agents#mcp).

## What you need

- Node.js 22 or newer
- A secret `sk_live_` API key from the dashboard. Replay and MP4 export need it,
  and it stays on the server. An `rk_live_` restricted key is refused when the
  app starts, with that reason on the page.
- A browser that can publish with WebCodecs (see [Browser support](https://synento.com/docs/browser-support.md))

## Run it

```bash
git clone https://github.com/Synento/ai-interview-recorder.git
cd ai-interview-recorder
npm install
cp .env.example .env.local
```

Put the `sk_live_` key in `SYNENTO_API_KEY` inside `.env.local`. Do not commit
that file.

```bash
npm run dev
```

Open `http://localhost:3010`. Create an interview, open the candidate link in
another browser or a private window, and join from both. Camera and microphone
are published from the button, not on page load. End the call as the
interviewer to open the review page.

`SYNENTO_API_URL` is optional. It defaults to `https://api.synento.com`.

## What the app does

1. `POST` creates a session with `@synento/node` and stores the id in memory.
   Restarting the dev server forgets interviews. Nothing is written to disk.
2. Each join asks the server for a new connection token. The browser uses
   `@synento/react` (`SynentoProvider`, `VideoTile`) and only ever sees that
   token.
3. Review reads `GET /v1/sessions/{id}/manifest` and
   `GET /v1/sessions/{id}/playback` on the server, and draws the result with
   `@synento/player` (`Compositor` and `ReplayAudio`). The API key stays on
   the server.
4. Export calls `GET /v1/sessions/{id}/export` (grid, landscape), polls
   `GET /v1/exports/{jobId}`, and downloads the MP4 through the app so the key
   is not in the browser. Repeating the same export returns the existing file.
5. **Your AI step** is `runInterviewAiStep` in `lib/ai-step.ts`. The button on
   the review page calls it. The function shipped here does not call a model
   and does not read an AI API key. Replace the body with a request to your
   own model. You can fetch the MP4 from the export download route, or send a
   transcript you produce yourself.

Anyone who has the interview id can join either seat or open the review page.
That is enough for a local starter. Add your own auth before you put it on the
internet.

## Tests

`npm test` checks the interview book, the export response parsing, the API-key
check, and that the AI stub does not look up a model key. It does not place a
call.

The same source is `examples/ai-interview-recorder` in the Synento source tree.
From that tree, `npm run dev -w ai-interview-recorder` starts it, and
`scripts/export-interview-recorder.sh <dir>` copies it into a directory ready
to push as `Synento/ai-interview-recorder`.
