AI Generation API Reference
Base path: /api/ai
All AI endpoints require JWT authentication (Authorization: Bearer <token>) and are subject to per-user usage limits enforced by the subscription service. When a limit is exceeded the API returns 429 Too Many Requests. Unauthenticated requests receive 401.
Table of Contents
- AI Provider Chain
- Endpoints
- GET /providers
- POST /generate
- POST /generate-h5p
- POST /generate-question-set
- POST /generate-image
- POST /translate
- POST /improve
- POST /analyze
- POST /suggest
- POST /chat
- POST /generate-differentiated
- POST /generate-bulk
- POST /recommend
- POST /generate-from-document
- POST /generate-from-url
- POST /generate-from-video
- POST /generate-from-image
- POST /remix-content
- GET /remix-options/:contentType
- POST /generate-scenario
- POST /combine-question-set
- GET /content-type-registry
- POST /stock-images/search
- POST /stock-images/download
- GET /stock-images/status
- Supported H5P Content Types
- Difficulty Levels
- Bloom's Taxonomy Levels
- Curriculum Context
- Quality Critic Service
- Image Generation Styles
AI Provider Chain
Creatiq uses a multi-provider architecture with automatic fallback. When the preferred provider is unavailable, the service tries the next provider in priority order.
| Priority | Provider | Model | Timeout | Env Variable |
|---|---|---|---|---|
| 1 (primary) | Google Gemini | gemini-2.5-flash | 30 s | GEMINI_API_KEY |
| 2 (fallback) | Anthropic Claude | claude-sonnet-4-20250514 | 30 s | ANTHROPIC_API_KEY |
| 3 (fallback) | OpenAI | gpt-4o | 30 s | OPENAI_API_KEY |
Additional specialized providers:
| Provider | Model | Purpose | Timeout |
|---|---|---|---|
| Gemini Image | gemini-2.5-flash-image | AI image generation | 60 s |
| Gemini Multimodal | gemini-2.5-flash / gemini-2.5-pro (large files) | PDF, image, video analysis | 60 s |
| Pexels | Pexels API v1 | Stock image search | 10 s |
The default provider can be overridden globally with AI_DEFAULT_PROVIDER env variable or per-request with the provider field. The maximum token output is configurable via AI_MAX_TOKENS (default: 4096).
Fallback behavior: If the requested provider is unavailable, the service iterates through the chain (gemini -> claude -> openai) until an available provider is found. If none is available, the request fails with an error.
Endpoints
GET /providers
Returns the status of all configured AI providers.
Authentication: None required.
Response:
{
"success": true,
"data": [
{ "type": "gemini", "available": true, "model": "gemini-2.5-flash" },
{ "type": "claude", "available": true, "model": "claude-sonnet-4-20250514" },
{ "type": "openai", "available": false }
]
}
POST /generate
Generate raw educational content using AI. Returns the AI result in its native format (not H5P-wrapped).
Authentication: Required. Rate limit: Per-user subscription limit.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Content type slug (see Supported H5P Content Types) |
input.text | string | Yes | Topic or source text |
input.language | string | No | ISO language code (default: en) |
input.count | number | No | Number of items to generate, 1-50 (default: 5) |
input.difficulty | string | No | easy, medium, hard (default: medium) |
input.customInstructions | string | No | Additional instructions for the AI (max 1000 chars) |
input.bloomsTarget | string | No | Target Bloom's level: remember, understand, apply, analyze, evaluate, create |
provider | string | No | Force a specific provider: gemini, claude, openai |
curriculum | object | No | Curriculum context |
Example request:
{
"type": "multiple-choice",
"input": {
"text": "The French Revolution and its impact on European politics",
"language": "en",
"count": 5,
"difficulty": "medium"
}
}
Response:
{
"success": true,
"data": {
"result": {
"questions": [
{
"question": "What event is considered the starting point of the French Revolution?",
"options": ["Storming of the Bastille", "Execution of Louis XVI", "Tennis Court Oath", "Reign of Terror"],
"correctIndex": 0,
"explanation": "The Storming of the Bastille on July 14, 1789 is widely regarded as the symbolic start."
}
]
},
"metadata": {
"provider": "gemini",
"model": "gemini-2.5-flash",
"processingTime": 2340
}
}
}
POST /generate-h5p
Generate AI content and convert it to H5P-ready parameters. This is the primary endpoint for creating content that can be directly saved as an H5P activity.
Authentication: Required. Rate limit: Per-user subscription limit.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Content type slug |
input.text | string | Yes | Topic or source text |
input.language | string | No | ISO language code (default: en) |
input.count | number | No | Number of items, 1-50 (default: 5) |
input.difficulty | string | No | easy, medium, hard (default: medium) |
input.customInstructions | string | No | Additional instructions (max 1000 chars) |
input.bloomsTarget | string | No | Target Bloom's taxonomy level |
provider | string | No | Provider override |
options | object | No | H5P-specific options (varies by content type) |
bloomsCritique | boolean | No | Run quality critique on generated content |
curriculum | object | No | Curriculum context |
Special behavior for branching-scenario: When type is branching-scenario, the endpoint delegates to the dedicated scenario generator which produces a decision tree with character profiles.
Image enrichment: Content types that support images (e.g., flashcards, dialog-cards) are automatically enriched with AI-generated images when available.
Example request:
{
"type": "flashcards",
"input": {
"text": "Solar system planets and their characteristics",
"language": "en",
"count": 8,
"difficulty": "easy"
},
"bloomsCritique": true
}
Response:
{
"success": true,
"data": {
"h5p": {
"library": "H5P.Flashcards 1.7",
"params": { "...H5P params ready to save..." }
},
"aiResult": { "...raw AI output..." },
"metadata": {
"provider": "gemini",
"model": "gemini-2.5-flash",
"processingTime": 3120
},
"bloomsReport": {
"overallScore": 72,
"bloomsDistribution": { "remember": 60, "understand": 30, "apply": 10, "analyze": 0, "evaluate": 0, "create": 0 },
"suggestions": ["Add more higher-order thinking questions"]
}
}
}
POST /generate-question-set
Generate multiple question types and assemble them into an H5P Question Set (quiz).
Authentication: Required. Rate limit: Per-user subscription limit.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
input.text | string | Yes | Topic or source text |
input.language | string | No | ISO language code (default: en) |
input.count | number | No | Total questions, 1-50 (default: 10) |
input.difficulty | string | No | easy, medium, hard (default: medium) |
questionTypes | string[] | No | Question types to include (default: ["multiple-choice", "true-false"]) |
provider | string | No | Provider override |
curriculum | object | No | Curriculum context |
options.introPage | boolean | No | Show introduction page |
options.introText | string | No | Introduction page text |
options.passPercentage | number | No | Pass threshold, 0-100 (default: 50) |
options.progressType | string | No | dots or textual (default: dots) |
Supported question types for Question Set: multiple-choice, true-false, fill-blanks, drag-words, mark-the-words, single-choice-set
Example request:
{
"input": {
"text": "Cell biology fundamentals",
"count": 10,
"difficulty": "medium"
},
"questionTypes": ["multiple-choice", "true-false", "fill-blanks"],
"options": {
"passPercentage": 70,
"progressType": "dots"
}
}
Response:
{
"success": true,
"data": {
"h5p": {
"library": "H5P.QuestionSet 1.20",
"params": { "...assembled question set params..." }
},
"questionCount": 10
}
}
POST /generate-image
Generate educational images using Google Gemini's image generation model.
Authentication: None required (endpoint-level). Rate limit: Standard.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | Image description |
style | string | No | Image style (see Image Generation Styles) |
contentType | string | No | H5P content type context for better results |
Example request:
{
"prompt": "Diagram of the water cycle showing evaporation, condensation, and precipitation",
"style": "diagram",
"contentType": "flashcards"
}
Response:
{
"success": true,
"data": {
"image": "<base64-encoded image data>",
"mimeType": "image/png",
"prompt": "Create a clear educational diagram with labels for educational purposes..."
}
}
Error (503): Returned when GEMINI_API_KEY is not configured.
POST /translate
Translate H5P content parameters from one language to another. Preserves the H5P parameter structure while translating all text fields.
Authentication: Required. Rate limit: Standard.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
content | object | Yes | H5P content parameters to translate |
sourceLanguage | string | Yes | Source language code (e.g., en) |
targetLanguage | string | Yes | Target language code (e.g., fr) |
provider | string | No | Provider override |
Example request:
{
"content": {
"question": "What is the capital of France?",
"answers": [
{ "text": "Paris", "correct": true },
{ "text": "London", "correct": false }
]
},
"sourceLanguage": "en",
"targetLanguage": "tr"
}
Response:
{
"success": true,
"data": {
"content": {
"question": "Fransa'nin baskenti neresidir?",
"answers": [
{ "text": "Paris", "correct": true },
{ "text": "Londra", "correct": false }
]
},
"metadata": {
"provider": "gemini",
"model": "gemini-2.5-flash",
"processingTime": 1580
}
}
}
POST /improve
Improve existing H5P content using AI. Supports multiple improvement dimensions.
Authentication: Required. Rate limit: Standard.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
content | object | Yes | H5P content parameters to improve |
improvementType | string | Yes | Type of improvement |
provider | string | No | Provider override |
language | string | No | Content language (default: en) |
curriculum | object | No | Curriculum context |
Improvement types:
| Type | Description |
|---|---|
grammar | Fix grammar and spelling errors |
clarity | Improve question/text clarity |
difficulty | Adjust difficulty level |
explanations | Add or improve explanations |
distractors | Improve distractor quality in MC questions |
feedback | Add or improve learner feedback |
accessibility | Improve accessibility of content |
Response:
{
"success": true,
"data": {
"improvedContent": { "...improved content..." },
"metadata": { "provider": "gemini", "model": "gemini-2.5-flash", "processingTime": 2100 }
}
}
POST /analyze
Analyze H5P content and provide pedagogical insights.
Authentication: Required. Rate limit: Standard.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
content | object | Yes | H5P content parameters to analyze |
analysisType | string | Yes | Type of analysis |
provider | string | No | Provider override |
language | string | No | Content language (default: en) |
curriculum | object | No | Curriculum context |
Analysis types:
| Type | Description |
|---|---|
learning-objectives | Identify learning objectives addressed |
bloom-taxonomy | Classify by Bloom's taxonomy levels |
difficulty-analysis | Analyze difficulty distribution |
coverage | Assess topic coverage completeness |
quality | Overall quality assessment |
Response:
{
"success": true,
"data": {
"analysis": { "...analysis results..." },
"metadata": { "provider": "gemini", "model": "gemini-2.5-flash", "processingTime": 1890 }
}
}
POST /suggest
Get AI-powered suggestions for improving existing content.
Authentication: Required. Rate limit: Standard.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
content | object | Yes | H5P content parameters |
suggestionType | string | Yes | accessibility, pedagogy, or engagement |
provider | string | No | Provider override |
language | string | No | Content language (default: en) |
curriculum | object | No | Curriculum context |
Suggestion types:
| Type | Description |
|---|---|
accessibility | WCAG compliance and accessibility improvements |
pedagogy | Pedagogical best practices and learning design |
engagement | Student engagement and interactivity improvements |
POST /chat
Conversational AI interface for content generation. Accepts natural language messages and automatically detects the user's intent to generate appropriate H5P content.
Authentication: Required. Rate limit: Per-user subscription limit.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
message | string | Yes | User's natural language message |
context.preferences.language | string | No | Preferred language (default: en) |
context.preferences.difficulty | string | No | easy, medium, hard (default: medium) |
context.curriculum | object | No | Curriculum context |
Intent detection: The system parses the message to detect:
- Content type (e.g., "quiz" ->
multiple-choice, "flashcards" ->flashcards) - Topic (extracted from message context)
- Count (if specified, e.g., "10 questions")
If intent is detected, content is generated and returned with H5P parameters. If no intent is detected, the system returns helpful suggestions.
Example request:
{
"message": "Create a quiz about photosynthesis with 5 questions",
"context": {
"preferences": { "language": "en", "difficulty": "medium" }
}
}
Response (content generated):
{
"success": true,
"data": {
"message": "I've created a multiple-choice quiz about photosynthesis!",
"h5pContent": {
"library": "H5P.MultiChoice 1.16",
"params": { "..." }
},
"suggestions": [
"Create flashcards about photosynthesis",
"Generate a fill-in-the-blanks exercise",
"Create a crossword puzzle"
],
"metadata": { "provider": "gemini", "model": "gemini-2.5-flash", "processingTime": 2500 }
}
}
Response (no intent detected):
{
"success": true,
"data": {
"message": "I can help you create educational content! Try one of these:",
"h5pContent": null,
"suggestions": [
"Create a quiz about [topic]",
"Make flashcards for [topic]",
"Generate a crossword about [topic]",
"Create a timeline of [topic]"
]
}
}
POST /generate-differentiated
Generate the same content at three difficulty levels (beginner, intermediate, advanced) in parallel.
Authentication: Required. Rate limit: Per-user subscription limit. Feature gate: differentiation
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Content type slug |
input | string | Yes | Topic text |
language | string | No | ISO language code (default: en) |
count | number | No | Items per level, 1-20 (default: 5) |
curriculum | object | No | Curriculum context |
Response:
{
"success": true,
"data": {
"beginner": {
"kind": "single",
"library": "H5P.MultiChoice 1.16",
"params": { "..." },
"metadata": { "title": "multiple-choice -- beginner", "difficulty": "easy", "..." }
},
"intermediate": {
"kind": "single",
"library": "H5P.MultiChoice 1.16",
"params": { "..." },
"metadata": { "title": "multiple-choice -- intermediate", "difficulty": "medium", "..." }
},
"advanced": {
"kind": "single",
"library": "H5P.MultiChoice 1.16",
"params": { "..." },
"metadata": { "title": "multiple-choice -- advanced", "difficulty": "hard", "..." }
}
}
}
POST /generate-bulk
Generate a large batch of questions with deduplication, quality filtering, and optional Bloom's taxonomy distribution.
Authentication: Required. Rate limit: Per-user subscription limit. Feature gate: bulk-generation
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
topic | string | Yes | Topic text (max 2000 chars) |
totalCount | number | Yes | Total items to return, 1-50 |
types | string[] | Yes | Content type slugs to generate |
bloomsDistribution | object | No | Target distribution by Bloom's level, values 0-100 |
language | string | No | ISO language code (default: en) |
difficulty | string | No | easy, medium, hard, or mixed (default: mixed) |
deduplication | boolean | No | Enable deduplication (default: true) |
curriculum | object | No | Curriculum context |
Pipeline:
- Generate 2x the requested count (safety margin), capped at 100 items
- Run across content types with max 5 concurrent AI calls per batch
- Deduplicate using Levenshtein similarity (threshold: 0.85)
- Filter items below minimum quality score (50)
- Select final items matching the requested Bloom's distribution
Example request:
{
"topic": "World War II key events and figures",
"totalCount": 20,
"types": ["multiple-choice", "true-false", "fill-blanks"],
"bloomsDistribution": {
"remember": 20,
"understand": 30,
"apply": 30,
"analyze": 20
},
"difficulty": "mixed",
"deduplication": true
}
Response:
{
"success": true,
"data": {
"questions": [
{
"content": {
"kind": "single",
"library": "H5P.MultiChoice 1.16",
"params": { "..." },
"metadata": { "title": "...", "contentType": "multiple-choice", "..." }
},
"qualityScore": 78,
"bloomsLevel": "understand"
}
],
"stats": {
"generated": 42,
"deduplicated": 5,
"qualityFiltered": 2,
"returned": 20
}
}
}
POST /recommend
Generate AI-powered content recommendations based on student or class performance data.
Authentication: Required. Rate limit: Standard. Feature gate: ai-recommendation
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
targetType | string | Yes | student or class |
targetId | string | Yes | Student or class identifier |
count | number | No | Number of recommendations, 1-10 |
language | string | No | ISO language code (default: en) |
curriculum | object | No | Curriculum context |
POST /generate-from-document
Upload a PDF or TXT file and generate a lesson bundle with multiple H5P content types.
Authentication: Required. Rate limit: Per-user subscription limit. Feature gate: pdf-to-h5p
Content-Type: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
file | File | Yes | PDF or TXT file (max 20 MB) |
targetTypes | string[] (JSON) | No | Content types to generate (default: multiple-choice, flashcards, summary, fill-blanks, true-false) |
language | string | No | Override detected language |
count | number | No | Items per type, 1-20 (default: 5) |
curriculum | object (JSON) | No | Curriculum context |
Allowed MIME types: application/pdf, text/plain
Response:
{
"success": true,
"data": {
"bundle": {
"kind": "bundle",
"title": "...",
"items": [ "...H5P items..." ],
"bloomsCoverage": { "..." },
"estimatedDuration": 15
},
"qualityReport": { "overallScore": 75, "..." },
"processingTime": 12500
}
}
POST /generate-from-url
Extract content from a web page URL and generate H5P content.
Authentication: Required. Rate limit: Per-user subscription limit. Feature gate: url-to-h5p
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Valid URL to extract content from |
targetTypes | string[] | No | Content types to generate |
language | string | No | Override detected language |
count | number | No | Items per type, 1-20 (default: 5) |
curriculum | object | No | Curriculum context |
Response:
{
"success": true,
"data": {
"items": [ "...SingleH5POutput items..." ],
"suggestedOrder": ["0", "1", "2"],
"metadata": { "url": "https://...", "wordCount": 2500 }
}
}
POST /generate-from-video
Analyze a YouTube video and generate Interactive Video question points.
Authentication: Required. Rate limit: Per-user subscription limit. Feature gate: video-to-h5p
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
videoUrl | string | Yes | YouTube video URL |
language | string | No | ISO language code (default: en) |
questionsPerMinute | number | No | Density of questions, 0.5-3 (default: 1) |
estimatedDurationMinutes | number | No | Estimated video length, 1-180 |
curriculum | object | No | Curriculum context |
Response:
{
"success": true,
"data": {
"videoId": "abc123",
"title": "Video Title",
"segments": [ "..." ],
"timestamps": [ "..." ],
"extractedText": "...",
"totalSegments": 5,
"processingTime": 8500
}
}
POST /generate-from-image
Upload an image and generate H5P Image Hotspots content with AI-detected regions.
Authentication: Required. Rate limit: Per-user subscription limit. Feature gate: image-hotspot
Content-Type: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
file | File | Yes | Image file (max 10 MB) |
hotspotCount | number | No | Number of hotspots, 1-15 |
language | string | No | ISO language code (default: en) |
detailLevel | string | No | brief or detailed (default: detailed) |
curriculum | object | No | Curriculum context |
Allowed image types: image/jpeg, image/png, image/webp
Response:
{
"success": true,
"data": {
"h5p": {
"library": "H5P.ImageHotspots 1.10",
"params": { "..." }
},
"detectedRegions": [
{ "x": 25, "y": 40, "label": "Mitochondria", "description": "The powerhouse of the cell..." }
],
"imageDescription": "A labeled diagram of an animal cell...",
"processingTime": 5200
}
}
POST /remix-content
Convert existing H5P content from one format to another using AI.
Authentication: Required. Rate limit: Per-user subscription limit. Feature gate: content-remixer
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
contentId | string | Yes | Source content ID |
targetType | string | Yes | Target content type slug |
language | string | No | Content language |
curriculum | object | No | Curriculum context |
Response:
{
"success": true,
"data": {
"h5p": { "library": "H5P.Flashcards 1.7", "params": { "..." } },
"sourceType": "multiple-choice",
"targetType": "flashcards",
"conversionNotes": "Converted 5 MC questions to flashcard format",
"processingTime": 3200
}
}
GET /remix-options/:contentType
Get available conversion targets for a given content type.
Authentication: None required.
Path parameters:
| Parameter | Description |
|---|---|
contentType | Source content type slug |
Response:
{
"success": true,
"data": {
"sourceType": "multiple-choice",
"availableTargets": ["flashcards", "true-false", "fill-blanks", "drag-words"]
}
}
POST /generate-scenario
Generate a branching scenario with a decision tree, character profiles, and H5P parameters.
Authentication: Required. Rate limit: Per-user subscription limit. Feature gate: branching-scenario
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
topic | string | Yes | Scenario topic (max 2000 chars) |
context | string | No | Additional context (max 2000 chars) |
characters | string[] | No | Character names (max 5, AI generates if omitted) |
outcomes | string[] | Yes | Possible endings, 2-5 required |
language | string | No | ISO language code (default: en) |
complexity | string | Yes | simple (3-4 nodes), standard (5-7 nodes), complex (8-12 nodes) |
curriculum | object | No | Curriculum context |
Example request:
{
"topic": "Ethical decision making in a business context",
"outcomes": [
"Best outcome: Company maintains integrity and profits",
"Good outcome: Issue resolved with minor consequences",
"Poor outcome: Company faces legal and reputational damage"
],
"complexity": "standard",
"language": "en"
}
Response:
{
"success": true,
"data": {
"h5p": {
"library": "H5P.BranchingScenario 1.8",
"params": { "..." }
},
"decisionTree": [
{ "id": 0, "text": "You discover...", "choices": [...], "isEndNode": false }
],
"characterProfiles": [
{ "name": "Alex Chen", "role": "CEO", "motivation": "Maintain company reputation" }
],
"processingTime": 8200
}
}
POST /combine-question-set
Assemble existing H5P content items into a single Question Set without AI generation.
Authentication: Required. Rate limit: Per-user subscription limit.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
contentIds | string[] | Yes | Content IDs to combine, 1-50 |
title | string | No | Quiz title (max 500 chars) |
options.introPage | boolean | No | Show introduction page |
options.introText | string | No | Introduction text (max 1000 chars) |
options.passPercentage | number | No | Pass threshold, 0-100 |
options.progressType | string | No | dots or textual |
options.randomizeOrder | boolean | No | Randomize question order |
Compatible H5P libraries: H5P.MultiChoice, H5P.TrueFalse, H5P.Blanks, H5P.DragText, H5P.MarkTheWords, H5P.SingleChoiceSet
Response:
{
"success": true,
"data": {
"library": "H5P.QuestionSet 1.20",
"params": { "..." },
"title": "My Quiz",
"questionCount": 8
}
}
GET /content-type-registry
Returns all H5P content types supported for AI generation, grouped by pedagogy category.
Authentication: None required.
Response:
{
"success": true,
"data": {
"categories": {
"assessment": [
{
"slug": "multiple-choice",
"displayName": "Multiple Choice",
"h5pLibrary": "H5P.MultiChoice 1.16",
"description": "Questions with multiple answer options",
"ai": { "supported": true, "inputMethods": ["text", "pdf", "url"] },
"media": { "image": "optional", "video": "optional", "audio": "none" },
"generationModes": ["single", "bulk", "differentiated"],
"requiredPlan": "free",
"defaultBloomsLevel": "understand",
"supportsQuestionSet": true
}
],
"practice": [ "..." ],
"teaching": [ "..." ],
"exploration": [ "..." ]
},
"totalTypes": 21,
"aiSupportedCount": 21
}
}
POST /stock-images/search
Search free stock images from Pexels.
Authentication: None required. Rate limit: 180 requests/hour (Pexels API).
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search query (max 200 chars) |
page | number | No | Page number, 1-100 |
perPage | number | No | Results per page, 1-80 (default: 15) |
orientation | string | No | landscape, portrait, square (default: landscape) |
size | string | No | small, medium, large (default: medium) |
language | string | No | Search locale (max 5 chars) |
contentType | string | No | H5P content type for query enhancement |
Response:
{
"success": true,
"data": {
"images": [
{
"id": 12345,
"width": 1920,
"height": 1080,
"photographer": "John Doe",
"photographerUrl": "https://www.pexels.com/@johndoe",
"alt": "Solar system illustration",
"avgColor": "#2B3E50",
"urls": {
"original": "https://...",
"large2x": "https://...",
"large": "https://...",
"medium": "https://...",
"small": "https://...",
"tiny": "https://..."
}
}
],
"totalResults": 250,
"page": 1,
"perPage": 15,
"hasMore": true
}
}
Error (503): Returned when PEXELS_API_KEY is not configured.
POST /stock-images/download
Download a stock image and save it to H5P temporary storage.
Authentication: None required.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
imageUrl | string | Yes | Direct image URL |
photographer | string | Yes | Photographer name for attribution |
photographerUrl | string | Yes | Photographer profile URL |
Response:
{
"success": true,
"data": {
"filename": "pexels-12345-abc.jpg",
"contentPath": "images/pexels-12345-abc.jpg",
"mimeType": "image/jpeg",
"photographer": "John Doe",
"photographerUrl": "https://www.pexels.com/@johndoe"
}
}
GET /stock-images/status
Check if the stock image provider (Pexels) is available.
Authentication: None required.
Response:
{
"success": true,
"data": {
"available": true,
"provider": "pexels"
}
}
Supported H5P Content Types
Assessment
| Slug | H5P Library | Display Name | Bloom's Level | Question Set | Plan | Generation Modes |
|---|---|---|---|---|---|---|
multiple-choice | H5P.MultiChoice 1.16 | Multiple Choice | understand | Yes | free | single, bulk, differentiated |
true-false | H5P.TrueFalse 1.8 | True/False | understand | Yes | free | single, bulk, differentiated |
fill-blanks | H5P.Blanks 1.14 | Fill in the Blanks | apply | Yes | free | single, bulk, differentiated |
drag-words | H5P.DragText 1.10 | Drag the Words | apply | Yes | free | single, bulk, differentiated |
single-choice-set | H5P.SingleChoiceSet 1.11 | Single Choice Set | understand | Yes | free | single, bulk, differentiated |
mark-the-words | H5P.MarkTheWords 1.11 | Mark the Words | apply | Yes | free | single, bulk, differentiated |
essay | H5P.Essay 1.5 | Essay | evaluate | No | free | single, differentiated |
question-set | H5P.QuestionSet 1.20 | Question Set | understand | No | free | single, bulk |
Practice
| Slug | H5P Library | Display Name | Bloom's Level | Question Set | Plan | Generation Modes |
|---|---|---|---|---|---|---|
flashcards | H5P.Flashcards 1.7 | Flashcards | remember | No | free | single, bulk |
dialog-cards | H5P.Dialogcards 1.9 | Dialog Cards | remember | No | free | single, bulk |
crossword | H5P.Crossword 0.5 | Crossword | apply | No | free | single, bulk |
find-the-words | H5P.FindTheWords 1.4 | Find the Words | remember | No | free | single, bulk |
sort-paragraphs | H5P.SortParagraphs 0.11 | Sort the Paragraphs | analyze | No | free | single, bulk |
arithmetic-quiz | H5P.ArithmeticQuiz 1.1 | Arithmetic Quiz | apply | No | free | single |
Teaching
| Slug | H5P Library | Display Name | Bloom's Level | Question Set | Plan | Generation Modes |
|---|---|---|---|---|---|---|
summary | H5P.Summary 1.10 | Summary | understand | No | free | single |
accordion | H5P.Accordion 1.0 | Accordion | understand | No | free | single |
timeline | H5P.Timeline 1.1 | Timeline | understand | No | free | single |
chart | H5P.Chart 1.2 | Chart | understand | No | free | single |
Exploration
| Slug | H5P Library | Display Name | Bloom's Level | Question Set | Plan | Generation Modes |
|---|---|---|---|---|---|---|
personality-quiz | H5P.PersonalityQuiz 1.0 | Personality Quiz | analyze | No | pro | single |
branching-scenario | H5P.BranchingScenario 1.8 | Branching Scenario | evaluate | No | premium | single |
image-hotspot | H5P.ImageHotspots 1.10 | Image Hotspots | understand | No | premium | single |
Input methods key:
text-- Plain text topic or descriptionpdf-- PDF/TXT document uploadurl-- Web page URL extractionimage-- Image upload (only Image Hotspots)
Difficulty Levels
All generation endpoints accept a difficulty parameter:
| Level | Description | AI Behavior |
|---|---|---|
easy | Basic recall and comprehension | Simple vocabulary, direct questions, obvious distractors |
medium | Application and understanding | Standard vocabulary, contextual questions, plausible distractors |
hard | Analysis and evaluation | Complex vocabulary, multi-step reasoning, subtle distractors |
For bulk generation, mixed randomly assigns a difficulty per item.
Bloom's Taxonomy Levels
Content can be targeted to specific cognitive levels:
| Level | Description | Default Content Types |
|---|---|---|
remember | Recall facts and basic concepts | flashcards, dialog-cards, find-the-words |
understand | Explain ideas or concepts | true-false, multiple-choice, single-choice-set, summary, accordion, timeline |
apply | Use information in new situations | fill-blanks, drag-words, mark-the-words, crossword, arithmetic-quiz |
analyze | Draw connections among ideas | chart, sort-paragraphs, image-hotspot |
evaluate | Justify a stand or decision | essay, personality-quiz |
create | Produce new or original work | branching-scenario |
Curriculum Context
All generation endpoints accept an optional curriculum object to align generated content with educational standards:
{
"curriculum": {
"frameworkCode": "CCSS",
"frameworkName": "Common Core State Standards",
"countryCode": "US",
"stageName": "Middle School",
"stageCode": "MS",
"typicalAge": "11-14",
"subjectCode": "SCI",
"subjectName": "Science",
"gradeCode": "7",
"gradeName": "Grade 7",
"topics": [
{ "code": "LS1.1", "name": "Cell Structure and Function" }
],
"objectives": [
{ "code": "NGSS-MS-LS1-1", "description": "Conduct an investigation to provide evidence that living things are made of cells" }
]
}
}
All fields are optional. When provided, the AI uses this context to generate age-appropriate, standards-aligned content.
Quality Critic Service
The quality critic service (bloomsCritique: true in /generate-h5p) provides automated analysis of AI-generated content.
Quality report fields:
| Field | Type | Description |
|---|---|---|
overallScore | number | 0-100 composite quality score |
bloomsDistribution | object | Percentage distribution across all 6 Bloom's levels |
distractorQualities | array | Per-distractor analysis for MC questions |
readability | object | Flesch-Kincaid score, grade level, target audience |
feedbackCoverage | number | 0-1 ratio of questions with feedback |
suggestions | string[] | Actionable improvement recommendations |
Scoring weights:
- Bloom's distribution: 30%
- Distractor quality: 30%
- Readability: 20%
- Feedback coverage: 20%
Quality thresholds:
| Threshold | Value |
|---|---|
| Minimum overall score | 60 |
| Minimum distractor score | 50 |
| Maximum revision iterations | 2 |
| Minimum feedback coverage | 70% |
Additional quality functions:
classifyBlooms(question)-- Classify a single question by Bloom's levelscoreDistractors(question, distractors)-- Score MC distractor qualityreviseQuestion(question, currentLevel, targetLevel)-- AI-revise to target Bloom's level
Image Generation Styles
The /generate-image endpoint supports four styles:
| Style | Description |
|---|---|
realistic | Photorealistic images |
illustration | Clean, professional illustrations (default) |
diagram | Educational diagrams with labels |
cartoon | Friendly, colorful cartoon-style images |
All generated images are:
- Suitable for all ages
- Clear and easy to understand
- Returned as base64-encoded data with MIME type
- Generated by
gemini-2.5-flash-imagemodel with a 60-second timeout
Error Responses
All endpoints return errors in the standard format:
{
"success": false,
"error": "Human-readable error message"
}
| Status | Meaning |
|---|---|
400 | Validation error or invalid parameters |
401 | Authentication required |
404 | Content not found |
429 | AI usage limit exceeded |
500 | Internal server error / AI generation failure |
503 | Service unavailable (e.g., missing API key for required provider) |