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

# Job → Interview → Report guide

> End-to-end flow: list/create a job, create an interview, poll for the report.

Simple end-to-end flow for testing the Interview API: create (or reuse) a job, create an interview for a candidate, then poll for the report.

**Base URLs**

| Environment | URL                                   |
| ----------- | ------------------------------------- |
| Production  | `https://interview.qode.world/api/v1` |
| Staging     | `https://interview.gomu.ai/api/v1`    |

Every endpoint expects `Authorization: Bearer <api-key>`. See [API reference → Authentication](/api-reference/introduction).

## 0. (Optional) List current available jobs

Call [`GET /jobs`](/api-reference/endpoint/list-jobs).

Query params: `pageIndex` (default 1), `pageSize` (default 20, max 100).

```json theme={null}
{
  "success": true,
  "data": {
    "results": [
      { "name": "Software Engineer", "qodeJobId": "826ae7c5-...", "userId": "...", "createdAt": "...", "updatedAt": "..." }
    ],
    "total": 12
  }
}
```

Use this to check if a job already exists before creating a new one — see the billing note below. Reuse an existing `qodeJobId` in step 2 if found.

## 1. Create a job → get `qodeJobId`

Call [`POST /jobs`](/api-reference/endpoint/create-a-job).

```json theme={null}
{
  "title": "Backend Engineer",
  "description": "<h3>About the role</h3><p>We are hiring a backend engineer with strong TypeScript and Postgres experience...</p><p><b>Workplace:</b> Hybrid — Ho Chi Minh City, Vietnam</p><ul><li>Design and operate REST services</li><li>Own PostgreSQL data models</li></ul>",
  "language": "EN"
}
```

Required: `title`, `description`. Optional: `language` (default `EN`).

<Note>
  Send `description` as **rich text** — HTML markup (`<p>`, `<ul>`, `<br>`) or at least explicit `\n` line breaks, **minimum 700 characters**. The JD is stored and rendered as-is (JD PDF, interview context), so a single flattened plain-text line loses all formatting. It must state a **workplace type** (On-site/Remote/Hybrid) and a **location** — a description missing either returns `422` naming what to add.
</Note>

```json theme={null}
{
  "success": true,
  "data": { "qodeJobId": "826ae7c5-...", "name": "Backend Engineer" }
}
```

Save `data.qodeJobId` — used in steps 2 and 3.

<Warning>
  `POST /jobs` charges the same as creating a job via the Qode platform UI — each API job-create call consumes credit identically to a manual job create. Don't spam test jobs on prod; use staging for repeated test runs.
</Warning>

## 2. Create an interview for a candidate

Call [`POST /interviews`](/api-reference/endpoint/create-interview).

```json theme={null}
{
  "candidate_email": "candidate@example.com",
  "candidate_name": "Jane Doe",
  "cv_link": "https://.../resume.pdf",
  "qodeJobId": "826ae7c5-..."
}
```

All 4 fields required.

```json theme={null}
{
  "success": true,
  "data": { "interview_link": "https://...", "name": "Tracy interview | Jane Doe - Backend Engineer" }
}
```

Send `interview_link` to the candidate.

## 3. Get the list of meetings for a `qodeJobId`

Call [`GET /interviews?qodeJobId=<id>`](/api-reference/endpoint/list-interviews).

Returns the list of interviews/meetings for that job, each with a `meetingId`. Needed for step 4.

Status field: `isCompleted` (enum) per meeting:

| Value                | Meaning                   | Detailed report in step 4? |
| -------------------- | ------------------------- | -------------------------- |
| `COMPLETED`          | Interview fully done      | Yes                        |
| `PARTIALLY_COMPLETE` | Interview partly done     | Yes                        |
| `INCOMPLETED`        | Interview not done        | No                         |
| `null`               | Not started / no data yet | No                         |

Only call step 4 for meetings where `isCompleted` is `COMPLETED` or `PARTIALLY_COMPLETE`.

## 4. Get details for a `meetingId`

Call [`GET /interviews/{meetingId}/report`](/api-reference/endpoint/get-interview-report).

Call this only for meetings with `isCompleted` = `COMPLETED` or `PARTIALLY_COMPLETE` (from step 3) — `INCOMPLETED`/`null` meetings have no report data.

Response `data` fields of interest:

* `completedAt` — set once the interview is finished
* `transcript` — full scored report (`overallScore`, `skillScore`, `feedbackSummary`, `hiringDecision`, `questionSummary`, etc.)

Recommended polling (while `isCompleted` is `null`/`INCOMPLETED` in step 3): every 30–60s, timeout after \~15 min, retry on 5xx with backoff.

## Error codes (all endpoints)

| Code  | Meaning                                                                                              |
| ----- | ---------------------------------------------------------------------------------------------------- |
| `401` | API key missing/invalid/revoked                                                                      |
| `403` | Validation failed — check the `errors` array                                                         |
| `404` | Resource not found                                                                                   |
| `422` | (`POST /jobs`) JD is missing workplace type and/or location — the `errors` message names what to add |
| `5xx` | Temporary server issue — retry with backoff                                                          |

## Quick curl sequence

```bash theme={null}
API_KEY="qint_xxx"
BASE="https://interview.gomu.ai/api/v1"   # staging

# 1. create job — description must be rich text (HTML/line breaks), ≥700 chars,
#    and must state a workplace type + location (else 422)
JD='<h3>About the role</h3><p>We are hiring a Backend Engineer with strong TypeScript and Postgres experience to build and scale our API platform, working closely with product and data teams to ship reliable, well-tested services.</p><p><b>Workplace:</b> Hybrid — Ho Chi Minh City, Vietnam</p><h3>Responsibilities</h3><ul><li>Design, build, and operate high-throughput REST services in Node.js and TypeScript</li><li>Own PostgreSQL schema design, query performance, and data integrity</li><li>Set up observability, alerting, and CI/CD for the services you own</li><li>Review code and mentor junior engineers</li></ul><h3>Requirements</h3><ul><li>5+ years of backend experience</li><li>Strong SQL and data-modeling skills</li><li>Experience with distributed systems, message queues, and caching</li></ul>'
JOB=$(curl -s -X POST $BASE/jobs -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d "{\"title\":\"Backend Engineer\",\"description\":\"$(echo $JD | sed 's/"/\\"/g')\"}")
JOB_ID=$(echo $JOB | jq -r .data.qodeJobId)

# 2. create interview
curl -s -X POST $BASE/interviews -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d "{\"candidate_email\":\"test@example.com\",\"candidate_name\":\"Test Candidate\",\"cv_link\":\"https://example.com/cv.pdf\",\"qodeJobId\":\"$JOB_ID\"}"

# 3. list interviews to get meetingId
curl -s "$BASE/interviews?qodeJobId=$JOB_ID" -H "Authorization: Bearer $API_KEY"

# 4. poll report
curl -s "$BASE/interviews/{meetingId}/report" -H "Authorization: Bearer $API_KEY"
```
