# Quick Start with APIs

This guide walks you through creating your first background check using the Checkr API. You'll create a candidate, send an invitation, and retrieve the resulting report.

Staging environment
All requests in this guide use the staging environment (`api.checkr-staging.com`). No real checks are run.

Before you begin
Don't have a Checkr staging account and API key? Follow the steps on the [API Keys](/get-started/prerequisites) page first.

## Run with AI

Prefer to use an AI assistant? Copy the prompt below into Claude, ChatGPT, Cursor, or whichever one you use. It'll ask for a few details, then take you through the steps below itself.

Copy prompt
```markdown
You are helping me run through the Checkr Quick Start guide.

## Your first task
Fetch and read the Quick Start page:
https://docs-beta.checkr.com/get-started/quick-start.md

Use the steps described on that page as your execution plan. Steps 1, 2, and 4 are API calls — execute those. Step 3 (candidate completes the apply flow) isn't an API call; handle it as described below. Skip the webhook step at the end — it's a dashboard configuration step, not part of this walkthrough.

## Before you start, ask me for:
1. My Checkr staging API key
2. A candidate email address
3. The package slug to use — only ask if I mention I have a specific one configured; otherwise use the default package shown in the cURL example on the page

**Note:** If I don't have a staging API key yet, tell me to follow the steps at https://docs-beta.checkr.com/get-started/prerequisites before proceeding.

## How to execute
- Work through each step in order
- Make the actual API call for each step
- Show me each step's full response as pretty-printed JSON. Do not pipe through `jq`, `python`, or any external tool — format it yourself in your reply. Format only — never change the values. If the body isn't valid JSON, show it raw.
- Extract and carry forward any IDs between steps automatically
- If a step fails, explain what went wrong and suggest a fix
- When you reach the step where the candidate completes the application: pause, display the invitation URL from the previous response, and tell me to open it in my browser and complete the apply flow as if I were the candidate. Wait for me to confirm I've completed it before continuing.
- When retrieving the report, if the status isn't `complete` yet, wait about 10 seconds and check again, up to 3 times, before telling me to check back later.

Ready? Fetch the page first, then ask me for the inputs.
```

## Steps

### Create a candidate

A candidate is the individual being screened. Create one by providing their basic information.

```bash cURL
const response = await fetch('https://api.checkr-staging.com/v1/candidates', {
    method: 'POST',
    headers: {
        'Authorization': 'Basic ' + btoa('YOUR_API_KEY:'),
        'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: new URLSearchParams({
        first_name: 'John',
        last_name: 'Smith',
        email: 'john.smith@example.com',
        dob: '1990-01-01',
        ssn: 'XXX-XX-XXXX',
        zipcode: '90401',
        'work_location[country]': 'US',
    }),
});
const candidate = await response.json();
console.log(candidate.id); // Save this for the next step
```

```python
import requests

response = requests.post(
    'https://api.checkr-staging.com/v1/candidates',
    auth=('YOUR_API_KEY', ''),
    data={
        'first_name': 'John',
        'last_name': 'Smith',
        'email': 'john.smith@example.com',
        'dob': '1990-01-01',
        'ssn': 'XXX-XX-XXXX',
        'zipcode': '90401',
        'work_location[country]': 'US',
    }
)
candidate = response.json()
print(candidate['id'])  # Save this for the next step
```

```javascript
const response = await fetch('https://api.checkr-staging.com/v1/candidates', {
  method: 'POST',
  headers: {
    'Authorization': 'Basic ' + btoa('YOUR_API_KEY:'),
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: new URLSearchParams({
    first_name: 'John',
    last_name: 'Smith',
    email: 'john.smith@example.com',
    dob: '1990-01-01',
    ssn: 'XXX-XX-XXXX',
    zipcode: '90401',
    'work_location[country]': 'US',
  }),
});
const candidate = await response.json();
console.log(candidate.id); // Save this for the next step
```

Request fields
```json
{
  "title": "Candidate",
  "type": "object",
  "required": [
    "email"
  ],
  "properties": {
    "email": {
      "type": "string",
      "format": "email",
      "description": "Candidate's email address."
    },
    "first_name": {
      "type": "string",
      "description": "Candidate's first name."
    },
    "last_name": {
      "type": "string",
      "description": "Candidate's last name."
    },
    "dob": {
      "type": "string",
      "format": "date",
      "description": "Date of birth in `YYYY-MM-DD` format."
    },
    "ssn": {
      "type": "string",
      "description": "Social Security Number. Required for most US screenings."
    },
    "zipcode": {
      "type": "string",
      "pattern": "^\\d{5}$",
      "description": "Candidate's 5-digit zip code."
    },
    "work_locations": {
      "type": "array",
      "description": "Array of work location objects. Required for non-US screenings.",
      "items": {
        "type": "object"
      }
    }
  }
}
```

Response fields
```json
{
  "title": "Candidate",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "The candidate ID. Save this — you'll use it in the next step."
    },
    "object": {
      "type": "string",
      "const": "candidate",
      "description": "Always 'candidate'"
    },
    "report_ids": {
      "type": "array",
      "description": "Report IDs associated with this candidate. Empty until a check is ordered.",
      "items": {
        "type": "string"
      }
    }
  }
}
```

