Skip to content
StudyFetch API

API Documentation

Practice Test

Overview

The Practice Test component creates comprehensive tests from your study materials with multiple question types, difficulty levels, and customizable settings. Perfect for exam preparation and knowledge assessment.

Questions are generated in the background after the component is created. Learners take the test in the embed, which shows generation progress while questions are being written and auto-submits when the time limit runs out.

Creating a Practice Test Component

JavaScript

import StudyfetchSDK from '@studyfetch/sdk';

const client = new StudyfetchSDK({
  apiKey: 'your-api-key',
  baseURL: 'https://studyfetchapi.com',
});

const testComponent = await client.v1.components.create({
  name: 'Biology Midterm Practice',
  type: 'practice_test',
  config: {
    materials: ['mat-123', 'mat-456'],
    folders: ['folder-789'],
    questionTypes: ['multiplechoice', 'truefalse', 'shortanswer'],
    questionsPerTest: 25,
    difficulty: 'medium',
    timeLimit: 45,
    randomizeQuestions: true,
    passingScore: 75,
  },
});

console.log('Practice test component created:', testComponent._id, testComponent.componentId);

Python

from studyfetch_sdk import StudyfetchSDK

client = StudyfetchSDK(
    api_key="your-api-key",
    base_url="https://studyfetchapi.com",
)

test_component = client.v1.components.create(
    name="Biology Midterm Practice",
    type="practice_test",
    config={
        "materials": ["mat-123", "mat-456"],
        "folders": ["folder-789"],
        "question_types": ["multiplechoice", "truefalse", "shortanswer"],
        "questions_per_test": 25,
        "difficulty": "medium",
        "time_limit": 45,
        "randomize_questions": True,
        "passing_score": 75,
    },
)

print(f"Practice test component created: {test_component.api_id} {test_component.component_id}")

Java

import com.studyfetch.javasdk.client.StudyfetchSdkClient;
import com.studyfetch.javasdk.client.okhttp.StudyfetchSdkOkHttpClient;
import com.studyfetch.javasdk.models.v1.components.ComponentResponse;
import com.studyfetch.javasdk.models.v1.components.ComponentCreateParams;

import java.util.List;

public class CreatePracticeTestComponent {
    public static void main(String[] args) {
        StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
            .fromEnv()
            .baseUrl("https://studyfetchapi.com")
            .build();

        ComponentCreateParams params = ComponentCreateParams.builder()
            .name("Biology Midterm Practice")
            .type(ComponentCreateParams.Type.PRACTICE_TEST)
            .config(ComponentCreateParams.Config.PracticeTestConfigDto.builder()
                .materials(List.of("mat-123", "mat-456"))
                .folders(List.of("folder-789"))
                .questionTypes(List.of("multiplechoice", "truefalse", "shortanswer"))
                .questionsPerTest(25)
                .difficulty(ComponentCreateParams.Config.PracticeTestConfigDto.Difficulty.MEDIUM)
                .timeLimit(45)
                .randomizeQuestions(true)
                .passingScore(75)
                .build())
            .build();

        ComponentResponse component = client.v1().components().create(params);
        System.out.println("Practice test component created: " + component._id());
    }
}

C#

using StudyfetchSDK;
using StudyfetchSDK.Models.V1.Components;
using StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.PracticeTestConfigDtoProperties;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class CreatePracticeTestComponent
{
    public static async Task CreatePracticeTest()
    {
        var client = new StudyfetchSDKClient()
        {
            APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
            BaseUrl = new Uri("https://studyfetchapi.com")
        };

        var testComponent = await client.V1.Components.Create(new()
        {
            Name = "Biology Midterm Practice",
            Type = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.Type.PracticeTest,
            Config = new StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.PracticeTestConfigDto()
            {
                Materials = new List<string> { "mat-123", "mat-456" },
                Folders = new List<string> { "folder-789" },
                QuestionTypes = new List<string> { "multiplechoice", "truefalse", "shortanswer" },
                QuestionsPerTest = 25,
                Difficulty = Difficulty.Medium,
                TimeLimit = 45,
                RandomizeQuestions = true,
                PassingScore = 75,
            }
        });

        Console.WriteLine($"Practice test component created: {testComponent._ID}");
    }
}

