Marketplace API Reference
Base path: /api/marketplace
The marketplace enables public content discovery, filtering, and cloning. Teachers can browse content published by other users, inspect curriculum metadata and quality scores, and clone content into their own library.
Endpoints
GET /api/marketplace/public-contents/facets
Return distinct filter values available across all public content. Use these values to populate filter dropdowns in the UI.
Auth: Authenticated user (JWT, authMiddleware)
Response (200):
{
"success": true,
"data": {
"subjects": ["Mathematics", "Science", "English"],
"grades": ["5th Grade", "8th Grade", "10th Grade"],
"difficulties": ["easy", "medium", "hard"],
"languages": ["en", "tr", "fr"],
"frameworks": ["MEB 2024", "Common Core"]
}
}
All arrays are sorted alphabetically and have null/empty values filtered out.
Errors:
| Status | Error | Cause |
|---|---|---|
| 500 | Failed to load filters | Internal error |
GET /api/marketplace/public-contents
Browse public content from other users with optional search and curriculum filters. Results are enriched with H5P metadata, curriculum data, quality scores, and author information.
Auth: Authenticated user (JWT, authMiddleware)
Query Parameters:
| Param | Type | Default | Constraints |
|---|---|---|---|
search | string | -- | max 500 chars, free-text search |
contentType | string | -- | max 100 chars, H5P content type filter |
frameworkCode | string | -- | max 50 chars |
gradeCode | string | -- | max 50 chars |
subjectCode | string | -- | max 100 chars |
difficulty | enum | -- | easy, medium, hard |
language | string | -- | max 10 chars |
sortBy | enum | newest | newest, popular, quality |
offset | integer | 0 | min 0 |
limit | integer | 20 | 1-50 |
Response (200):
{
"success": true,
"data": [
{
"id": "42",
"title": "Quadratic Equations Quiz",
"mainLibrary": "H5P.QuestionSet",
"contentTypeSlug": "question-set",
"authorId": "uuid",
"authorName": "Teacher A",
"viewCount": 128,
"publishedAt": "2025-01-10T08:00:00.000Z",
"curriculum": {
"frameworkName": "MEB 2024",
"stageName": "Middle School",
"gradeName": "8th Grade",
"subjectName": "Mathematics",
"topicNames": ["Equations"],
"difficulty": "medium",
"language": "tr"
},
"quality": {
"overallScore": 92,
"dimensions": {}
}
}
],
"total": 47
}
Enrichment details:
- Content owned by the authenticated user is excluded from results.
- Content that cannot be read from H5P storage is silently excluded.
curriculumisnullif the content has no curriculum metadata attached.qualityisnullif no quality assessment has been performed.authorNamefalls back to"Anonymous"if the author record is missing.
Errors:
| Status | Error | Cause |
|---|---|---|
| 400 | Validation error: ... | Invalid query parameters |
| 500 | Failed to list public contents | Internal error |
POST /api/marketplace/public-contents/:contentId/clone
Clone a public content item into the authenticated user's own library. Creates a full copy of the H5P content, ownership record, and curriculum metadata.
Auth: Teacher (JWT, teacherAuthMiddleware)
URL Parameters:
| Param | Type | Description |
|---|---|---|
contentId | string | H5P content ID to clone |
Request Body: None.
Process:
- Verifies the source content exists and has
visibility: public. - Checks the user's subscription quota (
contentlimit). - Copies H5P content (parameters + metadata) via
h5pEditor.saveOrUpdateContent. - Records ownership for the new content as
private. - Copies curriculum metadata from the source content to the clone.
- Increments the user's
contentusage counter. - Increments the source content's
viewCount(fire-and-forget).
Response (201):
{
"success": true,
"data": {
"contentId": "99"
}
}
Errors:
| Status | Error | Cause |
|---|---|---|
| 401 | User not found | JWT valid but user not in DB |
| 403 | Content limit reached | User's subscription content quota exceeded |
| 404 | Content not found or not public | Content ID does not exist or is not public |
| 500 | Failed to clone content | Internal error |
Referral System
The marketplace includes a referral service (referralService) for user acquisition. While the referral endpoints are defined in the referral service layer, they share the marketplace domain.
Referral Types
interface Referral {
id: string;
referrerId: string;
referredEmail: string;
referralCode: string;
status: "pending" | "converted" | "expired";
rewardType: "extra_credits" | "plan_discount";
createdAt: Date;
convertedAt: Date | null;
}
Referral Constants
| Constant | Value | Description |
|---|---|---|
PLATFORM_COMMISSION_RATE | 0.3 | Platform commission rate (30%) |
DEFAULT_CURRENCY | usd | Default currency |
DEFAULT_PAGE_LIMIT | 20 | Default pagination limit |
MAX_PAGE_LIMIT | 100 | Maximum pagination limit |
MIN_RATING | 1 | Minimum review rating |
MAX_RATING | 5 | Maximum review rating |
REFERRAL_CODE_LENGTH | 8 | Generated referral code length (hex characters) |
REFERRAL_EXTRA_CREDITS | 5 | AI generation credits awarded per successful referral |
Referral Flow
- Generate link: Each user gets a unique referral code stored in
creatiq_users.referral_code. The link format is{APP_URL}/login?ref={CODE}. - Convert: When a new user signs up via a referral link, the referral is recorded as
converted. The referrer receivesREFERRAL_EXTRA_CREDITS(5) additional AI generation credits. - Stats: Referrers can view their total, converted, and pending referral counts along with total rewards earned.
Data Model
Public Content List Item
| Field | Type | Description |
|---|---|---|
id | string | H5P content ID |
title | string | Content title from H5P metadata |
mainLibrary | string | H5P library name (e.g., H5P.QuestionSet) |
contentTypeSlug | string | Slugified content type (e.g., question-set) |
authorId | string | Author's user ID |
authorName | string | Author's display name |
viewCount | integer | Number of views/clones |
publishedAt | ISO 8601 | When the content was published |
curriculum | object or null | Curriculum metadata (see curriculum API) |
quality | object or null | Quality assessment summary |