Bulk Candidate Reports


You can get candidate reports in bulk for a particular test using following API endpoint:

 https://api.hackerearth.com/partner/hackerearth/events/candidates/bulk-reports/

Authentication

The client authentication is done using your unique client_id and client_secret.

You can refer to your Dashboard settings, for client_id and client_secret under API details.

client_id

Type: String

Description: client_id is a 67 character random key that serves as an identification for a particular client and must be provided when communicating with the API as a parameter to the API endpoint.

Example: d8a20ae8e475209er4b1faa72ede88a174423cc2029c.api.hackerearth.com

client_secret

Type: String

Description: client_secret is a 40 character random key that serves as an identification for a particular client and must be provided when communicating with the API as a parameter to the API endpoint.

Example: 2b0ff29f4f8751487540604cdab5611e6135f41c


Making requests

Candidate reports are accessible only for published test.

client_id, client_secret and test_id are the required parameters for making request to this API endpoint. emails, filters, page_number and page_size are optional parameters which are explained below.

All the requests to the API must be made using POST request method.

client_id and client_secret are explained above.

test_id

Type: Integer

Description: test_id is a unique integer for your test. Refer to this article for a better understanding. In this article, Recruiter API ID is the test_id.

Example: 5841

emails (Optional)

Type: List

Description: emails is a list/array which contains candidate emails. If this field is provided, then candidate reports corresponding to only these candidates are returned, else, candidate reports of all the candidates are returned who have taken the test.

Example: ["foo@bar.com", "bob@alice.com", "hacker@hackerearth.com"]

filters (Optional)

Type: Dictionary

Description: This field can accept two type of filters start_datetime and finish_datetime.

start_datetime and finish_datetime are date-range fields that accept two attributes: min and max, that should be in ISO8601 date format. A date-range field should have at-least one of the two attributes.

Combination of above filters is supported.

Example:

{
    "start_datetime":
    {
        "min": "2019-07-31T21:25:02+05:30",
        "max": "2019-08-02T23:25:02+05:30"
    },
    "finish_datetime":
    {
        "min": "2019-07-31T22:25:02+05:30",
        "max": "2019-08-02T23:25:02+05:30"
    }
}

page_number (Optional)

Type: Integer

Description: page_number is a valid page number for paginated reports. If this field is not provided, then by default page_number will be 1

page_size (Optional)

Type: Integer

Description: page_size is a valid page size for paginated reports. If this field is not provided, then by default page_size will be 10. The maximum permitted value for page_size is 20.

Sample request using python

#!/usr/bin/env python

import json
import requests

CLIENT_ID = "d8a20ae8e475209e0eb1faa72ede88a174423cc2029c.api.hackerearth.com"
CLIENT_SECRET = "2b0ff29f4f8751487450604cdab5611e6135f41c"
TEST_ID = 53
EMAILS = ["sample@gmail.com", "alice@bob.com", "example@gmail.com", "dummy@gmail.com"]
FILTERS = {
            "start_datetime":
            {
                "min": "2018-08-01T21:25:02+05:30",
                "max": "2019-08-21T23:25:02+05:30"
            },
            "finish_datetime":
            {
                "min": "2018-08-01T22:25:02+05:30",
                "max": "2019-08-21T23:25:02+05:30"
            }
          }
PAGE_NUMBER = 1
PAGE_SIZE = 5

payload = {
    'client_id': CLIENT_ID,
    'client_secret': CLIENT_SECRET,
    'test_id': TEST_ID,
    'emails': EMAILS,
    'filters': FILTERS,
    'page_number': PAGE_NUMBER,
    'page_size': PAGE_SIZE
}
r = requests.post("https://api.hackerearth.com/partner/hackerearth/events/candidates/bulk-reports/", data=json.dumps(payload))
print r.json()

Using cURL

curl --data '{
"client_id": "d8a20ae8e475209e0eb1faa72ede88a174423cc2029c.api.hackerearth.com",
"client_secret": "2b0ff29f4f8751487450604cdab5611e6135f41c",
"test_id": 53,
"emails": ["sample@gmail.com", "alice@bob.com", "example@gmail.com", "dummy@gmail.com"],
"filters": {
            "start_datetime":
            {
                "min": "2018-08-01T21:25:02+05:30",
                "max": "2019-08-21T23:25:02+05:30"
            },
            "finish_datetime":
            {
                "min": "2018-08-01T22:25:02+05:30",
                "max": "2019-08-21T23:25:02+05:30"
            }
           },