Configuration Parameters

name

string · required

Name of the practice test component

type

string · required

Must be "practice_test"

config

object · required

Practice test configuration object. questionTypes is required, and you need at least one material or folder. Unknown keys are rejected with 400.

Configuration Properties

These properties go inside config.

questionTypes

array · required

Types of questions to include. At least one:

  • multiplechoice - Multiple choice questions
  • truefalse - True/false questions
  • shortanswer - Short answer questions
  • frq - Free-response questions
  • fillinblank - Fill in the blank questions

Values are case-insensitive and underscores are ignored, so multiple_choice also works. Questions are split evenly across the types you choose.

materials

array

Material IDs to generate questions from. Provide materials, folders, or both.

folders

array

Folder IDs whose materials questions are generated from

questionsPerTest

number · default: 10

Number of questions per test

difficulty

string

Test difficulty level: easy, medium, hard, or mixed. When omitted, questions are generated at mixed difficulty.

timeLimit

number · default: 30

Time limit in minutes. The embed auto-submits the test when time runs out. There is no "no limit" option; 0 is treated as the default.

passingScore

number · default: 70

Minimum passing percentage (0-100) used to show a pass or fail result. 0 is treated as the default.

randomizeQuestions

boolean · default: false

Shuffle question order for each attempt

model

string · default: gpt-4o-mini-2024-07-18

AI model used to generate questions

allowRetakes

boolean

Accepted and stored, but not currently enforced; learners can always retake a test.

maxAttempts

number

Accepted and stored, but not currently enforced

showCorrectAnswers

boolean

Accepted and stored, but not currently used

showExplanations

boolean

Accepted and stored, but not currently used. Graded answers include an explanation when one is available.

randomizeAnswers

boolean

Accepted and stored, but not currently used

aiGenerationMode

string

balanced, comprehensive, focused, or adaptive. Accepted and stored, but not currently used.

questionDistribution

object

Per-type question counts (multiplechoice, truefalse, shortanswer, frq, fillinblank). Accepted and stored, but not currently used; questions are split evenly across questionTypes.

Response

{
  "_id": "6650f1c2a9b3e4d5f6a7b8c9",
  "componentId": "practice_test_V1StGXR8_Z",
  "name": "Biology Midterm Practice",
  "type": "practice_test",
  "status": "active",
  "origin": "api",
  "organization": "64f0a1b2c3d4e5f6a7b8c9d0",
  "materials": ["mat-123", "mat-456"],
  "folders": ["folder-789"],
  "config": {
    "materials": ["mat-123", "mat-456"],
    "folders": ["folder-789"],
    "questionTypes": ["multiplechoice", "truefalse", "shortanswer"],
    "questionsPerTest": 25,
    "difficulty": "medium",
    "timeLimit": 45,
    "randomizeQuestions": true,
    "passingScore": 75
  },
  "usageCount": 0,
  "createdAt": "2026-10-06T10:00:00.000Z",
  "updatedAt": "2026-10-06T10:00:00.000Z"
}

Embedding This Component

Once you've created a Practice Test component, you can embed it on your website using the embedding API. The component must be active. Attempts and results are stored per userId, so generate each learner's embed with their own userId.

Generate Embed URL

JavaScript

const embedResponse = await client.v1.components.generateEmbed(testComponent._id, {
  // User tracking
  userId: 'user-456',
  studentName: 'Jane Smith',  // Student name for display
  groupIds: ['class-101', 'class-102'],
  sessionId: 'session-789',

  // Dimensions
  width: '100%',
  height: '700px',
});

console.log(embedResponse.embedUrl);

Python

embed_response = client.v1.components.generate_embed(
    test_component.api_id,
    user_id="user-456",
    student_name="Jane Smith",  # Student name for display
    group_ids=["class-101", "class-102"],
    session_id="session-789",
    width="100%",
    height="700px",
)