### Create an invitation

An invitation emails the candidate a link to complete their background check application. Specify the candidate_id from Step 1 and the package to run.

```bash cURL
curl -u YOUR_API_KEY: \
  -X POST https://api.checkr-staging.com/v1/invitations \
  -d "candidate_id=CANDIDATE_ID" \
  -d "package=basic_package"
```

```python Python
import requests

response = requests.post(
    'https://api.checkr-staging.com/v1/invitations',
    auth=('YOUR_API_KEY', ''),
    data={
        'candidate_id': 'CANDIDATE_ID',
        'package': 'basic_package',
    }
)
invitation = response.json()
print(invitation['invitation_url'])  # Sent to the candidate
```

```javascript JavaScript
const response = await fetch('https://api.checkr-staging.com/v1/invitations', {
  method: 'POST',
  headers: {
    'Authorization': 'Basic ' + btoa('YOUR_API_KEY:'),
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: new URLSearchParams({
    candidate_id: 'CANDIDATE_ID',
    package: 'basic_package',
  }),
});
const invitation = await response.json();
console.log(invitation.invitation_url); // Sent to the candidate
```

Request fields
```json
{
  "title": "CreateReportRequest",
  "type": "object",
  "required": [
    "candidate_id",
    "package"
  ],
  "properties": {
    "candidate_id": {
      "type": "string",
      "description": "ID of the candidate from Step 1."
    },
    "package": {
      "type": "string",
      "description": "Slug of the screening package to run (e.g. driver_pro, tasker_standard)."
    },
    "work_locations": {
      "type": "array",
      "description": "Array of work location objects. Required for hierarchy-enabled accounts.",
      "items": {
        "type": "object"
      }
    },
    "tags": {
      "type": "array",
      "description": "Optional tags to apply to the resulting report.",
      "items": {
        "type": "string"
      }
    }
  }
}
```

Response fields
```json
{
  "title": "Invitation",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "The invitation ID."
    },
    "status": {
      "type": "string",
      "enum": [
        "pending",
        "completed",
        "expired"
      ],
      "description": "Current status: pending, completed, or expired."
    },
    "invitation_url": {
      "type": "string",
      "format": "uri",
      "description": "The URL sent to the candidate to complete their application."
    },
    "report_id": {
      "type": [
        "string",
        "null"
      ],
      "description": "ID of the report created once the candidate completes the apply flow. null until then."
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "Timestamp when the invitation expires."
    }
  }
}
```

### Candidate completes the apply flow

The invitation emails the candidate a link to Checkr’s hosted apply flow, where they confirm their information, provide consent, and submit their application.
In staging, you can simulate this step using Checkr’s test tools — no real candidate interaction is required.

### Retrieve the report

Once the candidate completes their application and the screenings process, a report is created. Retrieve it using the `report_id` from the invitation response or via webhook.

```bash cURL
curl -u YOUR_API_KEY: \
  https://api.checkr-staging.com/v1/reports/REPORT_ID
```

```python Python
import requests

response = requests.get(
    'https://api.checkr-staging.com/v1/reports/REPORT_ID',
    auth=('YOUR_API_KEY', '')
)
report = response.json()
print(report['status'])  # pending, complete, suspended, etc.
print(report['result'])  # clear or consider
```

```javascript JavaScript
const response = await fetch('https://api.checkr-staging.com/v1/reports/REPORT_ID', {
  headers: {
    'Authorization': 'Basic ' + btoa('YOUR_API_KEY:'),
  },
});
const report = await response.json();
console.log(report.status); // pending, complete, suspended, etc.
console.log(report.result); // clear or consider
```

Response fields
```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Report",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "The report ID."
    },
    "status": {
      "type": "string",
      "enum": [
        "pending",
        "complete",
        "suspended",
        "dispute",
        "canceled"
      ],
      "description": "Overall report status: pending, complete, suspended, dispute, or canceled."
    },
    "result": {
      "type": [
        "string",
        "null"
      ],
      "enum": [
        "clear",
        "consider",
        null
      ],
      "description": "Screening outcome: clear or consider. null while the report is pending."
    },
    "adjudication": {
      "type": "string",
      "enum": [
        "engaged",
        "pre_adverse_action",
        "post_adverse_action"
      ],
      "description": "Adjudication status: engaged, pre_adverse_action, or post_adverse_action."
    },
    "completed_at": {
      "type": "string",
      "format": "date-time",
      "description": "Timestamp when all screenings finished."
    },
    "candidate_id": {
      "type": "string",
      "description": "ID of the associated candidate."
    }
  }
}
```

Rather than polling for report status, configure a webhook endpoint to receive real-time updates when a report or screening status changes.

1. Go to **Dashboard → Developer → Webhooks**
2. Add your endpoint URL
3. Select the events to subscribe to (e.g., `report.completed`)


Checkr will POST to your endpoint when the report is ready.

## Next steps

Webhooks
Go deeper on real-time events — payloads, security, and the full event catalog.

API Reference
Full API reference for candidates, reports, and webhooks.