Skip to main content

Content Endpoints

Music, stories, and educational content management. Base path: /toy/content.

Content is organized in two layers:

  • Content Library (/content/library) — the unified catalog of individual content items (music tracks, story audio files). This is the primary system.
  • Legacy routes (/content/music/*, /content/story/*) — older per-type endpoints kept for compatibility.

Most read endpoints use requireFlexAuth (accepts Firebase ID token or admin custom token). Write/delete operations require admin auth.

Endpoint Summary

Content Library

MethodPathAuthDescription
GET/toy/content/libraryFlexAuthList library items (paginated, filterable)
GET/toy/content/library/searchFlexAuthFull-text search
GET/toy/content/library/categoriesFlexAuthList categories with counts
GET/toy/content/library/statisticsFlexAuthAggregate statistics
POST/toy/content/library/batchAdminBatch create items
POST/toy/content/library/uploadAdminUpload audio/image file to S3
GET/toy/content/library/:idFlexAuthGet single item by ID
POST/toy/content/libraryAdminCreate single item
PUT/toy/content/library/:idAdminUpdate item
DELETE/toy/content/library/:idAdminDelete item

Music (legacy)

MethodPathAuthDescription
GET/toy/content/music/listNoneList music (paginated)
GET/toy/content/music/:idNoneGet music by ID
POST/toy/content/music/createUserCreate music entry
PUT/toy/content/music/update/:idUserUpdate music entry

Content Library

GET /toy/content/library

Returns paginated content items with optional filters.

Query Parameters

ParamTypeDefaultDescription
pageinteger1Page number
limitinteger10Items per page
contentTypestringFilter: music or story
categorystringFilter by category (language/genre)
isActivebooleanFilter by active status

Response

{
"code": 0,
"msg": "success",
"data": {
"list": [
{
"id": "uuid",
"title": "Twinkle Twinkle",
"romanized": "twinkle twinkle",
"filename": "twinkle_twinkle.mp3",
"contentType": "music",
"category": "English",
"alternatives": ["twinkle", "star song"],
"awsS3Url": "https://cdn.example.com/music/twinkle_twinkle.mp3",
"durationSeconds": 120,
"fileSizeBytes": 1920000,
"isActive": 1,
"createdAt": "2024-01-01T00:00:00.000Z"
}
],
"total": 250,
"page": 1,
"limit": 10
}
}

GET /toy/content/library/search

Full-text search across title, romanized title, and alternative search terms.

Query Parameters

ParamTypeRequiredDescription
qstringYesSearch query (min 2 characters)
pageintegerNoDefault 1
limitintegerNoDefault 20
contentTypestringNoFilter: music or story
categorystringNoFilter by category

Returns 400 if q is shorter than 2 characters.


GET /toy/content/library/categories

Returns all categories with item counts.

Query Parameters

ParamDescription
contentTypeOptional. Filter by music or story

Response

{
"code": 0,
"msg": "success",
"data": [
{ "category": "English", "contentType": "music", "count": 45 },
{ "category": "Hindi", "contentType": "music", "count": 30 },
{ "category": "Bedtime", "contentType": "story", "count": 20 }
]
}

GET /toy/content/library/statistics

Returns aggregate counts for the library.

Response

{
"code": 0,
"msg": "success",
"data": {
"total": 350,
"byType": {
"music": 200,
"story": 150
},
"byCategory": {
"English": 100,
"Hindi": 80,
"Bedtime": 50
}
}
}

POST /toy/content/library/upload

Uploads an audio or image file to AWS S3 via multipart form data. Returns the CloudFront URL for the uploaded file.

Request (multipart/form-data)

FieldTypeRequiredDescription
filebinaryYesAudio file (mp3, wav, ogg, m4a) or image (jpeg, png, gif, webp) or .bin file. Max 50 MB.
contentTypestringYesmusic, story, or rfidcontent
categorystringNoCategory/language (defaults to "English")

Response

{
"code": 0,
"msg": "success",
"data": {
"url": "https://cdn.example.com/music/english/twinkle_twinkle.mp3",
"filename": "twinkle_twinkle.mp3"
}
}

POST /toy/content/library

Creates a new content item record (after uploading the file separately).

Request

{
"title": "Twinkle Twinkle",
"romanized": "twinkle twinkle",
"filename": "twinkle_twinkle.mp3",
"contentType": "music",
"category": "English",
"alternatives": ["twinkle", "star song"],
"awsS3Url": "https://cdn.example.com/music/english/twinkle_twinkle.mp3",
"durationSeconds": 120,
"fileSizeBytes": 1920000,
"isActive": 1
}
FieldTypeRequiredDescription
titlestringYesDisplay title
romanizedstringNoRomanized/transliterated title for search
filenamestringNoOriginal filename
contentTypestringYesmusic or story
categorystringNoLanguage/genre category
alternativesstring[]NoAlternative search terms
awsS3UrlstringNoS3/CDN URL for the audio file
durationSecondsintegerNoAudio duration
fileSizeBytesintegerNoFile size in bytes
isActiveintegerNo1 = active (default), 0 = inactive

POST /toy/content/library/batch

Creates multiple content items in a single request. Each item in the items array uses the same fields as the single create endpoint.

Request

{
"items": [
{
"title": "Twinkle Twinkle",
"contentType": "music",
"category": "English",
"awsS3Url": "https://cdn.example.com/music/twinkle.mp3"
},
{
"title": "The Three Little Pigs",
"contentType": "story",
"category": "Bedtime"
}
]
}

Response

{
"code": 0,
"msg": "Successfully created 2 content items",
"data": { "created": 2 }
}

PUT /toy/content/library/:id

Updates an existing library item. All fields optional; only provided fields are updated. Returns 404 if item does not exist.


DELETE /toy/content/library/:id

Deletes a library item. Returns 404 if item does not exist.


Music (Legacy Routes)

GET /toy/content/music/list

Query Parameters

ParamDescription
pagePage number (default 1)
limitItems per page (default 10)
categoryFilter by category
languageFilter by language

POST /toy/content/music/create

Request

{
"title": "Song Title",
"artist": "Artist Name",
"album": "Album Name",
"category": "English",
"language": "en",
"duration": 180,
"fileUrl": "https://cdn.example.com/song.mp3",
"coverUrl": "https://cdn.example.com/cover.jpg",
"lyrics": "La la la..."
}

PUT /toy/content/music/update/:id

Updates fields on an existing music record. Same body shape as create; all fields optional.