---
title: "CLI"
url: "https://raconte.ai/en/docs/cli"
---

### Documentation

[Introduction](/en/docs)[Getting started](/en/docs/getting-started)[MCP server](/en/docs/mcp)[Webhooks](/en/docs/webhooks)[REST API](/en/docs/api)[CLI](/en/docs/cli)[SDK](/en/docs/sdk)[Agent skill](/en/docs/skill)

### Guides

[Configure the MCP server](/en/guides/mcp-setup)[Using the MCP server](/en/guides/mcp-usage)

[Raconte](/) ⟩ [Documentation](/en/docs)

# CLI

Manage interviews and invitations from the terminal or an AI agent with @raconte/cli.

`@raconte/cli` drives Raconte from a terminal or an AI agent. It wraps the same surface as the [REST API](/en/docs/api) and the [MCP server](/en/docs/mcp): create and manage **interviews** and **invitations**, authenticated with an organization API key. Every command prints JSON, so it scripts cleanly and an agent can parse it.

Want to hand the CLI to an AI agent? Point it at the ready-made skill: [raconte.ai/skill.md](/skill.md).

## Install

```
npm install -g @raconte/cli
```

Or run without installing:

```
npx @raconte/cli interviews list
```

Requires Node.js 20 or newer.

## Authentication

Create an organization API key from [Settings → API](/settings/api), then expose it:

```
export RACONTE_API_KEY="YOUR_API_KEY"
```

Every command reads `RACONTE_API_KEY`. You can also pass `--api-key <key>` per call.

## Output and exit codes

*   All output is JSON on stdout. Pipe it to `jq` or parse it directly.
*   Errors are JSON on stderr: `{ "status", "error" }` for API errors, `{ "error" }` for transport or usage errors.
*   Exit codes: `0` success, `2` usage error, `3` auth failure (401/403), `1` any other failure.
*   Commands never prompt: they are deterministic and non-interactive.

## Commands

Run `raconte --help` or `raconte <group> <command> --help` for the authoritative list.

### Interviews

Command

Description

`interviews list [--archived]`

List interviews.

`interviews get <id>`

Get one interview.

`interviews create --prompt --locale --voice-id [...]`

Create an interview.

`interviews update <id> [...]`

Update an interview.

`interviews archive <id>`

Archive an interview.

`interviews restore <id>`

Restore an archived interview.

`interviews logs <id>`

Read activity logs.

`interviews regenerate-intro <id>`

Regenerate the AI intro message.

`interviews regenerate-first-message <id>`

Regenerate the AI first message.

### Invitations

Command

Description

`invitations list <interviewId>`

List the invitations of an interview.

`invitations get <invitationId>`

Get one invitation.

`invitations create <interviewId> [--name --email --phone]`

Create an invitation. With no fields, returns a blank shareable invitation; name/email/phone only pre-fill it and are not sent.

`invitations create-bulk <interviewId> --invitees '<json>'`

Bulk-create invitations and send each one right away.

`invitations update <invitationId> --name <name>`

Update the invitee display name. Email and phone are not editable here (use `send`).

`invitations send <invitationId> [--email --phone]`

Send by email or SMS (sets the contact and dispatches).

`invitations cancel <invitationId>`

Cancel a ready invitation.

`invitations reactivate <invitationId>`

Reactivate a cancelled invitation.

`invitations archive <invitationId>`

Archive an invitation.

`invitations restore <invitationId>`

Restore an archived invitation.

`invitations logs <invitationId>`

Read activity logs.

`invitations audio-url <invitationId> <messageId>`

Get a temporary audio URL for a transcript message.

**Just need a shareable link?** Run `invitations create <interviewId>` with no other field. It creates a READY invitation; the link to share is `https://raconte.ai/invitation/<slug>` (the `slug` is in the response). Anyone with the link can take the interview, and nothing is emailed or texted. Changing a recipient’s email or phone always sends (via `send`); `update` only changes the display name, so contact details are never altered silently.

### Voices

Command

Description

`voices list [--language <code>]`

List the voices you pass as `--voice-id`. Public, no API key required.

`voices test-audio-url <voiceId>`

Get a short-lived preview audio URL for a voice. Public, no API key required.

Mutating commands also accept `--data '<json object>'` for the full request body. Explicit flags override its keys.

## Example

```
# Pick a voice, then create an interview and keep its id
VOICE=$(raconte voices list --language en | jq -r '.[0].id')
ID=$(raconte interviews create \
  --title "Onboarding feedback" \
  --prompt "Ask about the first week, follow up on friction points." \
  --locale en \
  --voice-id "$VOICE" | jq -r '.id')

# Get a shareable link without sending anything
raconte invitations create "$ID" | jq -r '"https://raconte.ai/invitation/" + .slug'

# Or invite people directly (each is emailed or texted right away)
raconte invitations create-bulk "$ID" \
  --invitees '[{"name":"Ada","email":"ada@example.com"},{"name":"Bo","phone":"+33600000000"}]'
```

## Programmatic use

Building a TypeScript or Node integration? Use the [SDK](/en/docs/sdk) (`@raconte/node-sdk`) instead of shelling out: the same surface as typed functions with Zod schemas.

Table of contents

[1\. Install](#install)[2\. Authentication](#authentication)[3\. Output and exit codes](#output-and-exit-codes)[4\. Commands](#commands)[5\. Example](#example)[6\. Programmatic use](#programmatic-use)
