Getting started with GETMARKED Quiz Import API

GETMARKED Quiz Import API allows developers to quickly accept all kinds of question bank data from their users. At its core, there is only two endpoints that you would ever call. One to upload the quiz file, and one to get the extracted quiz question data. You can get familiar with it using our API Playground first before proceeding with the rest of this guide.

Here's a quickstart python code file that contains all the instruction below on how to use our API.
To get started, install your favourite http library in any programming language that you like. Alternatively, you may also follow through the steps using http request tools like Postman.

In our code examples we will be using Python 3 and Requests (a python HTTP library). The examples below are easily readable even if you don't use Python. If you do not have Requests installed yet, you can install it using pip:

pip install requests

Creating API Keys
All requests to GETMARKED's REST API need to be authenticated. We support authentication via API Keys. You can create and revoke them in the Developer Dashboard. Please keep the keys secret. For security reasons, we cannot show it to you again if you lose it.
Setting the API Key in the request header
To authorise your HTTP request, set the API Key in the AUTHORIZATION header of the HTTP request.

  1. Using Postman
  2. Under Headers, you should fill in the following information:
  3. Using Python
    import requests
    headers = {"AUTHORIZATION": "Api-Key YOUR-SECRET-API-KEY"}
    response = requests.get(API_URL, headers=headers)
Converting your quiz file into JSON data
We accept the following quiz file formats:
  1. DOCX
  2. Question banks exported from Canvas, Schoology, Brightspace, itslearning, Cognero, NEO LMS, Ilias LMS
  3. IMSCC file (Common Cartridge)
  4. Blackboard pool and test zip file
  5. QTI 2.2, 2.1, 1.2 zip file
  6. QTI 1.2 xml file
  7. Moodle XML
  8. WebCT zip file
  9. Examview export Blackboard Pools zip file
  10. GIFT and AIKEN TXT file
  11. JSON Google Form
Converting a quiz file into our JSON data format is an async process and will take at least two request/response cycle. This is because the conversion is a long running process that will take anywhere between 10s to 240s depending on the size of the file. As an estimate, conversion will usually take 500ms per page for docx file with a maximum of 5 mins per file.

In this getting started guide, we will be converting from a docx quiz file. Conversion from a QTI zip file or JSON Google form will work in exactly the same way.

Also, here's some sample docx quizzes you can use for testing:

  1. POST your file using multipart/form-data to
    NOTE: DO NOT USE Transfer-Encoding: chunked in your HTTP POST. Transfer-Encoding should be removed from your HTTP headers.
    import requests
    with open(filepath, 'rb') as file:
        API_URL = ""
        files = {"file": file}
        headers = {"AUTHORIZATION": "Api-Key YOUR-SECRET-API-KEY"}
        response =, files=files, headers=headers)
    You will receive a JSON response structured like so, if successful:
    { "status": "accepted", "message": "your file has been aceepted", "data": {"result_endpoint": "{id}/"} }
    If you are facing issues sending your file data to our API via HTTP POST, you can direct your HTTP POST request to to help you debug your POST request. will return with a JSON response of your POST data and it should look like the following:
      "args": {},
      "data": "",
      "files": {
        "file": "data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,U...."
      "form": {},
      "headers": {
        "Accept-Encoding": "gzip, deflate",
        "Authorization": "Api-Key YOUR_SECRET_KEY",
        "Cache-Control": "no-cache",
        "Content-Length": "195603",
        "Content-Type": "multipart/form-data; boundary=\"c46ede9c-af3d-4baf-a9e9-c8a627ebfdae\"",
        "Host": "",
        "X-Amzn-Trace-Id": "Root=1-61d90a6d-2233f13f505cf8c95c69e44c"
      "json": null,
      "origin": "XXX.XX.XXX.XX",
      "url": ""

    Please note that the Content-Length must be specified. Also, we do not accept Transfer-Encoding of chunked. Transfer-Encoding should be stripped from your HTTP header.

    Alternatively, you may provide the URL of your question bank file instead of attaching the entire file in the POST request.

    import requests
    API_URL = ""
    data = {"url": "https://CDN.YOUR-DOMAIN.COM/YOUR-QUESTION-BANK.docx"}
    headers = {"AUTHORIZATION": "Api-Key YOUR-SECRET-API-KEY"}
    response =, data=data, headers=headers)
  2. Method one: GET the JSON data via polling
    Poll the returned result_endpoint for the extracted questions data at 15s intervals.
    import requests
    API_URL = "{id}/"
    headers = {"AUTHORIZATION": "Api-Key YOUR-SECRET-API-KEY"}
    response = requests.get(API_URL, headers=headers)
    And you would receive the questions data. Please refer to question schema on how to render the data.
  3. Method two (recommended): webhook integration to receive the question bank data.
    Instead of polling like in the above step, you may provide a webhook URL at the point of importing the job. For testing purposes, you can generate a temporary webhook here.
    import requests
    API_URL = ""
    data = {"url": "https://CDN.YOUR-DOMAIN.COM/YOUR-QUESTION-BANK.docx",
            "webhook": ""}
    headers = {"AUTHORIZATION": "Api-Key YOUR-SECRET-API-KEY"}
    response =, data=data, headers=headers)
    Once the import job is completed, our server will make a HTTP POST request to the webhook URL provided. In the request body, it will contain the same identical JSON data that you will get from result_endpoint in the above step. You must respond with a 2XX status code or our servers will keep retrying.
And that's it! In 2 simple HTTP request (or 1 if you opt to use webhook), you have converted your quiz docx file into questions JSON data. You can try it now using our API Playground.
Structure of HTTP Responses
Response body from our API endpoints should be read in JSON format, and all have the following structure:

    "status": "some status",
    "message": "some message",
    "data": response data,

  1. Status is a string and refers to whether the request was successfully received by the create_job API (accepted, error), or the status of conversion job in the result_endpoint (converting, success, failure).
  2. Message is a short description of the status.
  3. Data contains either the URL of the result_endpoint or the questions data.
Status Codes
Responses from our API endpoints come with status codes. Here is a quick cheat sheet to help you understand what is going on at our side when you send in your request.
Status Code Meaning Description
The request has succeeded, and you should look into the data field to obtain the relevant information.
Accepted. The request has succeed, but we need time to act on it.
Bad Request
Your request may have been formed badly (for eg. incorrect file type), or your previous created job failed due to a variety of reasons.
You are not authenticated for that resource. You have not have provided an authenticable API Key, or you might be requesting for a resource that does not belong to you.
Not Found
The resource which you have requested for cannot be found.
Server Error
There was a problem on GETMARKED's server.
Payment Plans
Signing up for a developer account gives you free credits that you can use on the production endpoint. If the free credits is insufficient, please contact us and we can offer even more generous amount of credits to help you get going.

Once exhausted, we recommend that you purchase a paid subscription plan.
Need some help?
Whether you have problems with the web application or with code interfacing with our endpoints, please do not hesitate to reach out and contact us.