Table of Contents
- List of Entrypoints
- CRUD Privileges
- Global Error Codes
- Authentication
- Genres
- Artists
- Songs
- Search
- Third-Party APIs
HTTP Method | Entrypoint | Description |
---|---|---|
Authentication | ||
POST | /login |
Generates an access token for the user upon login. |
POST | /glogin |
Generates an access token for the user by Google OAuth login. |
POST | /register |
Registers a new user onto the application. |
Genres | ||
GET | /genres |
Gets a list of all genres stored in the database. |
POST | /genres |
Create a new genre/sub-genre and save it to the database. |
GET | /genres/:id |
Gets a genre by ID, along with its sub-genres and parent genre (if any). |
PUT | /genres/:id |
Updates an existing genre/sub-genre and save it to the database. |
DELETE | /genres/:id |
Deletes an existing genre/sub-genre. |
GET | /genres/:id/songs |
Gets the songs belonging to a specific genre. |
Artists | ||
GET | /artists |
Gets the list of artists stored in the database. |
POST | /artists |
Create a new artist and save it to the database. |
GET | /artists/:id |
Gets data for a specific artist in the database, by their ID. |
PUT | /artists/:id |
Updates data for a specific artist in the database, by their ID. |
DELETE | /artists/:id |
Deletes data for a specific artist in the database, by their ID. |
GET | /artists/:id/songs |
Gets the list of songs for a specific artist in the database. |
Songs | ||
GET | /songs |
Gets a list of songs stored in the database. |
POST | /songs |
Create a new song and save it to the database. |
GET | /songs/:id |
Gets data for a specific song in the database, by their ID. |
PUT | /songs/:id |
Updates data for a specific song in the database, by their ID. |
DELETE | /songs/:id |
Deletes data for a specific song in the database, by their ID. |
PUT | /songs/:id/genres |
Updates a song's genre information. |
POST | /songs/:id/timed-lyrics |
Submits a set of timed lyrics for a song in the database. |
PUT | /songs/:id/timed-lyrics/:lyricsId |
Updates an existing set of timed lyrics for a song in the database. |
DELETE | /songs/:id/timed-lyrics/:lyricsId |
Deletes an existing set of timed lyrics for a song in the database. |
Search | ||
GET | /search/artists |
Searches for artists in the database by their name. |
GET | /search/songs |
Searches for songs in the database by their title. |
Third-party APIs | ||
POST | /youtube/artists |
Get the artist's recent videos as reported by the YouTube Data API. |
POST | /vocadb/artists |
Get the artist's top-rated VOCALOID songs as reported by the VocaDB API. |
Role | Read | Create | Update | Delete |
---|---|---|---|---|
Admin | ✅ All | ✅ All | ✅ All | ✅ All |
Staff | ✅ All | ✅ Songs, artists ❌ Genres |
✅ Songs, artists ❌ Genres |
❌ All |
User | ✅ All | ❌ All | ❌ All | ❌ All |
No Auth. | ✅ All | ❌ All | ❌ All | ❌ All |
{
"statusCode": 401,
"message": "Invalid token"
}
{
"statusCode": 401,
"message": "Token has expired"
}
{
"statusCode": 403,
"message": "Forbidden access"
}
{
"statusCode": 404,
"message": "Data not found"
}
Generates an access token for the user upon login.
Request Body
{
"email": "john.doe@mail.com",
"password": "password"
}
Response - 200 OK
{
"access_token": ...
}
Response - 401 Unauthorized
{
"statusCode": 401,
"message": "Invalid username/password"
}
Generates an access token for the user by Google OAuth login.
Request Headers
{
...
"google_token": ...
}
Response - 200 OK
{
"access_token": ...
}
Registers a new user onto the application.
Request Body
{
"username": "Jill Jones",
"email": "jill.jones@mail.com",
"password": "password"
}
Response - 201 Created
{
"message": "Registration successful"
}
Response - 400 Bad Request
{
"statusCode": 400,
"message": "Username is required"
}
{
"statusCode": 400,
"message": "Email is required"
}
{
"statusCode": 400,
"message": "Password is required"
}
{
"statusCode": 400,
"message": "Password must be at least 8 characters long"
}
{
"statusCode": 400,
"message": "Username is already registered"
}
{
"statusCode": 400,
"message": "Email is already registered"
}
Gets a list of all genres stored in the database.
Response - 200 OK
[
{
"id": 5,
"name": "Country",
"subGenres": []
},
{
"id": 1,
"name": "Pop",
"subGenres": [
{
"id": 2,
"name": "C-Pop"
},
{
"id": 3,
"name": "J-Pop"
},
{
"id": 4,
"name": "K-Pop"
}
]
}
]
Create a new genre/sub-genre and save it to the database.
Request - Headers
{
...
"access_token": ...
}
Request - Body
{
"name": "Metalcore",
"parentId": 1
}
Response - 201 Created
{
"message": "Successfully added genre"
}
Response - 400 Bad Request
{
"statusCode": 400,
"message": "Genre name is required"
}
Gets a genre by ID, along with its sub-genres and parent genre (if any).
Path Parameters
id
: Genre ID
Response - 200 OK
{
"id": 1,
"name": "Pop",
"subGenres": [
{
"id": 17,
"name": "C-Pop"
},
{
"id": 18,
"name": "J-Pop"
},
{
"id": 16,
"name": "K-Pop"
}
],
"parentGenre": null
}
Updates an existing genre/sub-genre and save it to the database.
Path Parameters
id
: Genre ID
Request - Headers
{
...
"access_token": ...
}
Request - Body
{
"name": "Metalcore",
"parentId": 1
}
Response - 200 OK
{
"message": "Successfully edited genre"
}
Response - 400 Bad Request
{
"statusCode": 400,
"message": "Genre name is required"
}
Deletes an existing genre/sub-genre.
Path Parameters
id
: Genre ID
Request - Headers
{
...
"access_token": ...
}
Response - 200 OK
{
"message": "Successfully deleted genre"
}
Gets the songs belonging to a specific genre.
Path Parameters
id
: Genre ID
Response - 200 OK
{
"count": 14,
"offset": 0,
"data": [
{
"id": 5,
"name": "アンハッピーリフレイン",
"aliases": [
"Unhappy Refrain"
],
"releaseDate": "2011-05-02T00:00:00.000Z",
"songType": "Original",
"artists": [
{
"id": 1,
"name": "初音ミク"
},
{
"id": 2,
"name": "wowaka"
}
],
"links": [
{
"id": 11,
"songURL": "https://www.nicovideo.jp/watch/sm14330479",
"isInactive": false
},
{
"id": 12,
"songURL": "https://www.youtube.com/watch?v=uMlv9VWAxko",
"isInactive": false
}
]
},
...
]
}
Gets the list of artists stored in the database, including the number of their songs registered in the database.
Query Parameters
limit
: Number of records to fetch per API call.offset
: Number of records to offset by (for pagination).
Response - 200 OK
{
"count": 4,
"offset": 0,
"data": [
{
"id": 1,
"name": "初音ミク",
"aliases": [
"Hatsune Miku"
],
"imageURL": "",
"description": "A Japanese female voicebank released for the vocal synthesizer software VOCALOID by Crypton Future Media.",
"createdAt": "2023-10-09T12:49:17.646Z",
"numSongs": 14
},
...
]
}
Create a new artist and save it to the database.
When posting to this entrypoint, the sub-resource ArtistLink is created alongside the main resource Artist. Use the links
property of the request body to add each ArtistLink.
Request - Headers
{
...
"access_token": ...
}
Request - Body
{
"name": "Kagamine Rin",
"aliases": ["Rin Kagamine", "CV-02"],
"imageURL": "https://image-url.net/1234",
"description": "Japanese VOCALOID bank.",
"links": [
{
"webURL": "https://en.wikipedia.org/wiki/Kagamine_Rin/Len",
"description": "Wikipedia (JP)"
},
{
"webURL": "https://www.youtube.com/watch?v=abhbaac12f",
"description": "VEVO Account",
"isInactive": true
}
]
}
Response - 201 Created
{
"message": "Successfully created artist"
}
Response - 400 Bad Request
{
"statusCode": 400,
"message": "Artist name is required"
}
{
"statusCode": 400,
"message": "Web URL is not valid"
}
Gets data for a specific artist in the database, by their ID.
Path Parameters
id
: Artist ID
Response - 200 OK
{
"id": 1,
"name": "初音ミク",
"aliases": [
"Hatsune Miku"
],
"imageURL": "https://upload.wikimedia.org/wikipedia/id/9/93/Hatsune_Miku.png",
"description": "A Japanese female voicebank released for the vocal synthesizer software VOCALOID by Crypton Future Media.",
"links": [
{
"id": 1,
"webURL": "https://en.wikipedia.org/wiki/Hatsune_Miku",
"description": "Wikipedia",
"isInactive": false
},
{
"id": 2,
"webURL": "https://ec.crypton.co.jp/pages/prod/vocaloid/mikuv4x",
"description": "Official webpage (JP)",
"isInactive": false
}
]
}
Updates data for a specific artist in the database, by their ID.
When posting to this entrypoint, the sub-resource ArtistLink is updated alongside the main resource Artist. Use the links
property of the request body to update/add/delete each ArtistLink.
Path Parameters
id
: Artist ID
Request - Headers
{
...
"access_token": ...
}
Request - Body
{
"id": 2,
"name": "Kagamine Rin",
"aliases": [],
"imageURL": "https://image-url.net/abcd",
"description": "Japanese female VOCALOID bank. Released in December 2007.",
"links": [
{
"id": 3,
"webURL": "https://en.wikipedia.org/wiki/Kagamine_Rin/Len",
"description": "Wikipedia (JP)",
"isInactive": false
},
{
"id": 4,
"webURL": "https://www.youtube.com/watch?v=abhbaac12f",
"description": "VEVO Account",
"isInactive": true
},
{
"webURL": "https://vocadb.net",
"description": "VOCALOID database",
"isInactive": false
}
]
}
Response - 200 OK
{
"message": "Successfully edited artist"
}
Response - 400 Bad Request
{
"statusCode": 400,
"message": "Artist name is required"
}
{
"statusCode": 400,
"message": "Web URL is not valid"
}
Deletes data for a specific artist in the database, by their ID.
When posting to this entrypoint, the sub-resource ArtistLink is deleted alongside the main resource Artist.
Path Parameters
id
: Artist ID
Request - Headers
{
...
"access_token": ...
}
Response - 200 OK
{
"message": "Successfully deleted artist"
}
Gets the list of songs for a specific artist in the database.
Path Parameters
id
: Artist ID
Query Parameters
limit
: Number of records to fetch per API call.offset
: Number of records to offset by (for pagination).
Response - 200 OK
{
"count": 14,
"offset": 0,
"data": [
{
"id": 5,
"name": "アンハッピーリフレイン",
"aliases": [
"Unhappy Refrain"
],
"releaseDate": "2011-05-02T00:00:00.000Z",
"songType": "Original",
"parentId": null,
"artists": [
{
"id": 2,
"name": "wowaka",
"aliases": null
},
{
"id": 1,
"name": "初音ミク",
"aliases": [
"Hatsune Miku"
]
}
],
"links": [
{
"id": 11,
"songURL": "https://www.nicovideo.jp/watch/sm14330479",
"isInactive": false
},
{
"id": 12,
"songURL": "https://www.youtube.com/watch?v=uMlv9VWAxko",
"isInactive": false
}
]
},
...
]
}
Gets a list of songs stored in the database.
Query Parameters
limit
: Number of records to fetch per API call.offset
: Number of records to offset by (for pagination).
Response - 200 OK
{
"count": 22,
"offset": 0,
"data": [
{
"id": 5,
"name": "アンハッピーリフレイン",
"aliases": [
"Unhappy Refrain"
],
"releaseDate": "2011-05-02T00:00:00.000Z",
"songType": "Original",
"parentId": null,
"createdAt": "2023-10-09T12:49:17.651Z",
"artists": [
{
"id": 1,
"name": "初音ミク",
"aliases": [
"Hatsune Miku"
]
},
{
"id": 2,
"name": "wowaka",
"aliases": null
}
],
"links": [
{
"id": 12,
"songURL": "https://www.youtube.com/watch?v=uMlv9VWAxko",
"isInactive": false
},
{
"id": 11,
"songURL": "https://www.nicovideo.jp/watch/sm14330479",
"isInactive": false
}
]
},
...
]
}
Create a new song and save it to the database.
When posting to this entrypoint, the sub-resources SongArtist and PlayLink are created alongside the main resource Song. Use the artists
, links
properties of the request body to add each SongArtist and PlayLink, respectively.
Request - Headers
{
...
"access_token": ...
}
Request - Body
{
"name": "ドラマツルギー",
"aliases": ["Dramaturgy"],
"releaseDate": "2017-10-11T00:00:00",
"songType": "Original",
"parentId": null,
"artists": [
{
"id": 2,
"role": "composer, singer"
}
],
"links": [
{
"songURL": "https://www.youtube.com/watch?v=jJzw1h5CR-I",
"isInactive": false
}
]
}
Response - 201 Created
{
"message": "Successfully created song"
}
Response - 400 Bad Request
{
"statusCode": 400,
"message": "Song name is required"
}
{
"statusCode": 400,
"message": "Song URL is not valid"
}
Gets data for a specific song in the database, by their ID.
Path Parameters
id
: Song ID
Response - 200 OK
{
"id": 1,
"name": "ローリンガール",
"aliases": [
"Rolling Girl"
],
"releaseDate": "2010-02-14T00:00:00.000Z",
"songType": "Original",
"parentId": null,
"basedOn": null,
"derivatives": [],
"genres": [
{
"id": 2,
"name": "Rock"
},
{
"id": 3,
"name": "Metal"
}
],
"artists": [
{
"id": 1,
"name": "初音ミク",
"aliases": [
"Hatsune Miku"
],
"role": "Vocalist"
},
{
"id": 2,
"name": "wowaka",
"aliases": null,
"role": "Composer"
}
],
"links": [
{
"id": 1,
"songURL": "https://www.nicovideo.jp/watch/sm9714351",
"isInactive": false
},
{
"id": 2,
"songURL": "https://www.youtube.com/watch?v=vnw8zURAxkU",
"isInactive": false
}
],
"timedLyrics": [
{
"id": 1,
"startTime": 31982,
"endTime": 41892,
"text": "For lonely girls, it's always the same, dreaming dreams that don't come true"
},
...
]
}
Updates data for a specific song in the database, by their ID.
When posting to this entrypoint, the sub-resources SongArtist and PlayLink are updated alongside the main resource Song. Use the artists
, links
properties of the request body to update/add/remove each SongArtist and PlayLink, respectively.
Path Parameters
id
: Song ID
Request - Headers
{
...
"access_token": ...
}
Request - Body
{
"id": 2,
"name": "Ura Omote Lovers",
"aliases": ["裏表ラバーズ"],
"releaseDate": "2009-08-26T00:00:00",
"songType": "Cover",
"parentId": 1,
"artists": [{
"id": 1,
"role": "vocalist",
}],
"links": [
{
"id": 3,
"songURL": "https://www.nicovideo.jp/watch/sm8082467",
"isInactive": false
},
{
"songURL": "https://www.youtube.com/watch?v=b_cuMcDWwsI",
"isInactive": false
}
]
}
Response - 200 OK
{
"message": "Successfully edited song"
}
Response - 400 Bad Request
{
"statusCode": 400,
"message": "Song name is required"
}
{
"statusCode": 400,
"message": "Song URL is not valid"
}
Deletes data for a specific song in the database, by their ID.
When posting to this entrypoint, the sub-resources SongArtist and PlayLink are deleted alongside the main resource Song. The resource Artist is unaffected.
Path Parameters
id
: Song ID
Request - Headers
{
...
"access_token": ...
}
Response - 200 OK
{
"message": "Successfully deleted song"
}
Updates a song's genre information.
Path Parameters
id
: Song ID
Request - Headers
{
...
"access_token": ...
}
Request - Body
{
"genres": [
{ "id": 3 },
{ "id": 2 }
]
}
Response - 200 OK
{
"message": "Successfully edited song genres"
}
Response - 400 Bad Request
{
"statusCode": 400,
"message": "Song genres must not be null"
}
Submits a set of timed lyrics for a song in the database. Validation for timed lyrics is done by checking if the sent text is parseable as a SubRip Text (SRT) string.
Path Parameters
id
: Song ID
Request - Headers
{
...
"access_token": ...
}
Request - Body
{
"srt": "1\n00:00:31,982 --> 00:00:41,892\nFor lonely girls, it's always the same, dreaming dreams that don't come true\n\n2\n00:00:41,892 --> 00:00:51,768\nAnd churning, churning through the clamor in their heads"
}
Response - 201 Created
{
"message": "Successfully added lyrics"
}
Response - 400 Bad Request
{
"statusCode": 400,
"message": "SubRip Text contents required."
}
{
"statusCode": 400,
"message": "Invalid SubRip Text contents."
}
Updates the lyrics for an existing set of timed lyrics for a song in the database. Validation for timed lyrics is done by checking if the sent text is parseable as a SubRip Text (SRT) string.
Path Parameters
id
: Song IDlyricsId
: Timed Lyrics ID
Request - Headers
{
...
"access_token": ...
}
Request - Body
{
"srt": "1\n00:00:31,982 --> 00:00:41,892\nFor lonely girls, it's always the same, dreaming dreams that don't come true\n\n2\n00:00:41,892 --> 00:00:51,768\nAnd churning, churning through the clamor in their heads"
}
Response - 200 OK
{
"message": "Successfully edited lyrics"
}
Response - 400 Bad Request
{
"statusCode": 400,
"message": "SubRip Text contents required."
}
{
"statusCode": 400,
"message": "Invalid SubRip Text contents."
}
Deletes an existing set of timed lyrics for a song in the database.
Path Parameters
id
: Song IDlyricsId
: Timed Lyrics ID
Request - Headers
{
...
"access_token": ...
}
Response - 200 OK
{
"message": "Successfully deleted lyrics"
}
Searches for artists in the database by their name.
Query Parameters
title
: Substring to search in the artists' name.limit
: Number of records to fetch per API call.offset
: Number of records to offset by (for pagination).
Response - 200 OK
{
"count": 1,
"offset": 0,
"data": [
{
"id": 1,
"name": "初音ミク",
"alias": "Hatsune Miku"
}
]
}
Searches for songs in the database by their title.
Query Parameters
title
: Substring to search in the artists' name.limit
: Number of records to fetch per API call.offset
: Number of records to offset by (for pagination).
Response - 200 OK
{
"count": 1,
"offset": 0,
"data": [
{
"id": 1,
"name": "ローリンガール",
"alias": "Rolling Girl"
}
]
}
Get the artist's recent videos as reported by the YouTube Data API.
Request Body
{
"channelUrl": "https://www.youtube.com/channel/UCUXfRsEIJ9xO1DT7TbEWksw"
}
Response - 200 OK
{
"channelId": "UCUXfRsEIJ9xO1DT7TbEWksw",
"title": "Eve",
"description": "Eve - OFFICIAL CHANNEL",
"customUrl": "@ooo0eve0ooo",
"publishedAt": "2013-11-10T02:48:09Z",
"imageUrl": {
"url": "https://yt3.ggpht.com/fw8zOGJrIuaYXSaQNuOpAsOi7CBboTWY9rbctP-S378bMLzVWbnz2GbzCb88jJOFsw3fdQfSKQ=s800-c-k-c0x00ffffff-no-nd-rj",
"width": 800,
"height": 800
},
"uploads": [
{
"title": "虎狼来 Music Animation #Shorts",
"imageUrl": {
"url": "https://i.ytimg.com/vi/EjoyPVwH6Yo/hqdefault.jpg",
"width": 480,
"height": 360
},
"videoId": "EjoyPVwH6Yo",
"publishedAt": "2023-08-30T11:02:03Z"
},
{
"title": "虎狼来 (Kororon) - Eve Music Video",
"imageUrl": {
"url": "https://i.ytimg.com/vi/Gw96jPDtoDQ/hqdefault.jpg",
"width": 480,
"height": 360
},
"videoId": "Gw96jPDtoDQ",
"publishedAt": "2023-08-27T09:28:37Z"
},
{
"title": "虎狼来 dance ver",
"imageUrl": {
"url": "https://i.ytimg.com/vi/zvPhEwzTMnc/hqdefault.jpg",
"width": 480,
"height": 360
},
"videoId": "zvPhEwzTMnc",
"publishedAt": "2023-08-18T10:20:43Z"
},
{
"title": "冒険録 (Adventure Log) - Eve Music Video",
"imageUrl": {
"url": "https://i.ytimg.com/vi/z9c5tlQHXWM/hqdefault.jpg",
"width": 480,
"height": 360
},
"videoId": "z9c5tlQHXWM",
"publishedAt": "2023-08-11T10:00:09Z"
},
{
"title": "デーモンダンストーキョー Animation Live #Shorts",
"imageUrl": {
"url": "https://i.ytimg.com/vi/Uo0e7Aqsrww/hqdefault.jpg",
"width": 480,
"height": 360
},
"videoId": "Uo0e7Aqsrww",
"publishedAt": "2023-06-30T11:12:30Z"
}
],
"statistics": {
"viewCount": "2305315470",
"subscriberCount": "4640000",
"hiddenSubscriberCount": false,
"videoCount": "93"
}
}
Get the artist's top-rated VOCALOID songs as reported by the VocaDB API.
Request Body
{
"vocadbUrl": "https://vocadb.net/Ar/53"
}
Response - 200 OK
[
{
"name": "ローリンガール",
"aliases": "Rolling Girl, Rollin' Girl, 翻滚少女",
"artistString": "wowaka feat. 初音ミク",
"ratingScore": 1370
},
{
"name": "ワールズエンド・ダンスホール",
"aliases": "World's End Dancehall, 世末舞厅, 世界末日舞厅",
"artistString": "wowaka feat. 初音ミク, 巡音ルカ",
"ratingScore": 945
},
{
"name": "アンノウン・マザーグース",
"aliases": "Unknown Mother-Goose, Unknown Mother Goose, 不为人知的鹅妈妈童谣",
"artistString": "wowaka, ヒトリエ feat. 初音ミク V4X (Dark)",
"ratingScore": 741
},
{
"name": "裏表ラバーズ",
"aliases": "Uraomote Lovers, Two-Sided Lovers, Two-Faced Lovers, 里表情人, Love & Lovers",
"artistString": "wowaka feat. 初音ミク",
"ratingScore": 719
},
{
"name": "アンハッピーリフレイン",
"aliases": "Unhappy Refrain",
"artistString": "wowaka feat. 初音ミク",
"ratingScore": 638
},
{
"name": "とおせんぼ",
"aliases": "Toosenbo, Shall Not Pass, Standing in Your Way, I Won't Let You Through",
"artistString": "wowaka feat. 初音ミク",
"ratingScore": 264
},
{
"name": "リバシブルドール",
"aliases": "Reversible Doll",
"artistString": "wowaka feat. 初音ミク, 巡音ルカ",
"ratingScore": 163
},
{
"name": "日常と地球の額縁",
"aliases": "Nichijou to Chikyuu no Gakubuchi, Usual Life and Earth's Frame, Frame of Normal Life and the World, 日常和地球的画框",
"artistString": "wowaka feat. 初音ミク",
"ratingScore": 158
}
]