NAV Navbar
cURL http
  • Devskiller API Overview
  • Candidate operations
  • Exam operations
  • Webhooks
  • Errors
  • Devskiller API Overview

    The Devskiller REST API lets you interact with Devskiller platform. You can use the API especially for:

    API Endpoint

    All API URLs are relative to https://api.devskiller.com/. For example, to get list of candidates you should call /candidates endpoint at https://api.devskiller.com/candidates

    API Key

    Each request must contain an API Key passed as HTTP header: X-Api-Key. To get your personal API key, please navigate to the Settings -> Integrations menu in the Devskiller administration panel, and acquire your key in the API Access section.

    More details about acquiring the API Key can be found in our help https://help.devskiller.com/devskiller-settings/integrations/how-to-integrate-with-an-api

    Candidate operations

    The Candidates resources is used to create and list candidates

    Listing candidates

    Request

    GET /candidates?query=John&count=10&page=1&status=TOKEN_SENT&tags=Tag1&tags=Tag2 HTTP/1.1
    X-Api-Key: TEST-API-KEY
    Accept: application/json
    Host: api.devskiller.com
    
    
    $ curl 'https://api.devskiller.com/candidates?query=John&count=10&page=1&status=TOKEN_SENT&tags=Tag1&tags=Tag2' -i \
        -H 'X-Api-Key: TEST-API-KEY' \
        -H 'Accept: application/json'
    

    Response

    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    Content-Length: 458
    
    {
      "items" : [ {
        "id" : "CANDIDATE-UUID-1234",
        "firstName" : "John",
        "lastName" : "Smith",
        "email" : "test@email.com",
        "examId" : "UUID-FOR-123",
        "status" : "TOKEN_SENT",
        "scoredPoints" : null,
        "maxPoints" : 65,
        "examUrl" : "http://exam.url/exam.html?TEST-TOKEN",
        "tags" : [ "Tag1", "Tag2" ],
        "externalId" : "EXTERNAL-1234"
      } ],
      "totalElements" : 1,
      "totalPages" : 1,
      "pageSize" : 10,
      "pageNumber" : 1
    }
    
    {
      "items" : [ {
        "id" : "CANDIDATE-UUID-1234",
        "firstName" : "John",
        "lastName" : "Smith",
        "email" : "test@email.com",
        "examId" : "UUID-FOR-123",
        "status" : "TOKEN_SENT",
        "scoredPoints" : null,
        "maxPoints" : 65,
        "examUrl" : "http://exam.url/exam.html?TEST-TOKEN",
        "tags" : [ "Tag1", "Tag2" ],
        "externalId" : "EXTERNAL-1234"
      } ],
      "totalElements" : 1,
      "totalPages" : 1,
      "pageSize" : 10,
      "pageNumber" : 1
    }
    

    GET /candidates

    A GET request will list all candidates.

    Request parameters:

    Parameter Description Constraints
    query Search by name,email or token Optional
    status Filter candidates by status. Add multiple status parameters to search for several statuses. Optional
    tags Filter candidates by tags. Add multiple tags parameters to search for several tags. Optional
    count Maximum number of candidates to get. Default: 10, Max: 100 Optional
    page Number of the page to fetch, starting with 1. Default: 1 Optional

    Response structure:

    Path Type Description
    pageNumber Number Number of the current page
    pageSize Number Maximum number of elements for a page
    totalElements Number Total number of candidates matching criteria
    totalPages Number Total number of pages matching criteria
    items Array An array with candidates
    items[].id String The candidate’s id
    items[].externalId String The candidate’s external id
    items[].firstName String The candidate’s first name
    items[].lastName String The candidate’s last name
    items[].email String The candidate’s email address
    items[].examId String The exam’s id that the candidate has been asked to solve
    items[].status String The candidate’s status. Possible values: TOKEN_SENT, TOKEN_EXPIRED, TEST_STARTED, TEST_FINISHED, AUTO_ASSESSMENT_READY, IN_ASSESSMENT, ASSESSMENT_READY, ACCEPTED, REJECTED
    items[].scoredPoints Null The candidate’s score. Null if candidate has not been assessed yet
    items[].maxPoints Number The maximum number of points, that candidate might get from assigned exam
    items[].examUrl String The url to the test for candidate
    items[].tags Array The candidate’s tags (array of strings)

    Creating a candidate

    Request

    POST /candidates HTTP/1.1
    Content-Type: application/json
    X-Api-Key: TEST-API-KEY
    Accept: application/json
    Host: api.devskiller.com
    Content-Length: 236
    
    {
        "communicationDisabled": false,
        "firstName": "John",
        "lastName": "Smith",
        "examId": "UUID-FOR-123",
        "tags": [
            "Tag1",
            "Tag2"
        ],
        "email": "test@email.com",
        "externalId": "EXTERNAL-1234"
    }
    
    $ curl 'https://api.devskiller.com/candidates' -i -X POST \
        -H 'Content-Type: application/json' \
        -H 'X-Api-Key: TEST-API-KEY' \
        -H 'Accept: application/json' \
        -d '{
        "communicationDisabled": false,
        "firstName": "John",
        "lastName": "Smith",
        "examId": "UUID-FOR-123",
        "tags": [
            "Tag1",
            "Tag2"
        ],
        "email": "test@email.com",
        "externalId": "EXTERNAL-1234"
    }'
    

    Response

    HTTP/1.1 201 Created
    Location: https://api.devskiller.com/candidates/CANDIDATE-UUID-1234
    Content-Type: application/json;charset=UTF-8
    Content-Length: 332
    
    {
      "id" : "CANDIDATE-UUID-1234",
      "firstName" : "John",
      "lastName" : "Smith",
      "email" : "test@email.com",
      "examId" : "UUID-FOR-123",
      "status" : "TOKEN_SENT",
      "scoredPoints" : null,
      "maxPoints" : 65,
      "examUrl" : "http://exam.url/exam.html?TEST-TOKEN",
      "tags" : [ "Tag1", "Tag2" ],
      "externalId" : "EXTERNAL-1234"
    }
    
    {
      "id" : "CANDIDATE-UUID-1234",
      "firstName" : "John",
      "lastName" : "Smith",
      "email" : "test@email.com",
      "examId" : "UUID-FOR-123",
      "status" : "TOKEN_SENT",
      "scoredPoints" : null,
      "maxPoints" : 65,
      "examUrl" : "http://exam.url/exam.html?TEST-TOKEN",
      "tags" : [ "Tag1", "Tag2" ],
      "externalId" : "EXTERNAL-1234"
    }
    

    POST /candidates

    A POST request is used to create a candidate. After successfully creating a candidate, an email with the invitation will be send to the candidate.

    Request fields:

    Path Type Description Constraints
    email String The candidate's email address Required
    firstName String The candidate's first name Required
    lastName String The candidate's last name Required
    examId String The exam's id that the candidate has been asked to solve Required
    tags Array The candidate's tags (array of strings) Optional
    communicationDisabled Boolean Should the outbound communication to the candidate be disabled. Default: "false" Optional
    externalId String Unique identifier of the candidate used in your system Optional

    Possible response codes

    Status code Usage
    200 OK The request completed successfully
    400 Bad Request The request was malformed. The response body will include an error providing further information
    412 Precondition failed Requested exam cannot be used (it doesn't exist or is in wrong state)
    417 Expectation failed There are insufficient credits to complete the request

    Details of a candidate

    Request

    GET /candidates/CANDIDATE-UUID-1234 HTTP/1.1
    X-Api-Key: TEST-API-KEY
    Accept: application/json
    Host: api.devskiller.com
    
    
    $ curl 'https://api.devskiller.com/candidates/CANDIDATE-UUID-1234' -i \
        -H 'X-Api-Key: TEST-API-KEY' \
        -H 'Accept: application/json'
    

    Response

    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    Content-Length: 332
    
    {
      "id" : "CANDIDATE-UUID-1234",
      "firstName" : "John",
      "lastName" : "Smith",
      "email" : "test@email.com",
      "examId" : "UUID-FOR-123",
      "status" : "TOKEN_SENT",
      "scoredPoints" : null,
      "maxPoints" : 65,
      "examUrl" : "http://exam.url/exam.html?TEST-TOKEN",
      "tags" : [ "Tag1", "Tag2" ],
      "externalId" : "EXTERNAL-1234"
    }
    
    {
      "id" : "CANDIDATE-UUID-1234",
      "firstName" : "John",
      "lastName" : "Smith",
      "email" : "test@email.com",
      "examId" : "UUID-FOR-123",
      "status" : "TOKEN_SENT",
      "scoredPoints" : null,
      "maxPoints" : 65,
      "examUrl" : "http://exam.url/exam.html?TEST-TOKEN",
      "tags" : [ "Tag1", "Tag2" ],
      "externalId" : "EXTERNAL-1234"
    }
    

    GET /candidates/{id}

    A GET request will retrieve the details of a candidate

    Response structure

    Path Type Description
    id String The candidate's id
    externalId String The candidate's external id
    status String The candidate's status. Possible values: TOKEN_SENT, TOKEN_EXPIRED, TEST_STARTED, TEST_FINISHED, AUTO_ASSESSMENT_READY, IN_ASSESSMENT, ASSESSMENT_READY, ACCEPTED, REJECTED, ERROR
    email String The candidate's email address
    firstName String The candidate's first name
    lastName String The candidate's last name
    scoredPoints Null The candidate's score. Null if candidate has not been assessed yet
    maxPoints Number The maximum number of points, that candidate might get from assigned exam
    examUrl String The url to the test for candidate
    examId String The exam's id that the candidate has been asked to solve
    tags Array The candidate's tags (array of strings)

    Results for a candidate

    Request

    GET /candidates/CANDIDATE-UUID-5678/results HTTP/1.1
    X-Api-Key: TEST-API-KEY
    Accept: application/json
    Host: api.devskiller.com
    
    
    $ curl 'https://api.devskiller.com/candidates/CANDIDATE-UUID-5678/results' -i \
        -H 'X-Api-Key: TEST-API-KEY' \
        -H 'Accept: application/json'
    

    Response

    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    Content-Length: 564
    
    {
      "reportUrl" : "https://report.devskiller.com/candidate-report.html?REPORT-UUID/REPORT-UUID2",
      "pdfReportUrl" : null,
      "scoredPoints" : 45,
      "maxPoints" : 65,
      "skills" : [ {
        "name" : "Skill1",
        "scoredPoints" : 50,
        "maxPoints" : 100
      }, {
        "name" : "Skill2",
        "scoredPoints" : 36,
        "maxPoints" : 100
      } ],
      "note" : "Some note about candidate",
      "askedForContractData" : true,
      "financialExpectations" : 5000,
      "noticePeriod" : "one month",
      "replySent" : false,
      "examDurationInMinutes" : 44,
      "examTimeLimitInMinutes" : 60
    }
    
    {
      "reportUrl" : "https://report.devskiller.com/candidate-report.html?REPORT-UUID/REPORT-UUID2",
      "pdfReportUrl" : null,
      "scoredPoints" : 45,
      "maxPoints" : 65,
      "skills" : [ {
        "name" : "Skill1",
        "scoredPoints" : 50,
        "maxPoints" : 100
      }, {
        "name" : "Skill2",
        "scoredPoints" : 36,
        "maxPoints" : 100
      } ],
      "note" : "Some note about candidate",
      "askedForContractData" : true,
      "financialExpectations" : 5000,
      "noticePeriod" : "one month",
      "replySent" : false,
      "examDurationInMinutes" : 44,
      "examTimeLimitInMinutes" : 60
    }
    

    GET /candidates/{id}/results

    A GET request will retrieve the results for a candidate

    Response structure

    Path Type Description
    maxPoints Number Maximum points that candidate could get for the test
    scoredPoints Number The candidate's score
    examDurationInMinutes Number How long did it take to complete the test
    examTimeLimitInMinutes Number Exam's time limit
    askedForContractData Boolean True if candidate has been asked for contract data
    financialExpectations Number Financial expectations, available if candidate has been asked for contract data.
    noticePeriod String Notice period, available if candidate has been asked for contract data
    note String Optional note about candidate, made by assessor
    replySent Boolean True if a feedback mail has been sent to the candidate
    reportUrl String The candidate's report URL.
    pdfReportUrl Null The candidate's report URL (PDF download).
    skills Array The candidate's skills results.
    skills[].name String The skill's name.
    skills[].scoredPoints Number The skil's scored points.
    skills[].maxPoints Number The skill's max points.

    Exam operations

    The Exams resources is used to list exams

    List exams

    Request

    GET /exams?count=10&page=1 HTTP/1.1
    X-Api-Key: TEST-API-KEY
    Accept: application/json
    Host: api.devskiller.com
    
    
    $ curl 'https://api.devskiller.com/exams?count=10&page=1' -i \
        -H 'X-Api-Key: TEST-API-KEY' \
        -H 'Accept: application/json'
    

    Response

    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    Content-Length: 558
    
    {
      "items" : [ {
        "id" : "UUID-FOR-123",
        "name" : "Test exam 123",
        "durationInMinutes" : 100,
        "automaticAssessmentPossible" : true,
        "numberOfPages" : 2,
        "numberOfTasks" : 4,
        "skillTags" : [ "Java", "Hibernate" ]
      }, {
        "id" : "UUID-FOR-456",
        "name" : "Test exam 456",
        "durationInMinutes" : 100,
        "automaticAssessmentPossible" : true,
        "numberOfPages" : 2,
        "numberOfTasks" : 4,
        "skillTags" : [ "Java", "Hibernate" ]
      } ],
      "totalElements" : 2,
      "totalPages" : 1,
      "pageSize" : 10,
      "pageNumber" : 1
    }
    
    {
      "items" : [ {
        "id" : "UUID-FOR-123",
        "name" : "Test exam 123",
        "durationInMinutes" : 100,
        "automaticAssessmentPossible" : true,
        "numberOfPages" : 2,
        "numberOfTasks" : 4,
        "skillTags" : [ "Java", "Hibernate" ]
      }, {
        "id" : "UUID-FOR-456",
        "name" : "Test exam 456",
        "durationInMinutes" : 100,
        "automaticAssessmentPossible" : true,
        "numberOfPages" : 2,
        "numberOfTasks" : 4,
        "skillTags" : [ "Java", "Hibernate" ]
      } ],
      "totalElements" : 2,
      "totalPages" : 1,
      "pageSize" : 10,
      "pageNumber" : 1
    }
    

    GET /exams

    A GET request will list all candidates.

    Request parameters:

    Parameter Description Constraints
    count Maximum number of exams to get. Default: 10, Max: 100 Optional
    page Number of the page to fetch, starting with 1. Default: 1 Optional

    Response structure

    Path Type Description
    pageNumber Number Number of the current page
    pageSize Number Maximum number of elements for a page
    totalElements Number Total number of exams matching criteria
    totalPages Number Total number of pages matching criteria
    items Array An array of exams
    items[].id String The exam’s id that the candidate has been asked to solve
    items[].name String The exam’s name
    items[].durationInMinutes Number How long did it take to complete the test
    items[].automaticAssessmentPossible Boolean Is automatic assessment of candidate’s answers is possible? If false, some of candidate’s answers needs manual assessment
    items[].numberOfPages Number The exam’s number of pages
    items[].numberOfTasks Number The exam’s number of tasks
    items[].skillTags Array Array of skills tested with this exam

    Details of an exam

    Request

    GET /exams/UUID-FOR-123 HTTP/1.1
    X-Api-Key: TEST-API-KEY
    Accept: application/json
    Host: api.devskiller.com
    
    
    $ curl 'https://api.devskiller.com/exams/UUID-FOR-123' -i \
        -H 'X-Api-Key: TEST-API-KEY' \
        -H 'Accept: application/json'
    

    Response

    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    Content-Length: 211
    
    {
      "id" : "UUID-FOR-123",
      "name" : "Test exam 123",
      "durationInMinutes" : 100,
      "automaticAssessmentPossible" : true,
      "numberOfPages" : 2,
      "numberOfTasks" : 4,
      "skillTags" : [ "Java", "Hibernate" ]
    }
    
    {
      "id" : "UUID-FOR-123",
      "name" : "Test exam 123",
      "durationInMinutes" : 100,
      "automaticAssessmentPossible" : true,
      "numberOfPages" : 2,
      "numberOfTasks" : 4,
      "skillTags" : [ "Java", "Hibernate" ]
    }
    

    GET /exams/{id}

    A GET request will retrieve the details of an exam

    Response structure

    Path Type Description
    id String The exam's id
    name String The exam's name
    durationInMinutes Number The exam's duration in minutes
    numberOfPages Number The exam's number of pages
    numberOfTasks Number The exam's number of tasks
    skillTags Array Array of skills tested with this exam
    automaticAssessmentPossible Boolean Is automatic assessment of candidate's answers is possible? If false, some of candidate's answers needs manual assessment

    Webhooks

    Webhooks are inverted API endpoints which allows you to receive push notifications from Devskiller.

    To receive Devskiller's push notifications you have to register your webhook endpoint address in the administration panel. You will also find here the webhook secret which is used to secure all requests sent by Devskiller. The secret is always passed in the "X-Hook-Secret" header.

    Receive push notification

    Request

    POST /devskillerWebhooks HTTP/1.1
    Content-Type: application/json
    X-Hook-Secret: TEST-SECRET
    Host: api.yourdomain.com
    Content-Length: 299
    
    [
        {
            "candidateId": "CANDIDATE-UUID-1234",
            "candidateExternalId": "EXTERNAL-1234",
            "candidateEmail": "test@email.com",
            "examId": "UUID-FOR-123",
            "examName": "Test exam 123",
            "status": "ASSESSMENT_COMPLETED",
            "event": "EXAM_FINISHED"
        }
    ]
    
    $ curl 'https://api.yourdomain.com/devskillerWebhooks' -i -X POST \
        -H 'Content-Type: application/json' \
        -H 'X-Hook-Secret: TEST-SECRET' \
        -d '[
        {
            "candidateId": "CANDIDATE-UUID-1234",
            "candidateExternalId": "EXTERNAL-1234",
            "candidateEmail": "test@email.com",
            "examId": "UUID-FOR-123",
            "examName": "Test exam 123",
            "status": "ASSESSMENT_COMPLETED",
            "event": "EXAM_FINISHED"
        }
    ]'
    

    POST https://your_endpoint_address_here

    A POST request will push events to your endpoint.

    If your endpoint responded 4xx or 5xx Devskiller will retry the request with a given schedule:

    Request headers

    Name Description
    X-Hook-Secret The webhook secret key

    Request structure

    Path Type Description Constraints
    [] Array An array of events Always
    [].candidateId String The candidate's id Always
    [].candidateExternalId String The candidate's external id If used
    [].candidateEmail String The candidate's email Always
    [].examId String The id of the exam Always
    [].examName String The name of the exam Always
    [].event String Event type. Possible values: EXAM_FINISHED Always
    [].status String Event type status. Possible values: WAITING_FOR_ASSESSMENT, ASSESSMENT_COMPLETED Always

    Errors

    Response

    HTTP/1.1 400 Bad Request
    Content-Type: application/json;charset=UTF-8
    Content-Length: 126
    
    {
      "code" : 400,
      "errorId" : "232ea67b-5acb-474c-84bb-d1ebfc812b1a",
      "details" : "Errors: email: incorrect mail, Email"
    }
    
    {
      "code" : 400,
      "errorId" : "232ea67b-5acb-474c-84bb-d1ebfc812b1a",
      "details" : "Errors: email: incorrect mail, Email"
    }
    

    Whenever an error response (status code >= 400) is returned, the body will contain a JSON object that describes the problem. The error object has the following structure:

    Path Type Description
    code Number Error code
    errorId String Unique error id, you can use it when contacting with us
    details String Error description

    For example, a request that attempts to apply a non-existent tag to a note will produce a 400 Bad Request response