<!-- Generated by scripts/gen-developer-docs.ts from src/developers/content/recruit/quickstart.md — do not edit. -->

# Quickstart

> Create a test key, create a role, listen for events, invite a candidate and simulate a finished interview — in about 10 minutes, without sending a real email or using a credit.

Every sample below runs as written against test mode: set `RECRUIT_API_KEY` to a test key (`r100x_test_…`) and the
same calls work later with a live key. Each call answers JSON.

## 1. Create a test key

In Recruit100x, open **Settings › Integrations › API keys › Create key**, choose **Mode: Test** and the permissions
you need (add **Create roles** for step 2). The key is shown once. Check it:

**curl**

```bash
curl -sS "${RECRUIT_BASE:-https://www.recruit100x.com}/api/v1/me" \
  -H "Authorization: Bearer $RECRUIT_API_KEY"
```

## 2. Create a role

Send the job description as text (or `"jd": {"mode": "url", "url": …}` for a job posting link). The role starts as a
draft while its interview guide is drafted.

> **Open-link default.** New roles get your workspace's open-link policy, which is open unless you changed it. Send `"open_link": {"policy": "invite_only"}` if your system decides who is eligible.

**curl**

```bash
curl -sS -X POST "${RECRUIT_BASE:-https://www.recruit100x.com}/api/v1/roles" \
  -H "Authorization: Bearer $RECRUIT_API_KEY" \
  -H "Idempotency-Key: create-role-req-1042" \
  -H "Content-Type: application/json" \
  -d '{
  "jd": { "mode": "paste", "text": "Payroll Lead\nRun payroll for 300 people across three US states. You own the close calendar, the year-end filings and the audits." },
  "client_label": "Acme Corp",
  "location": { "country": "US" },
  "external_ref": "req-1042",
  "open_link": { "policy": "invite_only" }
}'
```

**Node**

```js
const base = process.env.RECRUIT_BASE || "https://www.recruit100x.com";
const res = await fetch(`${base}/api/v1/roles`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RECRUIT_API_KEY}`,
    "Idempotency-Key": "create-role-req-1042-node",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "jd": { "mode": "paste", "text": "Payroll Lead\nRun payroll for 300 people across three US states. You own the close calendar, the year-end filings and the audits." },
    "client_label": "Acme Corp",
    "location": { "country": "US" },
    "external_ref": "req-1042",
    "open_link": { "policy": "invite_only" }
  }),
});
console.log(JSON.stringify(await res.json()));
```

**Python**

```python
import json, os, urllib.request

base = os.environ.get("RECRUIT_BASE", "https://www.recruit100x.com")
body = {
  "jd": { "mode": "paste", "text": "Payroll Lead\nRun payroll for 300 people across three US states. You own the close calendar, the year-end filings and the audits." },
  "client_label": "Acme Corp",
  "location": { "country": "US" },
  "external_ref": "req-1042",
  "open_link": { "policy": "invite_only" }
}
req = urllib.request.Request(
    base + "/api/v1/roles",
    data=json.dumps(body).encode(),
    method="POST",
    headers={
        "Authorization": "Bearer " + os.environ["RECRUIT_API_KEY"],
        "Idempotency-Key": "create-role-req-1042-python",
        "Content-Type": "application/json",
    },
)
with urllib.request.urlopen(req) as res:
    print(json.dumps(json.load(res)))
```

Keep `role.id` (`ROLE_ID` below). `guide_status` is `drafting`; a person on your team approves the guide in the
dashboard (or from the approval email), then the role becomes `active`. In test mode the guide is approved by itself
about 10 seconds later.

## 3. Listen for events

Subscribe a webhook with `"api_version": "2026-11-01"` to receive `role.ready` (the guide is approved — you can invite)
and `report.ready`. The answer carries the signing `secret`, shown only once.

**curl**

```bash
curl -sS -X POST "${RECRUIT_BASE:-https://www.recruit100x.com}/api/v1/hooks" \
  -H "Authorization: Bearer $RECRUIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "'"$HOOK_URL"'", "events": ["role.ready", "report.ready"], "api_version": "2026-11-01" }'
```

**Node**

```js
const base = process.env.RECRUIT_BASE || "https://www.recruit100x.com";
const res = await fetch(`${base}/api/v1/hooks`, {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.RECRUIT_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ url: process.env.HOOK_URL, events: ["role.ready", "report.ready"], api_version: "2026-11-01" }),
});
// Keep the secret: it signs every delivery and is shown only here.
console.log(JSON.stringify(await res.json()));
```

**Python**

```python
import json, os, urllib.request