"page_number": 1,
"page_size": 5
}' https://api.hackerearth.com/partner/hackerearth/events/candidates/bulk-reports/


Response

Response returned will be in JSON format.

Sample response

{
    "mcode": "success",
    "message": "success"
    "has_more": false,
    "ecode": [
        "NOTINVITED",
        "NOTPARTICIPATED"
    ],
    "emessage": [
        "Candidate was never invited to this test.",
        "Candidate was invited but he/she did not participate in this test."
    ],
    "candidate_reports": {
        "sample@gmail.com": {
            "phone_number": null,
            "full_report_url": "https://www.hackerearth.com/recruiter/test-draft-7-136/candidates-report/c8001a2587a74c7cb80c552a92b009b9/5f2445dd4b1c7d08ef3c0307dc4ce90b/",
            "anon_report_url": "https://www.hackerearth.com/recruiter/test-draft-7-136/candidates-report/<hash1>/hash<2>/", // This feature is subjected to subscription.
            "candidate_assessment_report_url": "https://www.hackerearth.com/recruiter/test-draft-7-136/candidate-performance-report/c8001a2587a74c7cb80c552a92b009b9/66240bea5fc24e5baff57a6f9c44350f/",
            "full_report_pdf": "https://he-pdf.s3.amazonaws.com/reports/id-test_id-date.pdf",
            "anon_report_pdf_url": "https://he-pdf.s3.amazonaws.com/reports/id-test_id-date-anonymous.pdf",
            "start_datetime": "2019-08-05T10:11:46-05:51",
            "name": "sampleuser65",
            "institute": "IIT Delhi",
            "time_taken": "0:48:24",
            "problem_type_scores": {
                "Programming": 58.0,
                "Multiple Choice Questions": 2.0
            },
            "section_scores": {
                "Programming": {
                    "PSection1": 20.0,
                    "PSection2": 38.0
                },
                "Multiple Choice Questions": {
                    "MSection1": 2.0
                }
            },
            "score": 60.0,
            "status": "active",
            "candidate_id": "dedewd",
            "graduation_year": "2023",
            "finish_datetime": "2019-08-05T10:12:10-05:51",
            "percentage": 43,
            "email": "sample@gmail.com",
            "questions_attempted": 3,
            "skill_scores": {
                "Skill1": "45.0%",
                "Skill2": "100.0%",
                "Skill3": "75.0%"
            },
            "skill_scores_averages": {
                "Skill1": "65.0%",
                "Skill2": "100.0%",
                "Skill3": "66.7%"
            },
            // This field is subjected to subscription.
            "proctoring_information": {
              "snapshots": {
                "total_count": 30,
                "discrepancies_count": 8,
                "view_url": "https://www.hackerearth.com/recruiter/test-draft-7-136/candidates-report/6c6512bdf2bd4cc1b17bb08439643fa8?show=view-snapshots",
                "discrepancy_counts": {
                  "mobile_present": 2,
                  "multiple_persons": 2,
                  "wearing_earphones": 0,
                  "different_person": 0,
                  "no_person": 1,
                  "candidate_looking_away": 3,
                  "face_partially_hidden": 0
                },
                "candidate_reference_snapshot": "https://s3.ap-southeast-1.amazonaws.com/media.hackerearth.com/media/hackathon/test-draft-7-136/images/22199832/a102ab47c8374afa-1727675251-webcam.jpg"
              }
            },
            "cutoff_qualified":"No"
        }
    },
            "cutoff_qualified":"Yes"
        },
        "example@gmail.com": {
            "phone_number": null,
            "full_report_url": "https://www.hackerearth.com/recruiter/test-draft-7-136/candidates-report/c8001a2587a74c7cb80c552a92b009b9/5f2445dd4b1c7d08ef3c0307dc4ce90b/",
            "anon_report_url": "https://www.hackerearth.com/recruiter/test-draft-7-136/candidates-report/<hash1>/hash<2>/", // This feature is subjected to subscription.
            "candidate_assessment_report_url": "https://www.hackerearth.com/recruiter/test-draft-7-136/candidate-performance-report/c8001a2587a74c7cb80c552a92b009b9/66240bea5fc24e5baff57a6f9c44350f/",
            "full_report_pdf": "https://he-pdf.s3.amazonaws.com/reports/id-test_id-date.pdf",
            "anon_report_pdf_url": "https://he-pdf.s3.amazonaws.com/reports/id-test_id-date-anonymous.pdf",
            "start_datetime": "2019-08-05T10:11:46-05:51",
            "name": "exampleuser65",
            "institute": "IIT Delhi",
            "time_taken": "0:23:48",
            "problem_type_scores": {
                "Programming": 51.0,
                "Multiple Choice Questions": 2.0
            },
            "section_scores": {
                "Programming": {
                    "PSection1": 20.0,
                    "PSection2": 31.0
                },
                "Multiple Choice Questions": {
                    "MSection1": 2.0
                }
            },
            "custom_details": {
                "Stream/Branch": "CSE",
                "Degree": "B.Tech/B.E.",
                "Resume": "http://he-s3.s3.amazonaws.com/hackathon/am-ex-challenge/misc/a0a11516cb-kforJobFinal.pdf",
                "CGPA": "6.5",
                "College": "Other College",
                "Graduation Year": "Other"
            },
            "score": 53.0,
            "status": "active",
            "candidate_id": "dedewd",
            "graduation_year": "2023",
            "finish_datetime": "2019-08-05T10:12:10-05:51",
            "percentage": 39,
            "email": "example@gmail.com",
            "questions_attempted": 3
            "skill_scores": {
                "Skill1": "34.2%",
                "Skill2": "90.0%",
                "Skill3": "85.0%"
            },
            "skill_scores_averages": {
                "Skill1": "65.0%",
                "Skill2": "100.0%",
                "Skill3": "66.7%"
            },
            // This field is subjected to subscription.
            "proctoring_information": {
              "snapshots": {
                "total_count": 19,
                "discrepancies_count": 9,
                "view_url": "https://www.hackerearth.com/recruiter/test-draft-7-136/candidates-report/6c6512bdf2bd4cc1b17bb08439643fa8?show=view-snapshots",
                "discrepancy_counts": {
                  "mobile_present": 2,
                  "multiple_persons": 3,
                  "wearing_earphones": 0,
                  "different_person": 0,
                  "no_person": 0,
                  "candidate_looking_away": 4,
                  "face_partially_hidden": 0
                },
                "candidate_reference_snapshot": "https://s3.ap-southeast-1.amazonaws.com/media.hackerearth.com/media/hackathon/test-draft-7-136/images/22199832/a102ab47c8374afa-1727675251-webcam.jpg"
              }
            },
            "cutoff_qualified":"No"
        }
    },
    "candidate_reports_errors": {
        "alice@bob.com": {
            "emessage": "Candidate was never invited to this test.",
            "ecode": "NOTINVITED"
        },
        "dummy@gmail.com": {
            "emessage": "Candidate was invited but he/she did not participate in this test.",
            "ecode": "NOTPARTICIPATED"
        },
    },
}