print(embed_response.embed_url)

Java

import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedParams;
import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedResponse;

ComponentGenerateEmbedParams params = ComponentGenerateEmbedParams.builder()
    .id(testComponent._id())
    // User tracking
    .userId("user-456")
    .studentName("Jane Smith")  // Student name for display
    .groupIds(List.of("class-101", "class-102"))
    .sessionId("session-789")

    // Dimensions
    .width("100%")
    .height("700px")
    .build();

ComponentGenerateEmbedResponse embedResponse = client.v1().components()
    .generateEmbed(params);

System.out.println(embedResponse.embedUrl());

C#

using StudyfetchSDK;
using StudyfetchSDK.Models.V1.Components;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class GeneratePracticeTestEmbed
{
    public static async Task GenerateEmbed(string testComponentId)
    {
        var client = new StudyfetchSDKClient()
        {
            APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
            BaseUrl = new Uri("https://studyfetchapi.com")
        };

        var embedResponse = await client.V1.Components.GenerateEmbed(new()
        {
            ID = testComponentId,
            UserID = "user-456",
            StudentName = "Jane Smith",  // Student name for display
            GroupIDs = new List<string> { "class-101", "class-102" },
            SessionID = "session-789",
            Width = "100%",
            Height = "700px"
        });

        Console.WriteLine($"Embed URL: {embedResponse.EmbedURL}");
        Console.WriteLine($"Token: {embedResponse.Token}");
    }
}

The response contains embedUrl, token, expiresAt, componentId (the component's _id), componentType, and options (width and height, defaulting to 100% and 600px).

The practice test embed doesn't use any features settings, and always shows the learner's past attempts.

Embed in Your HTML

Use the embedUrl from the response as the iframe source. The host can differ per organization, so don't build the URL yourself.

<iframe
  src="EMBED_URL_FROM_RESPONSE"
  width="100%"
  height="700px"
  frameborder="0"
  style="border: 1px solid #e5e5e5; border-radius: 8px;">
</iframe>

Taking Tests from Your Server

To run tests in your own interface, send actions to POST /api/v1/components/{id}/interact, where {id} is the component's _id:

action Body fields Returns
create_test userId A new attempt: testId, test, and questions. While questions are still being generated, generating: true with progress instead.
get_test testId The attempt and its questions
submit_answer testId, questionId, answer, userId Whether the answer is correct, its grade, and an explanation
submit_test testId, answers (array of questionId and answer), userId grade, correctAnswers, totalQuestions, and per-question results
get_results testId Results of a submitted attempt
retake_test testId A fresh attempt at the same questions
list_tests userId The user's attempts

The SDKs' interact methods don't send a request body yet, so use cURL or an HTTP client.

curl -X POST "https://studyfetchapi.com/api/v1/components/6650f1c2a9b3e4d5f6a7b8c9/interact" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{ "action": "create_test", "userId": "user-456" }'

React Native

The React Native SDK (@studyfetch/react-native-sdk) renders Practice Tests natively with embed tokens instead of an iframe. Import it from @studyfetch/react-native-sdk/tests and wrap your app in EmbedTokenProvider with a getToken function that asks your backend to mint an embed token for a component.

import { EmbedTokenProvider } from '@studyfetch/react-native-sdk';
import { StudyFetchTest, useTest } from '@studyfetch/react-native-sdk/tests';

// Full test UI: questions, submission, results
<EmbedTokenProvider getToken={fetchToken}>
  <StudyFetchTest componentId="practice_test_V1StGXR8_Z" userId="user-456" />
</EmbedTokenProvider>

// Headless: build your own UI
const { questions, answers, setAnswer, submit, result, passed, retake, generating } = useTest({
  componentId: 'practice_test_V1StGXR8_Z',
  userId: 'user-456',
});
  • useTest starts an attempt automatically and polls while questions are being generated.
  • passed compares the result with the component's passingScore.