base = os.environ.get("RECRUIT_BASE", "https://www.recruit100x.com")
body = {"url": os.environ["HOOK_URL"], "events": ["role.ready", "report.ready"], "api_version": "2026-11-01"}
req = urllib.request.Request(
    base + "/api/v1/hooks",
    data=json.dumps(body).encode(),
    method="POST",
    headers={"Authorization": "Bearer " + os.environ["RECRUIT_API_KEY"], "Content-Type": "application/json"},
)
with urllib.request.urlopen(req) as res:
    print(json.dumps(json.load(res)))  # keep the secret: it is shown only here
```

See [Webhooks](/developers/webhooks) for every event and for verifying signatures.

## 4. Invite a candidate

With `"delivery": "return_link"` you deliver the link yourself: each invited row carries `screen_url` once. (With
`"recruit100x"` we email the candidate and send a reminder.)

**curl**

```bash
curl -sS -X POST "${RECRUIT_BASE:-https://www.recruit100x.com}/api/v1/roles/$ROLE_ID/invites" \
  -H "Authorization: Bearer $RECRUIT_API_KEY" \
  -H "Idempotency-Key: invite-app-77" \
  -H "Content-Type: application/json" \
  -d '{
  "delivery": "return_link",
  "candidates": [
    { "full_name": "Sam Rivera", "email": "sam.rivera@example.com", "external_ref": "app-77" }
  ]
}'
```

**Node**

```js
const base = process.env.RECRUIT_BASE || "https://www.recruit100x.com";
const res = await fetch(`${base}/api/v1/roles/${process.env.ROLE_ID}/invites`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RECRUIT_API_KEY}`,
    "Idempotency-Key": "invite-app-77-node",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "delivery": "return_link",
    "candidates": [
      { "full_name": "Sam Rivera", "email": "sam.rivera@example.com", "external_ref": "app-77" }
    ]
  }),
});
// With "return_link", each invited row carries screen_url once — send it to the candidate yourself.
console.log(JSON.stringify(await res.json()));
```

**Python**

```python
import json, os, urllib.request

base = os.environ.get("RECRUIT_BASE", "https://www.recruit100x.com")
body = {
  "delivery": "return_link",
  "candidates": [
    { "full_name": "Sam Rivera", "email": "sam.rivera@example.com", "external_ref": "app-77" }
  ]
}
req = urllib.request.Request(
    base + "/api/v1/roles/" + os.environ["ROLE_ID"] + "/invites",
    data=json.dumps(body).encode(),
    method="POST",
    headers={
        "Authorization": "Bearer " + os.environ["RECRUIT_API_KEY"],
        "Idempotency-Key": "invite-app-77-python",
        "Content-Type": "application/json",
    },
)
with urllib.request.urlopen(req) as res:
    print(json.dumps(json.load(res)))
```

## 5. Simulate the interview

In test mode `screen_url` opens a test page (`/test/screen/{token}`) with **Simulate completion**: it sends
`screen.completed`, then `report.ready` with a sample report, to your test webhooks. Then read the report:

**curl**

```bash
curl -sS "${RECRUIT_BASE:-https://www.recruit100x.com}/api/v1/roles/$ROLE_ID/reports?state=ready" \
  -H "Authorization: Bearer $RECRUIT_API_KEY"
```

**curl**

```bash
curl -sS "${RECRUIT_BASE:-https://www.recruit100x.com}/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $RECRUIT_API_KEY"
```

**Node**

```js
const base = process.env.RECRUIT_BASE || "https://www.recruit100x.com";
const res = await fetch(`${base}/api/v1/reports/${process.env.REPORT_ID}`, {
  headers: { Authorization: `Bearer ${process.env.RECRUIT_API_KEY}` },
});
console.log(JSON.stringify(await res.json()));
```

**Python**

```python
import json, os, urllib.request

base = os.environ.get("RECRUIT_BASE", "https://www.recruit100x.com")
req = urllib.request.Request(base + "/api/v1/reports/" + os.environ["REPORT_ID"], headers={"Authorization": "Bearer " + os.environ["RECRUIT_API_KEY"]})
with urllib.request.urlopen(req) as res:
    print(json.dumps(json.load(res)))
```

Next: [Authentication and scopes](/developers/authentication), [Invites](/developers/invites), [Errors](/developers/errors).
