> ## Documentation Index
> Fetch the complete documentation index at: https://intervyo.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# API Reference

> Drive intervyo.ai programmatically — Interviewers, Roles, Rounds, participants, sessions, and code execution over a single REST API.

The intervyo.ai REST API lets you run calibrated AI interviews from your own
systems: define how the AI evaluates, schedule sessions, stream back scorecards,
and sync results into your ATS, LMS, or internal tooling.

Everything you can do in the dashboard is available over the API.

<CardGroup cols={3}>
  <Card title="Interviewers" icon="bot" href="/api-reference/interviewers/get-interviewers">
    Define the AI interviewer — persona, scoring dimensions, tone, and difficulty.
  </Card>

  <Card title="Roles" icon="clipboard-list" href="/api-reference/roles/get-roles">
    Describe what to assess: role, skills, objective, and the pass bar.
  </Card>

  <Card title="Rounds" icon="git-branch" href="/api-reference/rounds/get-rounds">
    Compose multi-step pipelines — screen → technical → final.
  </Card>

  <Card title="Participants" icon="users" href="/api-reference/participants/get-participants">
    The people being evaluated. Create them, then schedule sessions.
  </Card>

  <Card title="Sessions" icon="message-circle" href="/api-reference/sessions/get-sessions">
    A single AI interview. Schedule it and the invite goes out automatically.
  </Card>

  <Card title="Code Execution" icon="terminal" href="/api-reference/code-execution/post-code-execute">
    Run candidate code against test cases in Python, JavaScript, or TypeScript.
  </Card>
</CardGroup>

## Base URL

All endpoints are served from a single host and versioned under `/api/v1`:

```text theme={null}
https://www.intervyo.ai/api/v1
```

```text theme={null}
GET    https://www.intervyo.ai/api/v1/sessions
POST   https://www.intervyo.ai/api/v1/sessions
GET    https://www.intervyo.ai/api/v1/participants
POST   https://www.intervyo.ai/api/v1/interviewers
```

## Authentication

