Overview
The base URL for every request is:
https://app.escreenly.com/api/v1
Requests and responses are JSON. Successful responses wrap their content in a data key. Reports
are identified by their reference, such as ES-7K4Q-92XM. Responses never include Social
Security numbers, dates of birth or license numbers.
Webhooks aren't available yet. To follow a check, retrieve the report periodically, for example every few minutes while it's in progress. Your team is also emailed when each report completes.
Authentication
An account owner or admin creates API keys under Settings → API keys. Each key is shown once when created; store it securely. Keys belong to the employer account, not a person, and only work while the account is approved. Send the key as a bearer token:
Authorization: Bearer es_live_...
Because keys aren't tied to a person, the API returns full results, including Clear/Consider and records. Keep keys on your servers, never in a browser or mobile app.
Errors
Errors return a JSON body with an error code:
400bad_requestA required parameter, such as report, is missing.401unauthorizedThe API key is missing, invalid or revoked.403account_not_approvedThe account is pending review, rejected or suspended.404not_foundNo report with that reference exists in your account.422invalidThe order failed validation. messages lists the problems by field.429rate_limitedToo many orders in the last hour.{
"error": "invalid",
"messages": {
"email": ["Email is invalid"]
}
}
Rate limits
Each account can order up to 100 reports per hour through the API. Reading packages and reports isn't limited under normal use.
GET /packages
The packages your account can order, with your price for each.
curl https://app.escreenly.com/api/v1/packages \
-H "Authorization: Bearer $ESCREENLY_KEY"
{
"data": [
{
"id": 1,
"name": "Standard",
"description": "Identity and criminal searches",
"price_cents": 2900,
"custom": false,
"screenings": ["ssn_trace", "national_criminal", "sex_offender"]
}
]
}
POST /reports
Orders a check and emails the candidate their invitation. The response includes the invitation_url in case you'd rather send it yourself.
report[package_id]RequiredA package id from GET /packages.report[candidate][first_name]RequiredThe candidate's first name.report[candidate][last_name]RequiredThe candidate's last name.report[candidate][email]RequiredWhere the invitation is sent.report[candidate][middle_name]Optionalreport[candidate][phone]Optionalreport[candidate][custom_id]OptionalYour own identifier, such as an ATS candidate id.report[work_location_state]OptionalTwo-letter state code of the job, such as CA. Determines state notices and fair-chance rules.report[fair_chance_certified]Conditionaltrue to certify the fair-chance hiring step. Required for criminal searches in some states; see below.curl https://app.escreenly.com/api/v1/reports \
-H "Authorization: Bearer $ESCREENLY_KEY" \
-H "Content-Type: application/json" \
-d '{
"report": {
"package_id": 1,
"work_location_state": "TX",
"candidate": {
"first_name": "Jordan",
"last_name": "Sample",
"email": "[email protected]",
"custom_id": "ATS-12345"
}
}
}'
Returns 201 Created with the new report, with status invited.
GET /reports
Your 100 most recent reports, newest first. Filter with ?status=invited, pending, complete or canceled.
curl "https://app.escreenly.com/api/v1/reports?status=complete" \
-H "Authorization: Bearer $ESCREENLY_KEY"
GET /reports/:id
One report by its reference, with its screenings and reportable records.
curl https://app.escreenly.com/api/v1/reports/ES-7K4Q-92XM \
-H "Authorization: Bearer $ESCREENLY_KEY"
{
"data": {
"id": "ES-7K4Q-92XM",
"status": "complete",
"result": "consider",
"adjudication": null,
"package": "Standard",
"identity_status": "verified",
"price_cents": 2900,
"work_location_state": "TX",
"candidate": {
"id": 42,
"first_name": "Jordan",
"last_name": "Sample",
"email": "[email protected]",
"custom_id": "ATS-12345"
},
"screenings": [
{
"type": "county_criminal",
"status": "complete",
"result": "consider",
"completed_at": "2026-09-24T15:02:11Z",
"records": [
{
"category": "Criminal",
"description": "Misdemeanor theft",
"severity": "moderate",
"jurisdiction": "Travis County, TX",
"disposition": "Convicted",
"occurred_on": "2019-05-14"
}
]
}
],
"created_at": "2026-09-22T14:10:03Z",
"submitted_at": "2026-09-22T18:41:52Z",
"completed_at": "2026-09-24T15:02:11Z"
}
}
The report object
idThe report's reference, such as ES-7K4Q-92XM.statusinvited (waiting for the candidate), pending (screenings in progress), complete or canceled.resultclear or consider once complete, otherwise null.adjudicationYour team's decision: engaged, not_engaged or null.identity_statusawaiting_review, verified, resubmission_requested, or null before submission.invitation_urlThe candidate's link, while the invitation is open.invitation_expires_atWhen the invitation link expires, while the report is invited.screenings[].typessn_trace, national_criminal, sex_offender, county_criminal, motor_vehicle, employment_verification, education_verification.screenings[].statuspending, in_progress, complete or canceled.screenings[].recordsReportable records only, each with category, description, severity (minor, moderate, major), jurisdiction, disposition and occurred_on. Records excluded by eScreenly never appear.Fair-chance certification
When work_location_state is California or Hawaii (conditional offer), or Illinois, Minnesota or
Washington (otherwise qualified), and the package includes a criminal search, the order must include
"fair_chance_certified": true, certifying that you've completed that hiring step. Without it, the
order is rejected with 422 and a message explaining what to certify. The certification is stored
with the report, word for word.