Serve Module Quiz
curl --request GET \
--url https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}B2B Learn
Serve Module Quiz
Serve module-quiz questions, creating or reusing the attempt server-side.
Auth: portal API key + X-Learner-Email header. 404 “Not enrolled in this course” if the header learner has no enrollment row for course_id.
Attempt lifecycle (server-owned, no client input selects questions):
- If the learner has an in-progress attempt for this module (finished_at IS NULL), this call is STICKY: it returns the exact same attempt_id + questions that were served when the attempt was created, so refreshing the page never reshuffles an in-flight quiz.
- If there is no in-progress attempt (first attempt, or the previous attempt for this module was already graded), a NEW attempt is created and stratified-random questions are drawn per difficulty tier, EXCLUDING every question_version_id the learner has already been served for this module — so a retry after a finished attempt always draws a fresh, previously-unseen set (falls back to repeats only once the pool of unseen questions is exhausted).
Returns 200 . questions is
[] with every answer-key field
(correct/key_points/rubric) stripped; id is str(question_version_id) and
must be echoed back as the answers’ question_id on grade. 404
quiz_not_available if the module has no question pool.
GET
/
api
/
v1
/
learn
/
courses
/
{course_id}
/
quiz
/
modules
/
{module_num}
Serve Module Quiz
curl --request GET \
--url https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.myustadia.com/api/v1/learn/courses/{course_id}/quiz/modules/{module_num}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Response
Successful Response