## Test Accounts

### Overview

Test accounts are a crucial part of the Checkr Trust API integration process. They allow you to validate your integration without making calls to production data sources. This guide explains how test accounts work and provides details about the available test data.

Test accounts are designated with the stage "test" and are designed to:

- Validate your integration code works correctly
- Understand the API response formats
- Test error handling scenarios
- Familiarize yourself with the product workflow


## Available Test Scenarios

The specific mock scenarios your account can run are served by the API rather than listed here.
[`GET /test_scenarios`](/v1#operation/get-test-scenarios) returns the catalog scoped to the
products enabled on your account. Each entry gives you the scenario's `title` and `description`,
its `result_kind` (`records_found`, `no_records`, `not_found`, and so on), the exact `inputs` that
trigger it, and `match_keys` — the subset of those inputs that actually selects it.

Fetching the catalog instead of copying values out of a docs page means your integration tests and
scenario pickers stay correct as we add, retire, or re-tune scenarios, and you only ever see
scenarios your account is authorized to run.

Send **every** field in `inputs`, not just the fields in `match_keys`. Some are required for
request validation, and some are compared against the fixture during identity matching (county
checks compare `dob`, for example), even though they are not what selects the scenario.
`match_keys` lists the fields that choose which scenario you get — change anything outside that
list and you still get the same scenario; change a field inside it and you fall through to the
empty-result default.

A Live account receives an empty array: live requests are served by real data sources, so there is
no mock data to advertise unless Checkr has allowlisted the account for production test searches.
Once allowlisted, the catalog returns the scenarios for the supported products. See
[Accounts](/accounts) for the environment model.

## Production Test Searches

Checkr can allow an approved live account to run deterministic scenarios through Regulated Criminal
Reports. Checkr allowlists the customer email domains on the account; there is no per-product setup.

To select test data, send the scenario inputs from
`GET /test_scenarios?product=regulated_criminal_report` and set `email` to an allowlisted address
whose local part ends with `+test`, or `+test` followed by letters or numbers, such as
`candidate+testQE1@example.com`. A request that uses `profile_id` instead of inline PII is matched
on the stored profile's email.

A test tag on a domain that is not allowlisted, or on any other product, follows the normal
live-provider path. A matching production test search does not call a live criminal-data provider.
If the email selects test mode but the name is not a persona for this product, the request fails
with a validation error, so a mistyped name cannot quietly return an empty report. The completion
webhook is the same `regulated_criminal_report.completed` event a live report sends, and fires
within 30 seconds.

## Getting Access

Please contact your account representative or [support@checkrtrust.com](mailto:support@checkrtrust.com) for additional questions.

## Available Products

Test accounts currently support:

- [Instant Criminal Record Checks](/v1#tag/instant-criminal-checks)
- [Targeted Instant Criminal Checks](/v1#tag/instant-criminal-checks)
- [Criminal Checks](/v1#tag/criminal-checks)
- [Sex Offender Registry Checks](/v1#tag/instant-criminal-checks)
- [Regulated Instant Criminal Checks](/v1#tag/regulated-instant-criminal-checks)
- [Regulated Criminal Reports](/v1#tag/regulated-criminal-reports)
- [Regulated Eviction Checks](/v1#tag/regulated-eviction-checks)
- [County Checks](/v1#tag/county-checks)
- [Identity Verifications (PII Validation)](/v1#tag/identity-verifications)
- [Identity Verifications (Document Verification)](/v1#tag/identity-verifications)
- [Identity Verifications (Personal Identity Records)](/v1#tag/identity-verifications)
- [Identity Verifications (Reverse Phone Lookup)](/v1#tag/identity-verifications)
- [Driver Checks](/v1#tag/driver-checks) (asynchronous; results delivered via webhook simulation)
Other products are not available in test mode and attempting to enable them for a test account will not be allowed.


### Product Behavior and Error Handling

1. **Using Test Data**
  - When making requests with PII that matches our test profiles, you'll receive predefined mock responses
  - When making requests with PII that doesn't match test profiles, you'll receive a successful response (HTTP 200) with empty results
  - This allows you to test both your success and "no results found" handling
  - **Important**: which fields select a scenario varies by product, and each scenario's `match_keys` tells you exactly which ones. Fields outside `match_keys` are still required, but changing them does not change which scenario you get. Three behaviors `match_keys` cannot express on its own:
    - **Driver Checks** (`driver_license_status`, `motor_vehicle_report`) still enforce the same input validation as live checks — required fields and state-specific requirements — even though mock selection is deterministic.
    - **Reverse Phone Lookup** (`reverse_phone`) matches US numbers on the 10-digit national number, so formatting and country code do not have to match exactly.
    - **County Checks** (`county_criminal`, `county_criminal_regulated`) apply identity matching against the fixture record DOB on name-based searches. Send the `dob` from the scenario's `inputs`, or the records are filtered out and you get an empty result set.
2. **Product Authorization**
  - Each test account must have products explicitly enabled via product configurations
  - Attempting to use a product that isn't enabled will result in a 401 Unauthorized response


## Worked Examples

Full request/response payloads for a few representative scenarios.

### Example 1: Some records returned, some removed by FCRA

Request (James Wilson):

```json
{
  "first_name": "James",
  "last_name": "Wilson",
  "dob": "19850420",
  "permissible_purpose": "Employment",
  "filter_context": {
    "candidate_jurisdiction": {
      "state": "FL"
    }
  }
}
```

Response (201) — one record returned, one removed by FCRA 7-year rule:

```json
{
  "id": "<uuid>",
  "check_type": "instant_criminal_regulated",
  "profile_id": "<uuid>",
  "results": [
    {
      "category": "Criminal/traffic",
      "record_id": "<record-id>",
      "person": {
        "first_name": "JAMES",
        "last_name": "WILSON",
        "dob": "19850420"
      },
      "cases": [
        {
          "court_name": "FL Orange Courts",
          "charges": [
            {
              "description": "BATTERY",
              "offense_date": "20220601",
              "record_date": "20220601",
              "dispositions": [
                { "disposition_type": "conviction", "disposition": "ADJUDICATED GUILTY" }
              ],
              "checks": []
            }
          ],
          "checks": []
        }
      ],
      "source": {
        "id": "FL_Orange_View",
        "category": "court",
        "state": "FL"
      },
      "checks": []
    }
  ]
}
```

### Example 2: All records removed by FCRA

Request (Emma Davis):

```json
{
  "first_name": "Emma",
  "last_name": "Davis",
  "dob": "19900712",
  "permissible_purpose": "Employment",
  "filter_context": {
    "candidate_jurisdiction": {
      "state": "FL"
    }
  }
}
```

Response (201) — all records removed by FCRA, `results` is empty:

```json
{
  "id": "<uuid>",
  "check_type": "instant_criminal_regulated",
  "profile_id": "<uuid>",
  "results": []
}
```

### Example: Regulated Eviction Check (record found)

Request:

```json
{
  "first_name": "Patricia",
  "last_name": "Holloway",
  "dob": "19850314",
  "ssn": "123-45-6789",
  "addresses": [
    {
      "street": "482 Birch Lane",
      "city": "Springfield",
      "state": "IL",
      "zip_code": "62704"
    }
  ]
}
```

Response (201):

```json
{
  "id": "<uuid>",
  "check_type": "regulated_eviction_check",
  "profile_id": "<uuid>",
  "created_at": "<datetime>",
  "completed_at": "<datetime>",
  "results": [
    {
      "first_name": "Patricia",
      "last_name": "Holloway",
      "middle_name": "Ann",
      "address": "482 Birch Lane",
      "city": "Springfield",
      "state": "IL",
      "zip_code": "62704",
      "zone": "Springfield Metro",
      "subject": {
        "full_name": "Patricia Ann Holloway",
        "dob": null,
        "address": "482 Birch Lane, Springfield, IL 62704",
        "aliases": null,
        "state": "IL",
        "jurisdiction": null,
        "source": null,
        "case_number": "2023-EV-004471",
        "category": "Eviction",
        "status": null,
        "comments": null
      },
      "case": {
        "court": "Sangamon County Circuit Court",
        "case_number": "2023-EV-004471",
        "filing_date": "2023-06-12",
        "notice_type": "Forcible Entry and Detainer",
        "agency_state": null,
        "agency_county": null,
        "dismissal_date": null,
        "default_judgement": false,
        "restored_premises": false,
        "plaintiff": {
          "name": "Riverstone Property Management LLC",
          "phone": "217-555-0182",
          "attorney": "Gregory L. Marsh",
          "attorney_phone": "217-555-0199"
        },
        "judgement": {
          "date": "2023-07-05",
          "amount_cents": 347500,
          "type": "Judgment for Plaintiff",
          "for": "Plaintiff",
          "satisfaction_amount_cents": null,
          "release_date": null
        }
      }
    }
  ],
  "run_notes": []
}
```

### Example: Regulated Eviction Check (no records found)

Request:

```json
{
  "first_name": "John",
  "last_name": "Smith",
  "ssn": "123-45-6789",
  "addresses": [
    {
      "street": "123 Main St",
      "city": "Springfield",
      "state": "IL",
      "zip_code": "62701"
    }
  ]
}
```

Response (201):

```json
{
  "id": "<uuid>",
  "check_type": "regulated_eviction_check",
  "profile_id": "<uuid>",
  "created_at": "<datetime>",
  "completed_at": "<datetime>",
  "results": [],
  "run_notes": []
}
```

### Example: Reverse Phone Lookup

Reverse phone (`idv_type: reverse_phone`) is synchronous. Submit `POST /v1/identity_verifications` with `country_code` and `phone`. Mock selection uses the normalized US 10-digit number (or country code + national digits for international numbers).

Example request (found):

```json
{
  "idv_type": "reverse_phone",
  "country_code": "1",
  "phone": "202-555-0100"
}
```

### Document Verification in Test Accounts

Document Verification uses name-based mock selection (case-insensitive). For test accounts, the API returns a shared cached `collection_link` and completes results asynchronously via a delayed job; the Socure collection session is not used to determine the final results.

Fetch the scenarios for this product, and the exact inputs each one needs, from [`GET /test_scenarios`](/v1#operation/get-test-scenarios) — see [Available Test Scenarios](#available-test-scenarios) above.

### Using Test Data

1. Fetch the scenario from [`GET /test_scenarios`](/v1#operation/get-test-scenarios) and send
its inputs exactly — every field in `inputs`, not just the ones in `match_keys`.
2. Check `match_keys` to see which of those inputs choose the scenario. For most products it is
first and last name; driver checks select on `driver_license_number`, reverse phone on `phone`,
and county case-number searches on `case_number`.
3. Matching is case-insensitive and ignores surrounding whitespace.
4. For Checks endpoints, PII combinations with no scenario return empty results with a 200 OK
status; for PII Validation, non-matching names return a successful response with all
attribute scores 0 and a CT-0523 result context.
5. Test accounts cannot access production data.


## PII Validation in Test Accounts

- **Synchronous results**: `pii_validation` returns results immediately in the response.
- **Matching rules**: Only `first_name` and `last_name` determine which mock response is returned.
- **Unknown names**: Returns a successful response with minimal `attribute_match_scores` and a `result_context` entry for CT-0523 ("Name cannot be resolved to the individual").
- **Result fields**: Results include `attribute_match_scores` per attribute (0 or 100), an `overall_match_score` (0, 50, or 100), and a `result_context` array of objects derived from provider reason codes (each item includes `code`, `title`, and `category`).


### Example: Create PII Validation (from PII)

Request:

```json
{
  "first_name": "Marcus",
  "last_name": "Williams",
  "idv_type": "pii_validation",
  "email": "test@example.com"
}
```

Response (201):

```json
{
  "id": "<uuid>",
  "idv_type": "pii_validation",
  "results": {
    "attribute_match_scores": {
      "first_name": 100,
      "last_name": 100,
      "dob": 100,
      "phone": 100,
      "email": 100,
      "address": 100,
      "city": 100,
      "state": 100,
      "zip_code": 100,
      "ssn": 100
    },
    "overall_match_score": 100,
    "result_context": [
      {
        "code": "<CT-code>",
        "title": "<human-readable title>",
        "category": "informational"
      }
    ]
  }
}
```

### Example: Create PII Validation (unknown name)

Request:

```json
{
  "first_name": "Unknown",
  "last_name": "User",
  "idv_type": "pii_validation"
}
```

Response (201):

```json
{
  "id": "<uuid>",
  "idv_type": "pii_validation",
  "results": {
    "attribute_match_scores": {
      "first_name": 0,
      "last_name": 0,
      "dob": 0,
      "phone": 0,
      "email": 0,
      "address": 0,
      "city": 0,
      "state": 0,
      "zip_code": 0,
      "ssn": 0
    },
    "overall_match_score": 0,
    "result_context": [
      {
        "code": "CT-0523",
        "title": "Name cannot be resolved to the individual",
        "category": "rejection"
      }
    ]
  }
}
```

## Testing Error Scenarios

When integrating with the API, it's important to test how your application handles various error conditions. Here are key scenarios you should test:

### 1. Input Validation Errors (400 Bad Request)

Test these scenarios to ensure your application handles validation errors gracefully:

- **Invalid Date Format**

```json
{
  "first_name": "Marcus",
  "last_name": "Williams",
  "dob": "01-15-1988" // Invalid format, should be YYYYMMDD
}
```
- **Missing Required Fields**

```json
{
  "first_name": "Marcus"
  // Missing required last_name field
}
```
- **Invalid Field Format**

```json
{
  "first_name": "Marcus",
  "last_name": "Williams",
  "ssn": "123456789" // Invalid format, should be XXX-XX-XXXX
}
```


### 2. Authorization Errors (401 Unauthorized)

- Attempting to use products not enabled for your account
- Using expired or invalid access tokens
- Using incorrect client credentials


### 3. Empty Results vs Errors

It's important to understand the difference between error responses and valid empty results:

- **Empty Results (200 OK)**
  - Using valid PII that doesn't match any test profiles
  - The response will be successful with an empty results array

```json
{
  "results": []
}
```
- **Error Response (400 Bad Request)**
  - Using invalid PII formats or missing required fields
  - The response will include specific error details

```json
{
  "errors": [
    {
      "code": "validation_error",
      "title": "Invalid date format",
      "source": {
        "pointer": "/dob"
      }
    }
  ]
}
```


### 4. Product-Specific Testing

For each product enabled on your account (see [Available Test Scenarios](#available-test-scenarios)
for the scenarios available per product):

1. **Success Path**
  - Use test profile names to get known results
  - Verify all response fields are correctly parsed
2. **Empty Results Path**
  - Use valid but non-matching names
  - Verify your application handles empty results appropriately
3. **Error Path**
  - Attempt to use unsupported products
  - Verify error handling for invalid input formats


## Error Testing

1. **Implement Proper Error Handling**
The API follows the [JSON:API error format](https://jsonapi.org/format/#error-objects). All errors will be returned in this standardized format:

```json
{
  "errors": [
    {
      "code": "validation_error",
      "title": "Invalid date format",
      "source": {
        "pointer": "/dob"
      }
    }
  ]
}
```
Common error scenarios you might encounter:

```json
// Invalid SSN Format
{
  "errors": [
    {
      "code": "validation_error",
      "title": "Invalid SSN format",
      "source": {
        "pointer": "/ssn"
      }
    }
  ]
}

// Missing Required Field
{
  "errors": [
    {
      "code": "validation_error",
      "title": "Last name is required",
      "source": {
        "pointer": "/last_name"
      }
    }
  ]
}

// Unauthorized Product Access
{
  "errors": [
    {
      "code": "validation_error",
      "title": "The product requested is not enabled for this account",
      "source": {
        "pointer": "/check_type"
      }
    }
  ]
}
```
Your error handling should:
  - Parse the `errors` array to handle multiple errors
  - Use the `code` field for programmatic error handling
  - Display the `title` field for user-friendly error messages
  - Use the `source.pointer` to highlight specific form fields that need correction
2. **Validate All Response Fields**
  - Check both successful and error responses
  - Verify your application correctly processes all fields
3. **Test Edge Cases**
  - Very long names
  - test names with suffixes, prefixes, multiple parts of names
  - Special characters in names
  - Different date formats
  - Missing optional fields


Remember that test accounts are designed to help you validate your integration thoroughly before moving to production. Take advantage of these error scenarios to ensure your application handles all cases gracefully.

## Other Scenarios to Test

1. **Test Error Handling**:
  - Try requests with invalid PII to ensure your application handles empty results appropriately
  - Test unauthorized product access to ensure your error handling works
  - Validate your response parsing for both successful and empty results
2. **Validate Response Parsing**:
  - Use different test profiles to ensure your code properly handles various response formats
  - Test both criminal records and sex offender registry responses
3. **Test All Workflows**:
  - Exercise both successful and unsuccessful paths in your integration
  - Verify your handling of empty results (200 OK with no records)
  - Validate your error handling for unauthorized products (401)


## County Checks in Test Accounts

County checks are asynchronous. For test accounts, provider completion is simulated via a delayed job. Create a county check as normal; results are populated after a short delay and webhook notifications are delivered using your configured webhook destination.

### Behavior and matching rules

- Result simulation runs about 60 seconds after check creation
- For name-based searches, mock **fixture selection** is based on `first_name` + `last_name` (case-insensitive). State and `county_fips_code` are still required and validated, but they do not choose which fixture is loaded.
- For name-based searches, after the fixture loads, identity matching compares the request/profile DOB to the DOB on each fixture record. Pass the `dob` listed for that profile (YYYYMMDD). A mismatched DOB still completes successfully (`status: complete`) but returns an empty `results` array because the records are filtered out.
- For case-number searches (`case_number` + `state` + `county_fips_code`), mock selection is based on `case_number` (case-insensitive). Identity matching is not applied, so DOB is not required for those scenarios.
- Case number search is supported only for `NC` and `MN`; send the `state` and `county_fips_code` from the scenario's `inputs` so request parameters align with returned record jurisdictions
- Required request fields are still validated in test mode (`state`, `county_fips_code` as either 5-digit FIPS or `statewide` for name-based searches; 5-digit FIPS only for case-number searches)
- Unknown names or unknown case numbers return a completed result with an empty `records` array
- `case_number` must contain only letters, numbers, spaces, and hyphens (no underscores)


Fetch the scenarios for this product, and the exact inputs each one needs, from [`GET /test_scenarios`](/v1#operation/get-test-scenarios) — see [Available Test Scenarios](#available-test-scenarios) above.

## Moving to Production

When you're ready to move to production:

1. Work with your account representative to determine the appropriate account stage (pilot or live)
2. Update your integration to use production credentials
3. Begin testing with real PII data


## Important Notes

- Test accounts are free to use and do not incur charges
- Test data is static and does not change
- Test accounts cannot access production data
- Some test profiles may be updated or added over time
- Contact support if you need additional test scenarios


## Driver Checks in Test Accounts

Driver checks are asynchronous. For test accounts, the provider webhook is simulated via a delayed job. Create a driver check as normal; results are delivered later via webhook and reflected on `GET /v1/driver_checks/{id}`.

### MVR notes

Fetch the scenarios for this product, and the exact inputs each one needs, from [`GET /test_scenarios`](/v1#operation/get-test-scenarios) — see [Available Test Scenarios](#available-test-scenarios) above.

Notes:

- The `orderDetails.requestedAs.clientReferenceId` is set to your driver check id for correlation.
- For license numbers with no scenario, the mock provider returns a NOT_FOUND result (no licenses or events).
- A requester code is required for `CA`, `PA`, and `UT`. Pass `requester_code` on the request, or configure `ca_requestor_code` / `pa_requestor_code` / `ut_requestor_code` in the `motor_vehicle_report` product settings; a configured code is used automatically when the param is omitted.


### DLSC Mock Input → Output Scenarios

Driver License Status Checks (DLSC) are also asynchronous. For test accounts, we simulate Tessera completion via webhook and you will receive a signed event of type:

- `driver_license_status.completed`


#### Required fields (still validated in test mode)

Even though the **mock result selection** is deterministic, the API still enforces the same request validation rules as live driver checks (e.g. required fields and certain state-specific requirements). At minimum you must send:

- `check_type: "driver_license_status"`
- `first_name`, `last_name`, `dob` (YYYYMMDD)
- `driver_license_number`, `driver_license_state`


Some states require additional fields:

- `zip_code` is required for `RI`
- `ssn` is required for `PA`, `TX`, and `WV` (if you do not provide it, the system will attempt to derive it; if it cannot, you’ll receive a validation error)


`requester_code` is not required for DLSC in any state (it is an MVR-only requirement for `CA`, `PA`, and `UT`).

#### DLSC notes

Fetch the scenarios for this product, and the exact inputs each one needs, from [`GET /test_scenarios`](/v1#operation/get-test-scenarios) — see [Available Test Scenarios](#available-test-scenarios) above.

Notes:

- For DLSC, the high-level result is represented in the `results.passenger.validity` field (see the `driver_check_driver_license_status_result` schema).
- For Texas (TX), `validity` reflects Texas DPS's driver eligibility status (license fees, compliance, and medical certification standing) — not license validity. It cannot detect an expired license, and does not indicate the license's expiration date or class.
- Mock selection for DLSC is based on `check_type` + `driver_license_number`; other PII fields do not change which mock scenario you receive (but may be required for validation depending on `driver_license_state`).