ClassMarker API
You can use the ClassMarker API to quickly integrate exams. You can perform operations such as:
- Retrieving exam results
- Controlling access to exams
- Adding and editing questions and question categories
The ClassMarker API is built to allow developers to download and store results in their own databases. See our code examples in GitHub, including PHP code and database table schemas to help get you started, or, our simple PHP API Client to integrate into your Code base. Use these examples as a guide for coding in other languages.
When retrieving exam results from ClassMarker's API, results are returned from their respective groups or links, depending on how they were taken. To retrieve results for a particular exam, your API key must have access to the group or link the exam is in. You can learn more about creating API keys in the Get started section.
Each link can only contain one exam and has a unique link (quiz_id
parameter) to access the exam.
ClassMarker concepts
Before you get started, you need to understand the following important concepts.
Groups and links
ClassMarker administrators can use two different methods to share exams.
Method | Used for? | How? |
---|---|---|
Groups | Groups of users, such as school classrooms or workplace departments | Administrators create user groups in ClassMarker and assign exams to them |
Links | Unregistered users or web page integration | Administrators create links (URLs) in ClassMarker and send them to users |
Learn more about giving access to exams using groups and links.
Access lists
You can use access lists to control access to exams for unregistered users.
Learn more about access lists in our User manual
and Integration page.
Categories
ClassMarker questions and exams can be organized into categories, consisting of parent and sub-categories.
Question bank
Question banks are a container for all the questions you define for use throughout your exams.
Learn more about question banks.
API rate limits
{
"status":"error",
"request_path":"v1",
"server_timestamp":1339857211,
"finished_after_timestamp_used":1338908448,
"error":{
"error_code":"rateLimitExceeded",
"error_message":"You have reached the rate limit of 30 requests per hour. You can next make a request after the UNIX epoch timestamp value set in: next_request_after",
"next_request_after":1339859100
}
}
Each API key can make up to 30 requests per hour. As exams are generally not taken around the clock, we recommend running a cron
job to request recent results once an hour (on a random minute of your choice).
If you receive a rate limit error, the next_request_after
value shown in the example gives you a timestamp for when you are next allowed to make a request. The next_request_after
timestamp will be within one hour.
Exam tracking data
When testing ClassMarker links, you can pass tracking data on users taking exams such as their name, email and user_id
from your system.
This data is saved in ClassMarker and returned with respective results via the API. You can use this data for referencing exam results back in your system.
You can read more about this in ClassMarker exam integration.
Get started
Authentication
To use ClassMarker API, you need an API key and secret. You can generate, view and manage your API keys in your ClassMarker account.
- Each API key has permissions set on which groups it is allowed to request quiz results from.
- Your API secret must be kept private and secure. ClassMarker holds a copy of your API secret to authenticate your requests.
- ClassMarker accounts can have multiple API key and API secret combinations created for separate groups/exam access.
Each request needs to include your API key, a lowercase MD5 signature and a timestamp.
The sections below explain how to create these three elements.
Generate an API key
- Log in to your ClassMarker account.
- Navigate to My Account > Webhooks / API Keys.
- In the API Keys tab, click New API Key +.
- Enter the values for the API key:
- Specify a name
- Set the key to active and specify a date range of validity if required
- Set other optional values as needed:
- Unique link IDs if you need to provide unique IDs to developers via API requests to link from external systems
- Unique results URLs to provide to users who are not logged in
- Choose between assigning permissions to all groups and links or select specific groups and links the key can access
When you save your settings, ClassMarker generates your new API key and accompanying secret.
Generate an MD5 signature hash
$your_api_key = 'd4tsE7SvEgzAKlJPFrlvAz3oe9uFQnxy';
$your_api_secret = 'keepThisSecret';
$current_unix_timestamp = time();
$signature = md5($your_api_key . $your_api_secret . $current_unix_timestamp);
You need to generate an MD5 hash to include as your signature in your requests. The PHP code example shows how to achieve this.
- The MD5 signature hash must be in lower case.
- The periods (.) in the
$signature
MD5 example are PHP concatenation operators.
Timestamp
- Use seconds since the UNIX Epoch, not milliseconds.
- There is a 5-minute window of time variance allowed from the sent timestamp.
- Make sure your server calling our service is in sync with an atomic clock.
Try it out
Send your first request:
curl --location --request GET "https://api.classmarker.com/v1.json?api_key=$your_api_key&signature=$your_signature×tamp=$current_unix_timestamp_in_secs"
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->getAllGroupLinkTest();
echo $json_response;
You're now ready to send your first request. The example shown returns all available groups, links and exams.
Your response should look like this:
{
"status": "ok",
"request_path": "v1",
"server_timestamp": 1339769771,
"groups": [
{
"group": {
"group_name": "Internal Accounts department",
"group_id": 29765,
"assigned_tests": [
{
"test": {
"test_name": "Health and safety exam",
"test_id": 64776
}
},
{
...
}
]
}
},
{
...
}
],
"links": [
{
"link": {
"link_name": "New York Sales Staff",
"link_id": 2343765,
"link_url_id": "g6v533a63444719ce32",
"access_list_id": 123456,
"assigned_tests": [
{
"test": {
"test_name": "Product specials & discounts quiz",
"test_id": 48756
}
}
]
}
},
{
...
}
]
}
PHP client library
Download our PHP client library to try out some more examples. GitHub ClassMarker API Client.
API reference
Feeling a bit lost? Have a quick look over the ClassMarker concepts.
You can obtain responses in either JSON or XML format. This reference includes JSON examples only. To use the API in XML format, substitute .json
in the examples with .xml
.
Groups, links and exams
GET all available groups, links and exams
HTTP request
GET https://api.classmarker.com/v1.json
Example request
curl --location --request GET "https://api.classmarker.com/v1.json?api_key=d4tsE7SvEgzAKlJPFrlvAz3oe9uFQnxy
&signature=4495a14efc483aa5ee2f6d4cd480f968×tamp=1335783600"
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->getAllGroupLinkTest();
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1",
"server_timestamp": 1339769771,
"groups": [
{
"group": {
"group_name": "Internal Accounts department",
"group_id": 29765,
"assigned_tests": [
{
"test": {
"test_name": "Health and safety exam",
"test_id": 64776
}
},
{
"test": {
"test_name": "March Quarter Skills assessment",
"test_id": 273864
}
},
{
"test": {
"test_name": "Billing system exam",
"test_id": 38676
}
},
{
"test": {
"test_name": "Customer complaints responses quiz",
"test_id": 95645
}
}
]
}
},
{
"group": {
"group_name": "Internal Sales Staff",
"group_id": 73645,
"assigned_tests": [
{
"test": {
"test_name": "Health and safety",
"test_id": 64776
}
},
{
"test": {
"test_name": "Product specials & discounts quiz",
"test_id": 48756
}
},
{
"test": {
"test_name": "March Quarter Skills assessment",
"test_id": 273864
}
},
{
"test": {
"test_name": "Billing system exam",
"test_id": 38676
}
}
]
}
}
],
"links": [
{
"link": {
"link_name": "New York Sales Staff",
"link_id": 2343765,
"link_url_id": "g6v533a63444719ce32",
"access_list_id": 123456,
"assigned_tests": [
{
"test": {
"test_name": "Product specials & discounts quiz",
"test_id": 48756
}
}
]
}
},
{
"link": {
"link_name": "Sydney Sales Staff",
"link_id": 985674,
"link_url_id": "4mb5243e51cf0b0cswe",
"assigned_tests": [
{
"test": {
"test_name": "Product specials & discounts quiz Sydney Version",
"test_id": 48758
}
}
]
}
}
]
}
Retrieves details of all groups, links and exams your API key has permissions to access.
For example, if your API key has access to all groups and links, you can use this endpoint to check when extra groups and links have been added.
You can also use this endpoint to retrieve IDs for use in other endpoints, such as:
- a test ID, group ID and link ID to use for querying recent results for a specific group and exam or link and exam
- an access list ID to use for deleting access lists
- a quiz ID for a link to use for giving access to new links
Parameter | Type | Mandatory | Description |
---|---|---|---|
api_key |
string | Y | Your API key |
signature |
string | Y | Your MD5 signature |
timestamp |
timestamp | Y | Current UNIX timestamp in seconds |
Response object
Field | Description |
---|---|
status |
The three status responses you can receive are: ok Request was successful and results have been found and returned to you. no_results Request was successful, however, no results have been found. error An error has occurred in your request. Refer to error codes for possible values. |
request_path |
The request path you requested - useful for debugging. |
server_timestamp |
ClassMarker's server timestamp - useful for keeping in sync with our 5 minute timestamp allowance. |
access_list_id |
Unique identifier of the access list. Only included if an access list is currently assigned to the link. |
link_url_id |
This is the unique URL identifier that is required to start a new exam (when taken via links). Only included if it is enabled in the permissions during API key generation. For example: https://...?quiz=sample_quiz_id_123 |
Recent results
Recent results and timestamps
You can use the parameter finishedAfterTimestamp
to avoid retrieving results more than once.
You can think of this parameter as an offset. Each time you make a request, you need to ensure your finishedAfterTimestamp
is set to the value of the next_finished_after_timestamp
you received from ClassMarker in your last successful request response (a response which returns existing results) so you only retrieve results that were completed after the last result you received from the ClassMarker API.
What if my response doesn't include any results?
If no results are returned in a response, the next_finished_after_timestamp
parameter is not returned either, so on your next request, you need to use the last next_finished_after_timestamp
you received.
To avoid downloading the same results in multiple requests, you can either:
keep a reference to the last
next_finished_after_timestamp
value returned to you by the API to use as thefinishedAfterTimestamp
value in your next request to ClassMarker (such as storing it in a database), orscan your own table of saved results from ClassMarker and use the most recently finished exam result's
time_finished
timestamp as your next request'sfinishedAfterTimestamp
value
Rules for finishedAfterTimestamp
- Default
finishedAfterTimestamp
used: 2 weeks ago - Oldest
finishedAfterTimestamp
allowed: 3 months ago
For example:
- If
finishedAfterTimestamp
is set in your request and is more recent than 3 months, it will be used as is. (Recommended Usage)
- If
finishedAfterTimestamp
is not set in your request, it defaults to a timestamp 2 weeks prior to the current time. - If
finishedAfterTimestamp
is set in your request but is older than 3 months, the API will return afinishedAfterTimestampTooEarly
error code to warn you of your invalid request.
Need to receive older results?
No problem. When you're ready, contact us to activate a seven day period where you can use older finishedAfterTimestamp
values to retrieve ALL your results.
GET recent results for all groups
HTTP request
GET https://api.classmarker.com/v1/groups/recent_results.json
Example request
curl --location --request GET "https://api.classmarker.com/v1/groups/recent_results.json?api_key=d4tsE7SvEgzAKlJPFrlvAz3oe9uFQnxy&signature=4495a14efc483aa5ee2f6d4cd480f968×tamp=1335783600&finishedAfterTimestamp=1339779290"
$finishedAfterTimestamp = 1339777290;
$limit = 200;
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->getRecentResultForAllGroups($finishedAfterTimestamp, $limit);
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1/groups/recent_results",
"server_timestamp": 1339782640,
"finished_after_timestamp_used": 1338908448,
"groups": [
{
"group": {
"group_id": 29765,
"group_name": "Internal Accounts department"
}
},
{
"group": {
"group_id": 73645,
"group_name": "Internal Sales Staff"
}
}
],
"tests": [
{
"test": {
"test_id": 64776,
"test_name": "Health and safety exam"
}
}
],
"results": [
{
"result": {
"user_id": 319118,
"first": "Paul",
"last": "Smith",
"email": "paul@example.com",
"test_id": 64776,
"group_id": 29765,
"percentage": 90,
"points_scored": 18,
"points_available": 20,
"time_started": 1339778290,
"time_finished": 1339781298,
"status": "f",
"duration": "00:50:08",
"percentage_passmark": 50,
"passed": true,
"requires_grading": "No",
"give_certificate_only_when_passed": true,
"certificate_url": "https://www.classmarker.com/pdf/certificate/SampleCertificate.pdf?required_parameters_here",
"certificate_serial": "CLPPYQSBSY-ZZVKJGQH-XHWMMRCHYT",
"view_results_url": "https://www.classmarker.com/view/results/?required_parameters_here"
}
},
{
"result": {
"user_id": 319119,
"first": "Tracy",
"last": "Thompson",
"email": "tracey@example.com",
"test_id": 64776,
"group_id": 73645,
"percentage": 50,
"points_scored": 10,
"points_available": 20,
"time_started": 133977830,
"time_finished": 133978998,
"status": "f",
"duration": "00:19:47",
"percentage_passmark": 50,
"passed": false,
"requires_grading": "No",
"give_certificate_only_when_passed": true,
"certificate_url": "https://www.classmarker.com/pdf/certificate/SampleCertificate.pdf?required_parameters_here",
"certificate_serial": "CXPWYQSBSY-ZYSVKJGQH-XHWMJUCHYT",
"view_results_url": "https://www.classmarker.com/view/results/?required_parameters_here"
}
}
],
"num_results_available": 2,
"num_results_returned": 2,
"more_results_exist": false,
"next_finished_after_timestamp": 133978998
}
Retrieves recent exam results for all groups your API key has permission to access.
Parameter | Type | Mandatory | Description |
---|---|---|---|
api_key |
string | Y | Your API key |
signature |
string | Y | Your MD5 signature |
timestamp |
timestamp | Y | Current UNIX timestamp in seconds |
finishedAfterTimestamp |
timestamp | Y | Current UNIX timestamp in seconds |
limit |
number | N | Number of results returned (default: 200) You can set a lower value but not higher |
Response object
Field | Description |
---|---|
status |
The three status responses you can receive are: ok Request was successful and results have been found and returned to you. no_results Request was successful, however, no results have been found. error An error has occurred in your request. Refer to error codes for possible values. |
finished_after_timestamp_used |
This is the finishedAfterTimestamp you sent ClassMarker with your request - useful for debugging. |
user_id |
Each registered user has a unique ID in ClassMarker. |
first |
First name. |
last |
Last name. |
email |
Users email. |
test_id |
Each exam has a unique ID in ClassMarker. |
group_id |
Each group has a unique ID in ClassMarker. |
percentage |
0 - 100 can include 1 decimal place. |
points_scored |
Total points scored. Can include 1 decimal place. |
points_available |
Total points available. Can include 1 decimal place. |
time_started |
Time Started (Unix Timestamp). |
time_finished |
Time Finished (Unix Timestamp). Can be updated and downloaded again (for example, an exam is re-opened by an administrator to give a user more time). |
status |
f: Finished. Status will always be "f" at present. |
duration |
Exam duration. |
percentage_passmark |
Percent required to pass exam. |
passed |
true or false ; true is returned if no Passmark is set for an exam. |
requires_grading |
Yes or No . Only exams that include essay style questions require grading. Score may not be considered final. |
give_certificate_only_when_passed |
true or false ; exams can be set up to disallow certificate downloading if a user fails the exam |
certificate_url |
Unique Link to download users certificate. |
certificate_serial |
Unique serial number for certificate. |
view_results_url |
Unique URL per exam result for viewing formatted exam results in ClassMarker (without being logged into a ClassMarker account). You need to set up an access control password for viewing access (see URL for viewing results for details). |
num_results_available |
The number of available results ClassMarker found in total. |
num_results_returned |
The number of results returned in this response (Maximum and Default returned results per request is 200). Use the Limit parameter in your request to modify. |
more_results_exist |
More results will be returned if you make another request using the next_finished_after_timestamp value as your next request parameters finishedAfterTimestamp so as to not download the same results twice. |
next_finished_after_timestamp |
When making your next request, use this timestamp as your next request parameters finishedAfterTimestamp so as to not re-download the same results twice. |
GET recent results for all links
HTTP request
GET https://api.classmarker.com/v1/links/recent_results.json
Example request
curl --location --request GET "https://api.classmarker.com/v1/links/recent_results.json?api_key=d4tsE7SvEgzAKlJPFrlvAz3oe9uFQnxy&signature=4495a14efc483aa5ee2f6d4cd480f968×tamp=1335783600&finishedAfterTimestamp=1339779290"
$finishedAfterTimestamp = 1339777290;
$limit = 200;
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->getRecentResultsForAllLinks($finishedAfterTimestamp, $limit);
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1/links/recent_results",
"server_timestamp": 1339838367,
"finished_after_timestamp_used": 1338908448,
"links": [
{
"link": {
"link_name": "New York Sales Staff",
"link_id": 38676,
"link_url_id": "g6v533a63444719ce32",
"access_list_id": 123456
}
},
{
"link": {
"link_name": "Sydney Sales Staff",
"link_id": 985674,
"link_url_id": "4mb5243e51cf0b0cswe",
"access_list_id": 637251
}
}
],
"tests": [
{
"test": {
"test_name": "Product specials and discounts quiz",
"test_id": 48756
}
}
],
"results": [
{
"result": {
"first": "Mary",
"last": "Simmons",
"test_id": 48756,
"link_id": 38676,
"percentage": 70,
"points_scored": 28,
"points_available": 40,
"time_started": 1339836668,
"time_finished": 1339836849,
"status": "f",
"email": "mary@example.com",
"access_code": "abc123",
"extra_info": "Demographic answer 1",
"extra_info2": "Demographic answer 2",
"extra_info3": "Demographic answer 3",
"extra_info4": "Demographic answer 4",
"extra_info5": "Demographic answer 5",
"duration": "00:02:41",
"percentage_passmark": 50,
"passed": true,
"requires_grading": "No",
"link_result_id": 22453,
"cm_user_id": "abc74524",
"ip_address": "192.0.43.10",
"give_certificate_only_when_passed": true,
"certificate_url": "https://www.classmarker.com/pdf/certificate/SampleCertificate.pdf?required_parameters_here",
"certificate_serial": "CLAQYQSBSY-ZZVKJGQH-XHWMMRCHYT",
"view_results_url": "https://www.classmarker.com/view/results/?required_parameters_here"
}
},
{
"result": {
"first": "Gary",
"last": "Carter",
"test_id": 48756,
"link_id": 38676,
"percentage": 81,
"points_scored": 32.4,
"points_available": 40,
"time_started": 1339836668,
"time_finished": 1339836849,
"status": "f",
"email": "mary@example.com",
"access_code": "abc123",
"extra_info": "Demographic answer 1",
"extra_info2": "Demographic answer 2",
"extra_info3": "Demographic answer 3",
"extra_info4": "Demographic answer 4",
"extra_info5": "Demographic answer 5",
"duration": "00:02:41",
"percentage_passmark": 50,
"passed": true,
"requires_grading": "No",
"link_result_id": 22463,
"cm_user_id": "ttr45613",
"ip_address": "192.0.43.10",
"give_certificate_only_when_passed": true,
"certificate_url": "https://www.classmarker.com/pdf/certificate/SampleCertificate.pdf?required_parameters_here",
"certificate_serial": "CLPERQSBSY-ZZVKJGQH-XHWMMRCHYT",
"view_results_url": "https://www.classmarker.com/view/results/?required_parameters_here"
}
},
{
"result": {
"first": "Carl",
"last": "Bright",
"test_id": 48756,
"link_id": 985674,
"percentage": 80,
"points_scored": 32,
"points_available": 40,
"time_started": 1339836668,
"time_finished": 1339836849,
"status": "f",
"email": "carl@example.com",
"access_code": "abc123",
"extra_info": "Demographic answer 1",
"extra_info2": "Demographic answer 2",
"extra_info3": "Demographic answer 3",
"extra_info4": "Demographic answer 4",
"extra_info5": "Demographic answer 5",
"duration": "00:02:41",
"percentage_passmark": 50,
"passed": true,
"requires_grading": "No",
"link_result_id": 22522,
"cm_user_id": "u7y45t",
"ip_address": "192.0.43.10",
"give_certificate_only_when_passed": true,
"certificate_url": "https://www.classmarker.com/pdf/certificate/SampleCertificate.pdf?required_parameters_here",
"certificate_serial": "CLPPYQSBSY-ZZVKJGQH-XHWMMRCHYT",
"view_results_url": "https://www.classmarker.com/view/results/?required_parameters_here"
}
}
],
"num_results_available": 3,
"num_results_returned": 3,
"more_results_exist": false,
"next_finished_after_timestamp": 1339836709
}
Retrieves recent results for all links your API key has permission to access.
Parameter | Type | Mandatory | Description |
---|---|---|---|
api_key |
string | Y | Your API key |
signature |
string | Y | Your MD5 signature |
timestamp |
timestamp | Y | Current UNIX timestamp in seconds |
finishedAfterTimestamp |
timestamp | Y | Current UNIX timestamp in seconds |
limit |
number | N | Number of results returned (default: 200) You can set a lower value but not higher |
Response object
Field | Description |
---|---|
status |
The three status responses you can receive are: ok Request was successful and results have been found and returned to you. no_results Request was successful, however, no results have been found. error An error has occurred in your request. Refer to error codes for possible values. |
finished_after_timestamp_used |
This is the finishedAfterTimestamp you sent ClassMarker with your request - useful for debugging. |
access_list_id |
Only included if an access list is currently assigned to the link. |
link_url_id |
Only included if it is enabled in the permissions during API key generation. |
link_result_id |
Unique 'Test Result ID'. |
first |
First name. |
last |
Last name. |
email |
Users email. |
test_id |
Each exam has a unique ID in ClassMarker. |
link_id |
Each link has a unique ID in ClassMarker. |
percentage |
0 - 100 can include 1 decimal place. |
points_scored |
Total points scored. Can include 1 decimal place. |
points_available |
Total points available. Can include 1 decimal place. |
time_started |
Time Started (Unix Timestamp). |
time_finished |
Time Finished (Unix Timestamp). Can be updated and downloaded again (for example, an exam is re-opened by an administrator to give a user more time). |
status |
f: Finished. Status will always be "f" at present. |
access_code |
Access code used to access test. |
extra_info |
Users answer 1. (Optional: non graded questions asked before Exam is started). |
extra_info2 |
Users answer 2. |
extra_info3 |
Users answer 3. |
extra_info4 |
Users answer 4. |
extra_info5 |
Users answer 5. |
cm_user_id |
Only included if it is sent to ClassMarker Use your own user IDs with ClassMarker. |
ip_address |
Users IP Address. |
duration |
Exam duration. |
percentage_passmark |
Percent required to pass exam. |
passed |
true or false ; true is returned if no Passmark is set for an exam. |
requires_grading |
Yes or No . Only exams that include essay style questions require grading. Score may not be considered final. |
give_certificate_only_when_passed |
true or false ; exams can be set up to disallow certificate downloading if a user fails the exam. |
certificate_url |
Unique Link to download users certificate. |
certificate_serial |
Unique serial number for certificate. |
view_results_url |
Unique URL per exam result for viewing formatted exam results in ClassMarker (without being logged into a ClassMarker account). You need to set up an access control password for viewing access (see URL for viewing results for details). |
num_results_available |
The number of available results ClassMarker found in total. |
num_results_returned |
The number of results returned in this response (Maximum and Default returned results per request is 200). Use the Limit parameter in your request to modify. |
more_results_exist |
More results will be returned if you make another request using the next_finished_after_timestamp value as your next request parameters finishedAfterTimestamp so as to not download the same results twice. |
next_finished_after_timestamp |
When making your next request, use this timestamp as your next request parameters finishedAfterTimestamp so as to not re-download the same results twice. |
GET recent results for specific group/exam
HTTP request
GET https://api.classmarker.com/v1/groups/{group_id}/tests/{test_id}/recent_results.json
Example request
curl --location --request GET "https://api.classmarker.com/v1/groups/110928/tests/744533/recent_results.json?api_key=Jtyh4zWiaF9SngWhlpRGElNRDtEnLTC1&signature=713cdae732ac2e0206e7c436bb03f8a0×tamp=1620999467"
$finishedAfterTimestamp = 1339777290;
$limit = 200;
$test_id = 726750;
$group_id = 151877;
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->getRecentResultsForSingleGroup($test_id, $group_id, $finishedAfterTimestamp, $limit);
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1/groups/29765/tests/64776/recent_results",
"server_timestamp": 1339782640,
"finished_after_timestamp_used": 1338908448,
"groups": [
{
"group": {
"group_id": 29765,
"group_name": "Internal Accounts department"
}
}
],
"tests": [
{
"test": {
"test_id": 64776,
"test_name": "Health and safety exam"
}
}
],
"results": [
{
"result": {
"user_id": 319118,
"first": "Paul",
"last": "Smith",
"email": "paul@example.com",
"test_id": 64776,
"group_id": 29765,
"percentage": 90,
"points_scored": 18,
"points_available": 20,
"time_started": 1339778290,
"time_finished": 1339781298,
"status": "f",
"duration": "00:50:08",
"percentage_passmark": 50,
"passed": true,
"requires_grading": "No",
"give_certificate_only_when_passed": true,
"certificate_url": "https://www.classmarker.com/pdf/certificate/SampleCertificate.pdf?required_parameters_here",
"certificate_serial": "CAQPYQSBSY-ZZVKJGQH-XHWMMRCHYT",
"view_results_url": "https://www.classmarker.com/view/results/?required_parameters_here"
}
},
{
"result": {
"user_id": 319119,
"first": "Tracy",
"last": "Thompson",
"email": "tracey@example.com",
"test_id": 64776,
"group_id": 29765,
"percentage": 50,
"points_scored": 10,
"points_available": 20,
"time_started": 133977830,
"time_finished": 133978998,
"status": "f",
"duration": "00:19:47",
"percentage_passmark": 50,
"passed": false,
"requires_grading": "No",
"give_certificate_only_when_passed": true,
"certificate_url": "https://www.classmarker.com/pdf/certificate/SampleCertificate.pdf?required_parameters_here",
"certificate_serial": "CLPPYQSBSY-ZZVKJGQH-XHWMMRDFYT",
"view_results_url": "https://www.classmarker.com/view/results/?required_parameters_here"
}
}
],
"num_results_available": 2,
"num_results_returned": 2,
"more_results_exist": false,
"next_finished_after_timestamp": 133978998
}
Retrieves results for a specific group and exam your API key has permission to access.
Parameter | Type | Mandatory | Description |
---|---|---|---|
api_key |
string | Y | Your API key |
signature |
string | Y | Your MD5 signature |
timestamp |
timestamp | Y | Current UNIX timestamp in seconds |
finishedAfterTimestamp |
timestamp | Y | Current UNIX timestamp in seconds |
limit |
number | N | Number of results returned (default: 200) You can set a lower value but not higher |
Response object
See field descriptions: GET recent results for all groups
GET recent results for specific link/exam
HTTP request
GET https://api.classmarker.com/v1/links/{link_id}/tests/{test_id}/recent_results.json
Example request
curl --location --request GET "https://api.classmarker.com/v1/links/29765/tests/64776/recent_results.json?api_key=d4tsE7SvEgzAKlJPFrlvAz3oe9uFQnxy&signature=4495a14efc483aa5ee2f6d4cd480f968×tamp=1335783600&finishedAfterTimestamp=1339779290"
$finishedAfterTimestamp = 1339777290;
$limit = 200;
$test_id = 293383;
$link_id = 332382;
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->getRecentResultsForSingleLink($test_id, $group_id, $finishedAfterTimestamp, $limit);
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1/links/38676/tests/48756/recent_results",
"server_timestamp": 1339838367,
"finished_after_timestamp_used": 1338908448,
"links": [
{
"link": {
"link_name": "New York Sales Staff",
"link_id": 38676,
"link_url_id": "g6v533a63444719ce32",
"access_list_id": 123456
}
}
],
"tests": [
{
"test": {
"test_name": "Product specials and discounts quiz",
"test_id": "48756"
}
}
],
"results": [
{
"result": {
"first": "Mary",
"last": "Simmons",
"test_id": 48756,
"link_id": 38676,
"percentage": 70,
"points_scored": 28,
"points_available": 40,
"time_started": 1339836668,
"time_finished": 1339836849,
"status": "f",
"email": "mary@example.com",
"access_code": "abc123",
"extra_info": "Demographic answer 1",
"extra_info2": "Demographic answer 2",
"extra_info3": "Demographic answer 3",
"extra_info4": "Demographic answer 4",
"extra_info5": "Demographic answer 5",
"duration": "00:02:41",
"percentage_passmark": 50,
"passed": true,
"requires_grading": "No",
"link_result_id": 22453,
"cm_user_id": "abc74524",
"ip_address": "192.0.43.10",
"give_certificate_only_when_passed": true,
"certificate_url": "https://www.classmarker.com/pdf/certificate/SampleCertificate.pdf?required_parameters_here",
"certificate_serial": "CLKPYQSBSY-ZZVKJGQH-XHWMMRCHYT",
"view_results_url": "https://www.classmarker.com/view/results/?required_parameters_here"
}
},
{
"result": {
"first": "Gary",
"last": "Carter",
"test_id": 48756,
"link_id": 38676,
"percentage": 81,
"points_scored": 32.4,
"points_available": 40,
"time_started": 1339836668,
"time_finished": 1339836849,
"status": "f",
"email": "mary@example.com",
"access_code": "abc123",
"extra_info": "Demographic answer 1",
"extra_info2": "Demographic answer 2",
"extra_info3": "Demographic answer 3",
"extra_info4": "Demographic answer 4",
"extra_info5": "Demographic answer 5",
"duration": "00:02:41",
"percentage_passmark": 50,
"passed": true,
"requires_grading": "No",
"link_result_id": 22463,
"cm_user_id": "ttr45613",
"ip_address": "192.0.43.10",
"give_certificate_only_when_passed": true,
"certificate_url": "https://www.classmarker.com/pdf/certificate/SampleCertificate.pdf?required_parameters_here",
"certificate_serial": "CZZPYQSBSY-ZZVKJGQH-XHWMMRCHYT",
"view_results_url": "https://www.classmarker.com/view/results/?required_parameters_here"
}
}
],
"num_results_available": 2,
"num_results_returned": 2,
"more_results_exist": false,
"next_finished_after_timestamp": 1339836709
}
Retrieves results for a specific link and exam your API key has permission to access.
Parameter | Type | Mandatory | Description |
---|---|---|---|
api_key |
string | Y | Your API key |
signature |
string | Y | Your MD5 signature |
timestamp |
timestamp | Y | Current UNIX timestamp in seconds |
finishedAfterTimestamp |
timestamp | Y | Current UNIX timestamp in seconds |
limit |
number | N | Number of results returned (default: 200) You can set a lower value but not higher |
Response object
Field | Description |
---|
See field descriptions: GET recent results for all links
Access lists
You can use access lists to restrict access to exams for non-registered users.
POST access codes
HTTP request
POST https://api.classmarker.com/v1/accesslists/{access_list_id}.json
Request body - JSON array of access codes to add
["Code1","Code2","Code3","Code4"]
Example request
curl --location --request POST "https://api.classmarker.com/v1/accesslists/123456.json?api_key=d4tsE7SvEgzAKlJPFrlvAz3oe9uFQnxy&signature=4495a14efc483aa5ee2f6d4cd480f968×tamp=1335783600" \
--header "Content-Type: application/json" \
--data '["Code1", "Code2", "Code3", "Code4"]'
$access_list_id = 123456;
$json_body = '["Code1", "Code2", "Code3", "Code4"]';
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->addAccessListCodes($access_list_id, $json_body);
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1/accesslists/123456",
"server_timestamp": 1335783600,
"access_lists": {
"access_list": {
"access_list_id": 123456,
"access_list_name": "New York Staff",
"num_codes_added": 4,
"num_codes_total": 16
}
}
}
Add one or more access codes to an access list. The following limits apply:
- 100 access codes maximum per request
- 20,000 access codes of up to 255 characters per access list
- API rate limits do not apply when adding access codes
Parameter | Type | Mandatory | Description |
---|---|---|---|
api_key |
string | Y | Your API key |
signature |
string | Y | Your MD5 signature |
timestamp |
timestamp | Y | Current UNIX timestamp in seconds |
DELETE access codes
HTTP request
DELETE https://api.classmarker.com/v1/accesslists/{access_list_id}.json
Request body - JSON array of access codes to remove
["Code1","Code2","Code3","Code4"]
Example request
curl --location --request DELETE "https://api.classmarker.com/v1/accesslists/123456.json?api_key=d4tsE7SvEgzAKlJPFrlvAz3oe9uFQnxy&signature=4495a14efc483aa5ee2f6d4cd480f968×tamp=1335783600" \
--header "Content-Type: application/json" \
--data '["Code1", "Code2", "Code3", "Code4"]'
$access_list_id = 123456;
$json_body = '["Code1", "Code2", "Code3", "Code4"]';
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->deleteAccessListCodes($access_list_id, $json_body);
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1/accesslists/123456",
"server_timestamp": 1335783600,
"access_lists": {
"access_list": {
"access_list_id": 123456,
"access_list_name": "New York Staff",
"num_codes_deleted": 4,
"num_codes_total": 16
}
}
}
Remove one or more access codes from an access list. The following restrictions apply:
- 100 access codes maximum per request
- 20,000 access codes of up to 255 characters per access list
- API rate limits do not apply when removing access codes
Categories
GET all categories
HTTP request
GET https://api.classmarker.com/v1/categories.json
Example request
curl --location --request GET https://api.classmarker.com/v1/categories.json?api_key=d4tsE7SvEgzAKlJPFrlvAz3oe9uFQnxy&signature=4495a14efc483aa5ee2f6d4cd480f968×tamp=1335783600"
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->getAllCategories();
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1/categories.json",
"server_timestamp": 1335783600,
"data": {
"parent_categories": [
{
"parent_category_id": 1,
"parent_category_name": "Mathematics",
"categories": [
{
"category_id": 3,
"category_name": "Calculus",
"parent_category_id": 1
},
{
"category_id": 4,
"category_name": "Probabilities",
"parent_category_id": 1
}
]
}
]
}
}
Retrieves exam categories.
POST parent category
HTTP request
POST https://api.classmarker.com/v1/categories/parent_category.json
Request body
{
"parent_category_name": "Mathematics"
}
Example request
curl --location --request POST "https://api.classmarker.com/v1/categories/parent_category.json"
--header "Content-Type: application/json" \
--data '{"parent_category_name": "Mathematics"}'
$parent_category_name = 'Mathematics';
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->addParentCategory($parent_category_name);
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1/categories/parent_category.json",
"server_timestamp": 1335783600,
"data": {
"parent_category": {
"parent_category_id": 2,
"parent_category_name": "Mathematics",
"categories": []
}
}
}
Creates a new parent category.
Parameter | Type | Mandatory | Description |
---|---|---|---|
verify_only |
boolean | N | Set to true to verify the format without updating, or false to update |
PUT parent category
HTTP request
PUT https://api.classmarker.com/v1/categories/parent_category/{parent_category_id}.json
Request body
{
"parent_category_name": "Mathematics"
}
Example request
curl --location --request PUT "https://api.classmarker.com/v1/categories/parent_category/2.json"
--header "Content-Type: application/json" \
--data '{"parent_category_name": "Mathematics"}'
$parent_category_id = 2;
$parent_category_name = 'Mathematics';
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->updateParentCategory($parent_category_id, $parent_category_name);
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1/categories/parent_category/1.json",
"server_timestamp": 1335783600,
"data": {
"parent_category": {
"parent_category_id": 2,
"parent_category_name": "Mathematics",
"categories": [
{
"category_id": 3,
"category_name": "Calculus",
"parent_category_id": 2
}
]
}
}
}
Updates an existing parent category.
Parameter | Type | Mandatory | Description |
---|---|---|---|
verify_only |
boolean | N | Set to true to verify the format without updating, or false to update |
POST category
HTTP request
POST https://api.classmarker.com/v1/categories/category.json
Request body
{
"category_name": "calculus",
"parent_category_id": "2"}
}
Example request
curl --location --request POST "https://api.classmarker.com/v1/categories/category.json"
--header "Content-Type: application/json" \
--data '{"category_name": "Calculus", "parent_category_id": 2}'
$parent_category_id = 2;
$parent_category_name = 'Calculus';
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->addCategory($parent_category_id, $category_name);
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1/categories/category.json",
"server_timestamp": 1335783600,
"data": {
"category": {
"category_id": 3,
"category_name": "Calculus",
"parent_category_id": 2
}
}
}
Creates a new category within a parent category.
Parameter | Type | Mandatory | Description |
---|---|---|---|
verify_only |
boolean | N | Set to true to verify the format without updating, or false to update |
PUT category
HTTP request
PUT https://api.classmarker.com/v1/category/{category_id}.json
Request body
{
"category_name": "Fractions",
"parent_category_id": 2
}
Example request
curl --location --request PUT "https://api.classmarker.com/v1/category/{category_id}.json"
--header "Content-Type: application/json" \
--data '{"category_name": "Fractions", "parent_category_id": 2}'
$parent_category_id = 2;
$category_id = 3;
$parent_category_name = 'Fractions';
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->updateCategory($category_id, $parent_category_id, $category_name);
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1/categories/category/3.json",
"server_timestamp": 1335783600,
"data": {
"category": {
"category_id": 3,
"category_name": "Fractions",
"parent_category_id": 2
}
}
}
Updates an existing category.
Parameter | Type | Mandatory | Description |
---|---|---|---|
verify_only |
boolean | N | Set to true to verify the format without updating, or false to update |
Question bank
Question types
ClassMarker supports the following question types:
- Multiple choice
- Multiple response
- True/false
- Essay
- Matching (per match, single)
- Free text
- Grammar
You can retrieve all question types, but only create and update the first four types in the list.
GET all questions in your question bank
HTTP request
GET https://api.classmarker.com/v1/questions.json
Example request
curl --location --request GET https://api.classmarker.com/v1/questions.json
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->getAllQuestions();
echo $json_response;
Response
{
"status": "ok",
"request_path": "v1/questions",
"server_timestamp": 1606694308,
"questions": [
{
"question_id": 53353203,
"question": "What is the first step for treating a skin burn?",
"question_type": "multiplechoice",
"category_id": 1,
"random_answers": false,
"points": "2.0",
"correct_feedback": "Well done!",
"incorrect_feedback": "Sorry, that was incorrect, refer to your training materials for further details.",
"last_updated_timestamp": 1606694308,
"status": "active",
"options": {
"A": {
"content": "Apply oil or butter"
},
"B": {
"content": "Nothing should be done"
},
"C": {
"content": "Soak in water for five minutes"
},
"D": {
"content": "Apply antibiotic ointment"
}
},
"correct_options": [
"C"
]
},
{
"question_id": 53384556,
"question": "Select the two ways we train new staff:",
"question_type": "multipleresponse",
"category_id": 1,
"random_answers": false,
"points": "2.0",
"correct_feedback": "Well done!",
"incorrect_feedback": "Sorry, that was incorrect, refer to your training materials for further details.",
"last_updated_timestamp": 1606694308,
"status": "active",
"grade_style": "partial_without_deduction",
"options": {
"A": {
"content": "Wait for them to make mistakes and address the issue then"
},
"B": {
"content": "Give them our Traing Materials and specific time for training"
},
"C": {
"content": "Test them on their knowledge after they have completed the Traing Materials"
},
"D": {
"content": "Test them on their knowledge before they have completed the Traing Materials"
},
"correct_options": [
"B",
"C"
]
}
}
]
}
Retrieves all questions from your question bank.
Parameter | Type | Mandatory | Description |
---|---|---|---|
page |
number | N | Pagination number to retrieve (default: 1) Number of questions per page: 200 |
Response object
Field | Description |
---|---|
grading scale |
Not supported by multiplechoice question types |
correct_answer |
Does not apply to essay questions, which need to be scored manually be a teacher/admin |
options |
A list of possible answers to multiple choice or multiple response questions -- you can specify up to 10 options (A-J) |
status |
active or archived |
correct_feedback |
Optional field |
incorrect_feedback |
Optional field |
GET question
HTTP request
GET https://api.classmarker.com/v1/questions/{question_id}.json
Example request
curl --location --request GET https://api.classmarker.com/v1/questions/53353203.json
$question_id = 53353203;
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->getQuestion($question_id);
echo $json_response;
Response
{
"question_id": 53353203,
"question": "What is the first step for treating a skin burn?",
"question_type": "multiplechoice",
"category_id": 1,
"random_answers": false,
"points": "2.0",
"correct_feedback": "Well done!",
"incorrect_feedback": "Sorry, that was incorrect, refer to your training materials for further details.",
"last_updated_timestamp": 1606694308,
"status": "active",
"options": {
"A": {
"content": "Apply oil or butter"
},
"B": {
"content": "Nothing should be done"
},
"C": {
"content": "Soak in water for five minutes"
},
"D": {
"content": "Apply antibiotic ointment"
}
},
"correct_options": [
"C"
]
}
Retrieves a specific question from your question bank.
Response object
Field | Description |
---|---|
grading scale |
Not supported by multiplechoice question types |
correct_answer |
Does not apply to essay questions, which need to be scored manually be an exam giver |
options |
A list of possible answers to multiple choice or multiple response questions -- you can specify up to 10 options (A-J) |
status |
active or archived |
correct_feedback |
Optional field |
incorrect_feedback |
Optional field |
POST question
HTTP request
POST https://api.classmarker.com/v1/questions/{question_id}.json
Example request
curl --location --request POST "https://api.classmarker.com/v1/questions.json"
--header "Content-Type: application/json" \
--data '{
"question", "What is the first step for treating a skin burn?",
"question_type": "multiplechoice",
"category_id", "3",
"random_answers": false,
"points": 2,
"correct_feedback": "Well done!",
"incorrect_feedback": "Sorry, that was incorrect, refer to your training materials for further details."
"options": {
"A": {
"content": "Apply oil or butter"
},
"B": {
"content": "Nothing should be done"
},
"C": {
"content": "Soak in water for five minutes"
},
"D": {
"content": "Apply antibiotic ointment"
}
},
"correct_options": ["C"],
}'
$question_json = '{
"question": "What is the first step for treating a skin burn?",
"question_type": "multiplechoice",
"category_id": 3,
"random_answers": false,
"points": "2.0",
"correct_feedback": "Well done!",
"incorrect_feedback": "Sorry, that was incorrect, refer to your training materials for further details.",
"options": {
"A": {
"content": "Apply oil or butter"
},
"B": {
"content": "Nothing should be done"
},
"C": {
"content": "Soak in water for five minutes"
},
"D": {
"content": "Apply antibiotic ointment"
}
},
"correct_options": ["C"]
}';
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->addQuestion($question_json);
echo $json_response;
Response
{
"question_id": 53353998,
"question": "What is the first step for treating a skin burn?",
"question_type": "multiplechoice",
"category_id": 3,
"random_answers": false,
"points": "2.0",
"correct_feedback": "Well done!",
"incorrect_feedback": "Sorry, that was incorrect, refer to your training materials for further details.",
"last_updated_timestamp": 1606694308,
"status": "active",
"options": {
"A": {
"content": "Apply oil or butter"
},
"B": {
"content": "Nothing should be done"
},
"C": {
"content": "Soak in water for five minutes"
},
"D": {
"content": "Apply antibiotic ointment"
}
},
"correct_options": [
"C"
]
}
Verify only response
{
"status": "verified",
"request_path": "v1/questions",
"server_timestamp": 1608266935
}
Creates a new question in the question bank.
Parameter | Type | Mandatory | Description |
---|---|---|---|
verify_only |
boolean | N | Set to true to verify the format without updating, or false to update |
Request body
The following fields are not supported when creating or updating questions:
question_id
last_updated_timestamp
status
The following fields are optional when creating or updating questions:
correct_feedback
incorrect_feedback
The following fields are returned for all question types.
Field | Type | Description |
---|---|---|
question_id |
number | Unique question identifier |
question_type |
string | Defines question type |
category_id |
number | Unique category identifier |
question |
string | Question details |
Specific question type fields are described in the sections below.
PUT question
HTTP request
PUT https://api.classmarker.com/v1/parent_category.json/questions/{question_id}.json
Example request
curl --location --request PUT "https://api.classmarker.com/v1/questions/53353998.json"
--header "Content-Type: application/json" \
--data '{
"question", "What is the first step for treating a skin burn?",
"question_type": "multiplechoice",
"category_id", "3",
"random_answers": false,
"points": 2,
"correct_feedback": "Well done!",
"incorrect_feedback": "Sorry, that was incorrect, refer to your training materials for further details."
"options": {
"A": {
"content": "Apply oil or butter"
},
"B": {
"content": "Nothing should be done"
},
"C": {
"content": "Soak in water for five minutes"
},
"D": {
"content": "Apply antibiotic ointment"
}
},
"correct_options": ["C"],
}'
$question_id = 53353998;
$question_json = '{
"question": "What is the first step for treating a skin burn?",
"question_type": "multiplechoice",
"category_id": 3,
"random_answers": false,
"points": "2.0",
"correct_feedback": "Well done!",
"incorrect_feedback": "Sorry, that was incorrect, refer to your training materials for further details.",
"options": {
"A": {
"content": "Apply oil or butter"
},
"B": {
"content": "Nothing should be done"
},
"C": {
"content": "Soak in water for five minutes"
},
"D": {
"content": "Apply antibiotic ointment"
}
},
"correct_options": ["C"]
}';
$cm_client = new ClassMarkerClient($cm_api_key, $cm_api_secret);
$json_response = $cm_client->updateQuestion($question_id, $question_json);
echo $json_response;
Response
{
"question_id": 53353998,
"question": "What is the first step for treating skin burns?",
"question_type": "multiplechoice",
"category_id": 3,
"random_answers": false,
"points": "2.0",
"correct_feedback": "Well done!",
"incorrect_feedback": "Sorry, that was incorrect, refer to your training materials for further details.",
"last_updated_timestamp": 1606834478,
"status": "active",
"options": {
"A": {
"content": "Apply oil or butter"
},
"B": {
"content": "Nothing should be done"
},
"C": {
"content": "Soak in water for five minutes"
},
"D": {
"content": "Apply antibiotic ointment"
}
},
"correct_options": [
"C"
]
}
Verify only response
{
"status": "verified",
"request_path": "v1/questions",
"server_timestamp": 1608266935
}
Updates an existing question in the question bank.
Parameter | Type | Mandatory | Description |
---|---|---|---|
verify_only |
boolean | N | Set to true to verify the format without updating |
Request body
See the POST question request body section.
Question object examples
Multiple choice
HTTP request
POST https://api.classmarker.com/v1/questions.json
Request body - multiplechoice
{
"question_id": 53353998,
"question": "What is the first step for treating a skin burn?",
"question_type": "multiplechoice",
"category_id": 1,
"random_answers": false,
"points": "2.0",
"correct_feedback": "Well done!",
"incorrect_feedback": "Sorry, that was incorrect, refer to your training materials for further details.",
"last_updated_timestamp": 1606694308,
"status": "active",
"options": {
"A": {
"content": "Apply oil or butter"
},
"B": {
"content": "Nothing should be done"
},
"C": {
"content": "Soak in water for five minutes"
},
"D": {
"content": "Apply antibiotic ointment"
}
},
"correct_options": [
"C"
]
}
Multiple choice questions do not support grading scale marking types.
Field | Type | Description |
---|---|---|
question_id |
number | question unique identifier |
question_type |
string | defines question type |
question |
string | the question text |
category_id |
number | category unique identifier |
points |
number | Points exam taker receives for answering correctly |
options |
object | A list of possible answers, up to 10 (A to J) are allowed |
correct_options |
string | Alphabetical index of options which are correct, only one is allowed |
random_answers |
boolean | Whether to randomize the order of options |
correct_feedback |
string | Feedback for exam taker for correct answer |
incorrect_feedback |
string | Feedback for exam taker for incorrect answer |
last_updated_timestamp |
string | UNIX timestamp |
status |
string | Active or archived question |
Multiple response
Request body - multipleresponse
{
"question_id": 53384556,
"question": "Select the two ways we train new staff:",
"question_type": "multipleresponse",
"category_id": 1,
"random_answers": false,
"points": "2.0",
"correct_feedback": "Well done!",
"incorrect_feedback": "Sorry, that was incorrect, refer to your training materials for further details.",
"last_updated_timestamp": 1606694308,
"status": "active",
"grade_style": "partial_without_deduction",
"options": {
"A": {
"content": "Wait for them to make mistakes and address the issue then"
},
"B": {
"content": "Give them our Traing Materials and specific time for training"
},
"C": {
"content": "Test them on their knowledge after they have completed the Traing Materials"
},
"D": {
"content": "Test them on their knowledge before they have completed the Traing Materials"
},
"correct_options": [
"B",
"C"
]
}
}
Multiple response questions can have one or more correct options.
Field | Type | Description |
---|---|---|
question_id |
number | question unique identifier |
question_type |
string | defines question type |
question |
string | the question text |
category_id |
number | category unique identifier |
points |
number | Points exam taker receives for answering correctly |
options |
object | A list of possible answers, up to 10 (A to J) are allowed |
correct_options |
string | Alphabetical index of options which are correct, only one is allowed |
random_answers |
boolean | Whether to randomize the order of options |
grade_style |
string | Either partial_with_deduction , partial_without_deduction or off |
correct_feedback |
string | Feedback for exam taker for correct answer |
incorrect_feedback |
string | Feedback for exam taker for incorrect answer |
last_updated_timestamp |
string | UNIX timestamp |
status |
string | Active or archived question |
True/false
Request body - true/false
{
"question_id": 53343792,
"question_type": "truefalse",
"category_id": 5,
"question": "Our customer support staff work 7 days a week",
"options": {
"A": {
"content": "True"
},
"B": {
"content": "False"
}
},
"correct_options": [
"A"
],
"points": 2,
"correct_feedback": "Well Done!",
"incorrect_feedback": "That is incorrect, we provide 7 day customer support",
"last_updated_timestamp": 1608085335,
"status": "active"
}
Field | Type | Description |
---|---|---|
question_id |
number | question unique identifier |
question_type |
string | defines question type |
question |
string | the question text |
category_id |
number | category unique identifier |
points |
number | Points exam taker receives for answering correctly |
options |
object | A list of possible answers, up to 10 (A to J) are allowed |
correct_options |
string | Alphabetical index of options which are correct, only one is allowed |
correct_feedback |
string | Feedback for exam taker for correct answer |
incorrect_feedback |
string | Feedback for exam taker for incorrect answer |
last_updated_timestamp |
string | UNIX timestamp |
status |
string | Active or archived question |
Essay
Request body - essay
{
"question_id": 53039287,
"question_type": "essay",
"category_id": 5,
"question": "Describe some advantages of having test papers graded instantly:",
"points": 30,
"correct_feedback": "Well Done!",
"incorrect_feedback": "More details are required in your answer",
"last_updated_timestamp": 1608085335,
"status": "active"
}
Essay questions do not have a correct_answer
field, since the exam giver needs to score them manually.
Field | Type | Description |
---|---|---|
question_id |
number | question unique identifier |
question_type |
string | defines question type |
question |
string | the question text |
category_id |
number | category unique identifier |
points |
number | Points exam taker receives for answering correctly |
correct_feedback |
string | Feedback for exam taker for correct answer |
incorrect_feedback |
string | Feedback for exam taker for incorrect answer |
last_updated_timestamp |
string | UNIX timestamp |
status |
string | Active or archived question |
Free Text
Request body - freetext
{
"question_id": 54342821,
"question_type": "freetext",
"category_id": 5,
"question": "The cpu i7-9700k is designed and developer by ________",
"options": {
"A": {
"content": "Intel",
"type": "exact_match"
},
"B": {
"content": "intel",
"type": "exact_match"
},
"C": {
"content": "Intel Co.",
"type": "exact_match"
},
"D": {
"content": "Intel Computer",
"type": "exact_match"
}
},
"points": 2,
"correct_feedback": "Nice work!",
"incorrect_feedback": "There are only two company desing Computer PC in the world.",
"last_updated_datetime": 1608085335,
"status": "active"
}
Free Text (Short answer) questions allow you to set multiple correct answers that will be accepted as correct.
Field | Type | Description |
---|---|---|
question_id |
number | question unique identifier |
question_type |
string | defines question type |
question |
string | the question text |
category_id |
number | category unique identifier |
points |
number | Points exam taker receives for answering correctly |
options |
object | A list of possible answers, up to 20 (A to T) are allowed |
content |
string | Accepted answers |
type |
string | exact_match is case-sensitive and the only supported option at present |
correct_feedback |
string | Feedback for exam taker for correct answer |
incorrect_feedback |
string | Feedback for exam taker for incorrect answer |
last_updated_timestamp |
string | UNIX timestamp |
status |
string | Active or archived question |
Grammar
Request body - grammar
{
"question_id": 32483729,
"question_type": "grammar",
"category_id": 5,
"question": "Was the car was parkked over their!",
"options": {
"A": {
"content": "Was the car was parked over there?"
}
},
"points": 2,
"correct_feedback": "Nice work!",
"incorrect_feedback": "There are only two company desing Computer PC in the world.",
"last_updated_datetime": 1608085335,
"status": "active"
}
Grammar questions allow you to set multiple correct answers that will be accepted as correct.
Field | Type | Description |
---|---|---|
question_id |
number | question unique identifier |
question_type |
string | defines question type |
question |
string | the question text |
category_id |
number | category unique identifier |
options |
object | A list of 1 single correct answer |
content |
string | Accepted answer |
correct_feedback |
string | Feedback for exam taker for correct answer |
incorrect_feedback |
string | Feedback for exam taker for incorrect answer |
last_updated_timestamp |
string | UNIX timestamp |
status |
string | Active or archived question |
Matching
Request body - matching
{
"question_id" : 53882732,
"question_type": "matching",
"category_id": 5,
"question": "Match the Capitals with the Country:",
"random_matching": "shuffle_clues_only | shuffle_clues_and_matches",
"matching_style": "drop_down",
"points_style": "per_match",
"grade_style": "off",
"options":{
"A": {
"clue": "England",
"match": "London",
"positive_score": 1,
"negative_score": 0
},
"B": {
"clue": "United States of America",
"match": "Washington D.C.",
"positive_score": 1,
"negative_score": 0
},
"C": {
"clue": "China",
"match": "Beijing",
"positive_score": 2,
"negative_score": 0
},
"D": {
"clue": "Australia",
"match": "Canberra",
"positive_score": 2,
"negative_score": 0
},
"E": {
"clue": "South Korea",
"match": "Seoul",
"positive_score": 2,
"negative_score": 0
}
},
"incorrect_options": ["Sydney", "New York", "Hong Kong"],
"points": 8.0,
"correct_feedback": "Nice work!",
"incorrect_feedback": "29 + 32 = 61",
"last_updated_datetime": 1608085335,
"status": "active"
}
Matching questions can have:
- Single points (see
points_style
) set for whole question or points per match - Matches (see
matching_style
) can be a HTML select list or text and media objects
Field | Type | Description |
---|---|---|
question_id |
number | question unique identifier |
question_type |
string | defines question type |
question |
string | the question text |
category_id |
number | category unique identifier |
points |
number | Points exam taker receives for answering correctly |
options |
object | A list of clues, matches |
clue |
string | clue text (displays left side) |
match |
string | clue text (displays right side side) |
positive_score |
number | points to receive when correct |
negative_score |
number | point to deduct when incorrect |
incorrect_options |
array | list of incorrect answer to raise question difficulty |
points_style |
string | single will use points field, per_match will use positive_score and negative_score fields |
grade_style , |
string | partial_with_deduction , partial_without_deduction , Default off only used when points_style set to single |
random_matching |
string | which options to shuffle when giving question: shuffle_matches_only , shuffle_clues_only , shuffle_clues_and_matches |
matching_style |
string | drop_down for HTML select list, |
correct_feedback |
string | Feedback for exam taker for correct answer |
incorrect_feedback |
string | Feedback for exam taker for incorrect answer |
last_updated_timestamp |
string | UNIX timestamp |
status |
string | Active or archived question |
Errors
Standard HTTP 404, 500 series error messages are returned if applicable.
ClassMarker's requests otherwise return an HTTP 200 success header even if an API system error occurs (such as the errors listed below).
ClassMarker API returns the following error message attributes as key-value pairs:
Key | Value |
---|---|
apiKeyAuthFail |
Access denied. Your API key authorization failed. Check your API key and API secret and try again. |
apiKeyInactive |
Access denied. Your API key authorization is currently not active. Check with the person in charge of your API key to check the key's active state or its start and finish active dates. |
apiKeyNoGroupPermission |
Access denied. Your API key does not have permission to access the group ID. |
incorrectUrl |
The requested URL does not exist. See https://www.classmarker.com/online-testing/api/developers/ for more information. Possible issues are: incorrect URL, incorrect ID used, incorrect HTTP method used. |
incorrectUrlVersionNumber |
The requested URL version number is incorrect or missing. See https://www.classmarker.com/online-testing/api/developers/ for more information. |
incorrectUrlId |
A requested URL ID is incorrect or missing. See https://www.classmarker.com/online-testing/api/developers/ for more information. |
incorrectRequestMethod |
The request method GET is incorrect for this action. See https://www.classmarker.com/online-testing/api/developers/ for more information. |
rateLimitExceeded |
You have reached the rate limit of 30 requests per hour. You can next make a request after the UNIX epoch timestamp value set in: next_request_after . |
timeStampOutOfRange |
Access denied. Timestamp issue. Recalculate the digital signature with each call. (There is a 5-minute window of time variance allowed.) Use seconds since the UNIX Epoch, not milliseconds. Make sure the server calling our service is in sync with an atomic clock. |
finishedAfterTimestampTooEarly |
Your finishedAfterTimestamp is too early: it can only be within the last 3 months. Contact us to activate a 7 day period to download all your results. |
offlineMaintenance |
Access denied. ClassMarker is currently down for maintenance. Check https://www.classmarker.com/msg/ for more details. |
noApiKeyExists |
Access denied. No API key exists. |
accountNotUpgraded |
Access denied. The ClassMarker account is not currently upgraded. Upgrade for API access. |
internalError100 |
Internal error. Contact ClassMarker with API Error code 100 if error persists. |
internalError101 |
Internal database error. Contact ClassMarker with API Error code 101 if error persists. |
invalidJson |
Invalid JSON. Check your payload. |
NotAllowedActionForQuestionType |
This operation is not supported this question type. |
payloadValidationError |
The payload has invalid data. |
requestParamValidationError |
The request parameter has invalid data. |
custom_error |
A custom message will display applicable to the action taken. |