Authenticate every request with an API key in the `x-api-key` header. Keys are
created in the dashboard under **Developer → API Keys** and are prefixed
`iv_live_`.

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://www.intervyo.ai/api/v1/sessions" \
    -H "x-api-key: iv_live_your_key_here"
  ```

  ```ts Node (fetch) theme={null}
  const res = await fetch("https://www.intervyo.ai/api/v1/sessions", {
    headers: { "x-api-key": process.env.INTERVYO_API_KEY! },
  });
  const { data, meta } = await res.json();
  ```

  ```python Python (requests) theme={null}
  import os, requests

  res = requests.get(
      "https://www.intervyo.ai/api/v1/sessions",
      headers={"x-api-key": os.environ["INTERVYO_API_KEY"]},
  )
  res.raise_for_status()
  payload = res.json()
  ```
</CodeGroup>

<Warning>
  API keys are secrets. Use them only from server-side code, never from a
  browser or mobile client. Rotate immediately if one leaks — see
  [Authentication](/en/authentication).
</Warning>

<Note>
  Calls made from a signed-in dashboard session can authenticate with cookies
  instead of a key. For those requests, pass your team slug as the
  `accountSlug` query parameter so the API can resolve the workspace.
</Note>

### Permission scopes

Keys carry granular scopes. A `403` means the key is valid but missing the
scope an endpoint requires.

| Scope                                      | Grants access to |
| ------------------------------------------ | ---------------- |
| `participants:read` / `:write` / `:delete` | Participants     |
| `sessions:read` / `:write` / `:delete`     | Sessions         |
| `role:read` / `:write` / `:delete`         | Roles            |
| `round:read` / `:write` / `:delete`        | Rounds           |
| `interviewer:read` / `:write` / `:delete`  | Interviewers     |

## Content type

Requests and responses are JSON. Send `Content-Type: application/json` on
`POST` and `PATCH`. Responses are always JSON, except `204 No Content` on
successful deletes.

## Response shape

Single-resource responses wrap the result in a `data` field:

```json theme={null}
{
  "data": { "id": "e3a1c2d4-...", "status": "scheduled" }
}
```

List endpoints add a `meta` object with pagination details:

```json theme={null}
{
  "data": [ /* rows */ ],
  "meta": { "page": 1, "pageSize": 20, "total": 137, "totalPages": 7 }
}
```

## Pagination

List endpoints accept `page` and `pageSize` query parameters:

```text theme={null}
GET /api/v1/sessions?page=2&pageSize=50
```

<ParamField query="page" type="integer" default="1">
  1-based page number.
</ParamField>

<ParamField query="pageSize" type="integer" default="20">
  Items per page. Maximum `100`.
</ParamField>

Stop iterating once `page` reaches `meta.totalPages`.

## Idempotency

Creating a session is the one operation you never want to run twice. Pass an
`idempotency_key` in the request body — replaying the same key returns the
original session instead of scheduling a duplicate.

```json theme={null}
POST /api/v1/sessions
{
  "candidate_id": "ba4f2cdd-...",
  "role_id": "ce1cd564-...",
  "stage": "screen",
  "idempotency_key": "ats-job-8821-stage-screen"
}
```

The response includes `"idempotent": true` when a prior session was returned.

<Tip>
  Derive the key from a stable identifier in your own system — an ATS job +
  stage, for example — so automatic retries are naturally deduplicated.
</Tip>

## Errors

Errors return the appropriate HTTP status with an `error` message. Validation
failures (`400`) also include an `issues` array pinpointing the offending
fields.

```json theme={null}
{
  "error": "Validation error",
  "issues": [
    { "path": ["role_id"], "message": "Required" }
  ]
}
```

<AccordionGroup>
  <Accordion title="400 — Bad Request" icon="circle-x">
    The request body or query failed validation. Inspect `issues` for the
    specific fields.
  </Accordion>

  <Accordion title="401 — Unauthorized" icon="key">
    Missing or invalid API key.
  </Accordion>

  <Accordion title="402 — Payment Required" icon="credit-card">
    The workspace has no active paid plan, or you're out of session credits.
  </Accordion>

  <Accordion title="403 — Forbidden" icon="ban">
    The key is valid but lacks the required permission scope.
  </Accordion>

  <Accordion title="404 — Not Found" icon="circle-question">
    The resource doesn't exist, or your key can't see it.
  </Accordion>

  <Accordion title="409 — Conflict" icon="copy">
    The resource already exists — e.g. a duplicate participant email, or a
    duplicate session. Pass `force: true` to override the session check.
  </Accordion>

  <Accordion title="408 / 422 / 502 — Code execution" icon="terminal">
    `408` execution timed out (15s limit), `422` the language doesn't support
    batched execution, `502` the upstream runner failed.
  </Accordion>
</AccordionGroup>

Retries are safe on `5xx`. If a burst is throttled, honor the `Retry-After`
header and back off exponentially.

## Timestamps

All timestamps are ISO 8601 in UTC, and should be sent the same way:

```json theme={null}
{ "scheduled_at": "2026-06-02T07:48:31.200Z" }
```

## MCP server

The same engine is available over the Model Context Protocol for use inside
Claude, Cursor, and other MCP clients. See
[Remote MCP Server](/api-reference/remote-mcp-server/post-mcp).

## Versioning

The current version is `v1`. Backward-compatible additions (new fields, new
endpoints) ship under `v1` without notice — **write clients that ignore unknown
fields**. Breaking changes ship under a new prefix (`v2`), and `v1` keeps
working for at least 12 months after `v2` reaches general availability.

<Tip>
  Subscribe to the [changelog](https://intervyo.ai/blog/changelog) for new
  endpoints and deprecation timelines.
</Tip>