mcode

Type : String

Description: Message code abbreviated as mcode.

message

Type: String

Description: A message for user regarding the success of request.

message and mcode are related to each other according to the following table:

mcode message
SUCCESS Request successful
FAILED Request failed

ecode

Type: List

Description: Error codes abbreviated as ecode.

emessage

Type: List

Description: A message explaining the error occurred during request processing.

emessage and ecode are related to each other according to the following table:

ecode emessage
AUTHFAILED Authentication Failed
ARGMISSING Request argument missing
BADDATA Invalid request data.
TESTNOTFOUND Test not found
TESTNOTPUBLISHED Test is not published.
INVALIDEMAIL Invalid email(s) exist.
CANDIDATENOTFOUND Candidate not found
NOTINVITED Candidate was never invited to this test.
NOTPARTICIPATED Candidate was invited but he/she did not participate in this test.
NOREPORT No report exist.
LIMITEXCEEDED The limit of the API requests has been reached. Contact support@hackerearth.com.
ACCESSERROR You are not authorized to access this feature. Please contact support@hackerearth.com.
PAGINATIONBADDATA Invalid pagination request data.

candidate_reports

Type: Dictionary (JSON)

Description: This JSON will contain candidate emails mapped to candidate details i.e. name, phone_number, status, start_datetime, finish_datetime, time_taken, institute, full_report_url, candidate_assessment_report_url, score, questions_attempted, graduation_year, questions_attempted, percentage, email, candidate_id, problem_type_scores (map of question type section and candidate's total score in that section), custom_details (map of Custom details fields and their values filled by the candidate), skill_scores, skill_scores_averages and proctoring_information (This field is subjected to subscription).

cutoff_qualified will have value "Yes" if candidate qulifies cutoff if not "No". if cutoff score for event is not set then value will be "NA".

Candidate's personal details like phone_number, institute, graduation_year and candidate_id will be set in response, if these fields were marked in Candidate Settings under Test Settings section and candidate has filled these details, otherwise, the value of these will be null

These candidate report details are sorted in descending order of candidate's test finish time.

status can have ['online', 'active', 'offered', 'archive'] values

Status Description
online Candidate is currently taking the test
active Candidate has finished the test and his result's review is pending
offered Candidate has been shortlisted
archive Candidate has been archived

Note: anon_report_url i.e. Anonymous report url will be provided only if your company has subscribed to the anonymous reports feature.

candidate_reports_errors

Type: Dictionary (JSON)

Description: This JSON will contain candidate emails mapped to error objects (containing ecode and emessage), depicting the errors due to which no report is available for the corresponding emails.

has_more

Type: Boolean value (True/False)

Description: The value of this field indicates that whether next page exists or not. If the value of has_more is false, then the current page is the last page in paginated reports

Errors (Mishandled API responses)

If the client_id or client_secret attribute is incorrect, then the JSON response that is returned is as follows:

{
    "message": "Request failed",
    "ecode": [
         "AUTHFAILED"
    ],
    "emessage": [
        "Authentication Failed"
    ],
    "mcode": "FAILED"
}

If the mandatory POST arguments are not provided, then the JSON response that is returned is as follows:

{
    "message": "Request failed",
    "ecode": [
        "ARGMISSING"
    ],
    "emessage": [
        "Request argument missing: 'test_id'"
    ],
    "mcode": "FAILED"
}

If the provided data is invalid, then the JSON response that is returned is as follows:

{
    "message": "Request failed",
    "ecode": [
         "BADDATA"
    ],
    "emessage": [
        "Invalid request data."
    ],
    "mcode": "FAILED"
}

If the provided pagination data is invalid, then the JSON response that is returned is as follows:

{
    "message": "Request failed",
    "ecode": [
         "PAGINATIONBADDATA"
    ],
    "emessage": [
        "Invalid pagination request data."
    ],
    "mcode": "FAILED"
}

If wrong test_id is provided or the test has already been deleted, then the JSON response that is returned is as follows:

{
    "message": "Request failed",
    "ecode": [
        "TESTNOTFOUND"
    ],
    "emessage": [
        "Test not found"
    ],
    "mcode": "FAILED"
}

If a test is not published, then the JSON response that is returned is as follows:

{
    "message": "Request failed",
    "ecode": [
        "TESTNOTPUBLISHED"
    ],
    "emessage": [
        "Test is not published."
    ],
    "mcode": "FAILED"
}

If a user is not authorized to access the test, then the JSON response that is returned is as follows:

{
    "message": "Request failed",
    "ecode": [
        "ACCESSERROR"
    ],
    "emessage": [
        "You are not authorized to access this feature. Please contact support@hackerearth.com."
    ],
    "mcode": "FAILED"
}

If the limit of API requests (15000 requests) is reached, then the JSON response that is returned is as follows:

{
    "message": "Request failed",
    "ecode": [
        "LIMITEXCEEDED"
    ],
    "emessage": [
        "The limit of the API requests has been reached. Contact support@hackerearth.com."
    ],
    "mcode": "FAILED"
}

If the rate (60 per min or 10000 per day) at which API requests are made by a specific user is reached, then the JSON response that is returned is as follows:

{
    "message": "Request failed",
    "ecode": [
        "RATELIMITEXCEEDED"
    ],
    "emessage": [
        "The rate at which the API requests are made has reached. Please try again after some time."
    ],
    "mcode": "FAILED"
}

If any other issue occurred do reach us out at api@hackerearth.com

Notifications
View All Notifications

?