NAV
javascript bash

Info

Welcome to the generated API reference.

This is the official API documentation for Koel, generated from the source code using Laravel API Documentation Generator. If you spot any mistake or want to add an improvement, please submit an issue or open a pull request.

1. Authentication

Log a user in

Koel uses JSON Web Tokens (JWT) for authentication. After the user has been authenticated, a random "token" will be returned. This token should then be saved in a local storage and used as an Authorization: Bearer header for consecutive calls.

Notice: The token is valid for a week, after that the user will need to log in again.

Example request:

curl -X POST "https://api-docs.koel.dev/api/me" \
    -H "Content-Type: application/json" \
    -d '{"email":"john@doe.com","password":"SoSecureMuchW0w"}'
const url = new URL("https://api-docs.koel.dev/api/me");

let headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "email": "john@doe.com",
    "password": "SoSecureMuchW0w"
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "token": "<a-random-string>"
}

HTTP Request

POST api/me

Body Parameters

Parameter Type Status Description
email string required The user's email.
password string required The password.

Log the current user out

Example request:

curl -X DELETE "https://api-docs.koel.dev/api/me" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/me");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "DELETE",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

HTTP Request

DELETE api/me

2. Application data

Get application data

The big fat call to retrieve a set of application data catered for the current user (songs, albums, artists, playlists, interactions, and if the user is an admin, settings as well). Naturally, this call should be made right after the user has been logged in, when you need to populate the application's interface with useful information.

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/data" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/data");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "albums": [
        {
            "id": 42,
            "artist_id": 42,
            "name": "...And Justice For All"
        },
        {
            "...": "..."
        }
    ],
    "allowDownload": true,
    "artists": [
        {
            "id": 42,
            "name": "Metallica"
        },
        {
            "...": "..."
        }
    ],
    "cdnUrl": "https:\/\/yourcdn.koel.example\/",
    "currentUser": {
        "id": 1,
        "name": "John Doe",
        "email": "john@doe.net",
        "is_admin": true,
        "preferences": {
            "lastfm_session_key": "hidden"
        }
    },
    "currentVersion": "v3.7.2",
    "interactions": [
        {
            "song_id": "f88c7671623c6b8be881e2a04e685509",
            "liked": false,
            "play_count": 5
        },
        {
            "...": "..."
        }
    ],
    "latestVersion": "v3.7.2",
    "playlists": [
        {
            "id": 1,
            "name": "Ballads",
            "rules": null,
            "is_smart": false
        },
        {
            "...": "..."
        }
    ],
    "recentlyPlayed": [
        "f78de3724e2823e7e4cfb660c4f691e9",
        "aebb93a69d6c8af79a1004aceabb201c",
        "..."
    ],
    "settings": {
        "media_path": "\/var\/www\/media"
    },
    "songs": [
        {
            "id": "00037ec0715a8781104ffd8efe0db06a",
            "album_id": 42,
            "artist_id": 42,
            "title": "Carpe Diem Baby",
            "created_at": "2015-12-10 05:52:22",
            "disc": 1,
            "track": 7,
            "length": 372.27
        },
        {
            "...": "..."
        }
    ],
    "supportsTranscoding": true,
    "useLastfm": true,
    "useYouTube": true,
    "useiTunes": true,
    "users": [
        {
            "id": 1,
            "name": "John Doe",
            "email": "john@doe.com",
            "is_admin": true
        },
        {
            "...": "..."
        }
    ]
}

HTTP Request

GET api/data

3. Song interactions

Play a song

The GET request to play/stream a song. By default Koel will serve the file as-is, unless it's a FLAC. If the value of transcode is truthy, Koel will attempt to transcode the file into bitRatekbps using ffmpeg.

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/1/play/1/1?jwt-token=saepe" 
const url = new URL("https://api-docs.koel.dev/api/1/play/1/1");

    let params = {
            "jwt-token": "saepe",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{}

HTTP Request

GET api/{song}/play/{transcode?}/{bitrate?}

Query Parameters

Parameter Status Description
jwt-token required The JWT token.

Increase play count

Increase a song's play count as the currently authenticated user. This request should be made whenever a song is played. An "interaction" record including the song and current user's data will be returned.

Example request:

curl -X POST "https://api-docs.koel.dev/api/interaction/play" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"song":"0146d01afb742b01f28ab8b556f9a75d"}'
const url = new URL("https://api-docs.koel.dev/api/interaction/play");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "song": "0146d01afb742b01f28ab8b556f9a75d"
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "song_id": "0146d01afb742b01f28ab8b556f9a75d",
    "liked": true,
    "play_count": 228,
    "song": {
        "id": "0146d01afb742b01f28ab8b556f9a75d",
        "album_id": 1363,
        "artist_id": 430,
        "title": "The Show Must Go On",
        "length": 407.33,
        "track": 0,
        "disc": 1,
        "created_at": "2017-02-07 10:35:03",
        "artist": {
            "id": 430,
            "name": "Queen",
            "image": "https:\/\/koel.yourdomain.net\/img\/artists\/5a7727c2afbb09.08223866.png"
        },
        "album": {
            "id": 1363,
            "artist_id": 430,
            "name": "Innuendo",
            "cover": "https:\/\/koel.yourdomain.net\/img\/covers\/5899a2d7a19c90.72864263.jpg",
            "created_at": "2017-02-07 10:35:03",
            "is_compilation": false
        }
    },
    "user": {
        "id": 1,
        "name": "John Doe",
        "email": "john@doe.com",
        "is_admin": true,
        "preferences": {
            "lastfm_session_key": "hidden"
        }
    }
}

HTTP Request

POST api/interaction/play

Body Parameters

Parameter Type Status Description
song string required The ID of the song.

Like or unlike a song

An "interaction" record including the song and current user's data will be returned.

Example request:

curl -X POST "https://api-docs.koel.dev/api/interaction/like" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"song":"0146d01afb742b01f28ab8b556f9a75d"}'
const url = new URL("https://api-docs.koel.dev/api/interaction/like");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "song": "0146d01afb742b01f28ab8b556f9a75d"
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "song_id": "0146d01afb742b01f28ab8b556f9a75d",
    "liked": true,
    "play_count": 228,
    "song": {
        "id": "0146d01afb742b01f28ab8b556f9a75d",
        "album_id": 1363,
        "artist_id": 430,
        "title": "The Show Must Go On",
        "length": 407.33,
        "track": 0,
        "disc": 1,
        "created_at": "2017-02-07 10:35:03",
        "artist": {
            "id": 430,
            "name": "Queen",
            "image": "https:\/\/koel.yourdomain.net\/img\/artists\/5a7727c2afbb09.08223866.png"
        },
        "album": {
            "id": 1363,
            "artist_id": 430,
            "name": "Innuendo",
            "cover": "https:\/\/koel.yourdomain.net\/img\/covers\/5899a2d7a19c90.72864263.jpg",
            "created_at": "2017-02-07 10:35:03",
            "is_compilation": false
        }
    },
    "user": {
        "id": 1,
        "name": "John Doe",
        "email": "john@doe.com",
        "is_admin": true,
        "preferences": {
            "lastfm_session_key": "hidden"
        }
    }
}

HTTP Request

POST api/interaction/like

Body Parameters

Parameter Type Status Description
song string required The ID of the song.

Like multiple songs

Like several songs at once, useful for "batch" actions. An array of "interaction" records containing the song and user data will be returned.

Example request:

curl -X POST "https://api-docs.koel.dev/api/interaction/batch/like" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"songs":[]}'
const url = new URL("https://api-docs.koel.dev/api/interaction/batch/like");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "songs": []
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[
    {
        "song_id": "0146d01afb742b01f28ab8b556f9a75d",
        "liked": true,
        "play_count": 228,
        "song": {
            "id": "0146d01afb742b01f28ab8b556f9a75d",
            "album_id": 1363,
            "artist_id": 430,
            "title": "The Show Must Go On",
            "length": 407.33,
            "track": 0,
            "disc": 1,
            "created_at": "2017-02-07 10:35:03",
            "artist": {
                "id": 430,
                "name": "Queen",
                "image": "https:\/\/koel.yourdomain.net\/img\/artists\/5a7727c2afbb09.08223866.png"
            },
            "album": {
                "id": 1363,
                "artist_id": 430,
                "name": "Innuendo",
                "cover": "https:\/\/koel.yourdomain.net\/img\/covers\/5899a2d7a19c90.72864263.jpg",
                "created_at": "2017-02-07 10:35:03",
                "is_compilation": false
            }
        },
        "user": {
            "id": 1,
            "name": "John Doe",
            "email": "john@doe.com",
            "is_admin": true,
            "preferences": {
                "lastfm_session_key": "hidden"
            }
        }
    },
    {
        "...": "..."
    }
]

HTTP Request

POST api/interaction/batch/like

Body Parameters

Parameter Type Status Description
songs array required An array of song IDs.

Unlike multiple songs

Unlike several songs at once, useful for "batch" actions. An array of "interaction" records containing the song and user data will be returned.

Example request:

curl -X POST "https://api-docs.koel.dev/api/interaction/batch/unlike" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"songs":[]}'
const url = new URL("https://api-docs.koel.dev/api/interaction/batch/unlike");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "songs": []
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[
    {
        "song_id": "0146d01afb742b01f28ab8b556f9a75d",
        "liked": true,
        "play_count": 228,
        "song": {
            "id": "0146d01afb742b01f28ab8b556f9a75d",
            "album_id": 1363,
            "artist_id": 430,
            "title": "The Show Must Go On",
            "length": 407.33,
            "track": 0,
            "disc": 1,
            "created_at": "2017-02-07 10:35:03",
            "artist": {
                "id": 430,
                "name": "Queen",
                "image": "https:\/\/koel.yourdomain.net\/img\/artists\/5a7727c2afbb09.08223866.png"
            },
            "album": {
                "id": 1363,
                "artist_id": 430,
                "name": "Innuendo",
                "cover": "https:\/\/koel.yourdomain.net\/img\/covers\/5899a2d7a19c90.72864263.jpg",
                "created_at": "2017-02-07 10:35:03",
                "is_compilation": false
            }
        },
        "user": {
            "id": 1,
            "name": "John Doe",
            "email": "john@doe.com",
            "is_admin": true,
            "preferences": {
                "lastfm_session_key": "hidden"
            }
        }
    },
    {
        "...": "..."
    }
]

HTTP Request

POST api/interaction/batch/unlike

Body Parameters

Parameter Type Status Description
songs array required An array of song IDs.

Get recently played songs

Get a list of songs recently played by the current user.

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/interaction/recently-played/1?count=2" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/interaction/recently-played/1");

    let params = {
            "count": "2",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[
    "0146d01afb742b01f28ab8b556f9a75d",
    "c741133cb8d1982a5c60b1ce2a1e6e47"
]

HTTP Request

GET api/interaction/recently-played/{count?}

Query Parameters

Parameter Status Description
count optional The maximum number of songs to be returned.

4. Playlist management

Get current user's playlists

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/playlist" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/playlist");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[
    {
        "id": 13,
        "name": "Ballads",
        "rules": null,
        "is_smart": false
    },
    {
        "id": 17,
        "name": "Brand New Tracks",
        "rules": [
            {
                "id": 1543242741773,
                "rules": [
                    {
                        "id": 1543242742767,
                        "model": "interactions.play_count",
                        "operator": "is",
                        "value": [
                            "0"
                        ]
                    }
                ]
            }
        ],
        "is_smart": true
    },
    {
        "id": 12,
        "name": "Great Solos",
        "rules": null,
        "is_smart": false
    }
]

HTTP Request

GET api/playlist

Create a new playlist

Example request:

curl -X POST "https://api-docs.koel.dev/api/playlist" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"name":"Sleepy Songs","rules":[]}'
const url = new URL("https://api-docs.koel.dev/api/playlist");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "name": "Sleepy Songs",
    "rules": []
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "id": 42,
    "name": "Sleepy Songs",
    "rules": [],
    "is_smart": false
}

HTTP Request

POST api/playlist

Body Parameters

Parameter Type Status Description
name string required Name of the playlist.
rules array optional An array of rules if creating a "smart playlist."

Rename a playlist

Example request:

curl -X PUT "https://api-docs.koel.dev/api/playlist/1" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"name":"Catchy Songs"}'
const url = new URL("https://api-docs.koel.dev/api/playlist/1");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "name": "Catchy Songs"
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "id": 42,
    "name": "Catchy Songs",
    "rules": [],
    "is_smart": false
}

HTTP Request

PUT api/playlist/{playlist}

PATCH api/playlist/{playlist}

Body Parameters

Parameter Type Status Description
name string required New name of the playlist.

Delete a playlist

Example request:

curl -X DELETE "https://api-docs.koel.dev/api/playlist/1" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/playlist/1");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "DELETE",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[]

HTTP Request

DELETE api/playlist/{playlist}

Replace a playlist's content

Instead of adding or removing songs individually, a playlist's content is replaced entirely with an array of song IDs.

Example request:

curl -X PUT "https://api-docs.koel.dev/api/playlist/1/sync" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"songs":[]}'
const url = new URL("https://api-docs.koel.dev/api/playlist/1/sync");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "songs": []
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[]

HTTP Request

PUT api/playlist/{playlist}/sync

Body Parameters

Parameter Type Status Description
songs array required An array of song IDs.

Get a playlist's songs

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/playlist/1/songs" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/playlist/1/songs");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[
    "0146d01afb742b01f28ab8b556f9a75d",
    "c741133cb8d1982a5c60b1ce2a1e6e47",
    "..."
]

HTTP Request

GET api/playlist/{playlist}/songs

5. Media information

Update song information

Example request:

curl -X PUT "https://api-docs.koel.dev/api/songs" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"songs":[],"data":{}}'
const url = new URL("https://api-docs.koel.dev/api/songs");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "songs": [],
    "data": {}
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

HTTP Request

PUT api/songs

Body Parameters

Parameter Type Status Description
songs array required An array of song IDs to be updated.
data object required The new data, with these supported fields: title, artistName, albumName, and lyrics.

Get album's extra information

Get extra information about an album via Last.fm.

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/album/1/info" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/album/1/info");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "url": "https:\/\/www.last.fm\/music\/Queen\/Innuendo",
    "image": "https:\/\/lastfm-img2.akamaized.net\/i\/u\/300x300\/b56adcd16ca6454498981a8470a3ec06.png",
    "wiki": {
        "summary": "Innuendo is a 1991 album by English rock band Queen...",
        "full": "Innuendo is a 1991 album by English rock band Queen. It is the band's fourteenth studio album..."
    },
    "tracks": [
        {
            "title": "Innuendo",
            "length": 392,
            "url": "https:\/\/www.last.fm\/music\/Queen\/_\/Innuendo"
        },
        {
            "title": "I'm Going Slightly Mad",
            "length": 247,
            "url": "https:\/\/www.last.fm\/music\/Queen\/_\/I%27m+Going+Slightly+Mad"
        },
        {
            "...": "..."
        }
    ],
    "cover": "https:\/\/koel.yourdomain.net\/img\/covers\/5a771ec82a5d72.25096250.png"
}

HTTP Request

GET api/album/{album}/info

Get artist's extra information

Get extra information about an artist via Last.fm.

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/artist/1/info" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/artist/1/info");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "url": "https:\/\/www.last.fm\/music\/Queen",
    "image": "https:\/\/koel.yourdomain.net\/img\/artists\/5a772708e7de19.84120679.png",
    "bio": {
        "summary": "Queen were an English rock band originally consisting of four members...",
        "full": "Queen were an English rock band originally consisting of four members: vocalist Freddie Mercury, guitarist Brian May, bass guitarist John Deacon, and drummer Roger Taylor..."
    }
}

HTTP Request

GET api/artist/{artist}/info

Get song's extra information

Get a song's extra information. The response of this request is a superset of both corresponding album/{album}/info and artist/{artist}/info requests, combined with the song's lyrics and related YouTube videos, if applicable. This means you can (and should) cache this information somewhere ;)

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/song/1/info" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/song/1/info");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "lyrics": "...",
    "album_info": {
        "url": "https:\/\/www.last.fm\/music\/Queen\/Innuendo",
        "image": "https:\/\/lastfm-img2.akamaized.net\/i\/u\/300x300\/b56adcd16ca6454498981a8470a3ec06.png",
        "wiki": {
            "summary": "Innuendo is a 1991 album by English rock band Queen...",
            "full": "Innuendo is a 1991 album by English rock band Queen. It is the band's fourteenth studio album and the last..."
        },
        "tracks": [
            {
                "title": "Innuendo",
                "length": 392,
                "url": "https:\/\/www.last.fm\/music\/Queen\/_\/Innuendo"
            },
            {
                "title": "I'm Going Slightly Mad",
                "length": 247,
                "url": "https:\/\/www.last.fm\/music\/Queen\/_\/I%27m+Going+Slightly+Mad"
            },
            {
                "...": "..."
            }
        ]
    },
    "artist_info": {
        "url": "https:\/\/www.last.fm\/music\/Queen",
        "image": "https:\/\/koel.yourdomain.net\/img\/artists\/5a772708e7de19.84120679.png",
        "bio": {
            "summary": "Queen were an English rock band...",
            "full": "<br \/>\nQueen were an English rock band originally consisting of four members: vocalist Freddie Mercury, guitarist Brian May, bass guitarist John Deacon, and drummer Roger Taylor..."
        }
    },
    "youtube": {
        "kind": "youtube#searchListResponse",
        "etag": "\"XI7nbFXulYBIpL0ayR_gDh3eu1k\/UMIztE1sQ8L9tu7igiTaSoBA9tw\"",
        "nextPageToken": "CAoQAA",
        "regionCode": "CH",
        "pageInfo": {
            "totalResults": 1000000,
            "resultsPerPage": 10
        },
        "items": [
            {
                "kind": "youtube#searchResult",
                "etag": "\"XI7nbFXulYBIpL0ayR_gDh3eu1k\/bRRI2oEvvXIbCBFKv8WrLUaG-0A\"",
                "id": {
                    "kind": "youtube#video",
                    "videoId": "t99KH0TR-J4"
                },
                "snippet": {
                    "publishedAt": "2013-10-15T14:24:31.000Z",
                    "channelId": "UCiMhD4jzUqG-IgPzUmmytRQ",
                    "title": "Queen - The Show Must Go On (Official Video)",
                    "description": "Subscribe to the Official Queen Channel Here http:\/\/bit.ly\/Subscribe2Queen Taken from Innuendo, 1991. Queen - The Show Must Go On (promo video, 1991) ...",
                    "thumbnails": {
                        "default": {
                            "url": "https:\/\/i.ytimg.com\/vi\/t99KH0TR-J4\/default.jpg",
                            "width": 120,
                            "height": 90
                        },
                        "medium": {
                            "url": "https:\/\/i.ytimg.com\/vi\/t99KH0TR-J4\/mqdefault.jpg",
                            "width": 320,
                            "height": 180
                        },
                        "high": {
                            "url": "https:\/\/i.ytimg.com\/vi\/t99KH0TR-J4\/hqdefault.jpg",
                            "width": 480,
                            "height": 360
                        }
                    },
                    "channelTitle": "Queen Official",
                    "liveBroadcastContent": "none"
                }
            },
            {
                "...": "..."
            }
        ]
    }
}

HTTP Request

GET api/song/{song}/info

Upload an album's cover

Upload an image as an album's cover.

Example request:

curl -X PUT "https://api-docs.koel.dev/api/album/1/cover" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"cover":"dignissimos"}'
const url = new URL("https://api-docs.koel.dev/api/album/1/cover");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "cover": "dignissimos"
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "coverUrl": "https:\/\/koel.host\/images\/albums\/new-cover.jpg"
}

HTTP Request

PUT api/album/{album}/cover

Body Parameters

Parameter Type Status Description
cover string required The cover image's content, in Data URI format.

Upload an artist's image

Upload an image as an artist's image.

Example request:

curl -X PUT "https://api-docs.koel.dev/api/artist/1/image" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"image":"nihil"}'
const url = new URL("https://api-docs.koel.dev/api/artist/1/image");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "image": "nihil"
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "imageUrl": "https:\/\/koel.host\/images\/artists\/new-cover.jpg"
}

HTTP Request

PUT api/artist/{artist}/image

Body Parameters

Parameter Type Status Description
image string required The image's content, in Data URI format.

Get an album's thumbnail

Get an album's thumbnail (a 48px-wide blurry version of the album's cover). Returns the full URL to the thumbnail or NULL if the album has no cover.

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/album/1/thumbnail" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/album/1/thumbnail");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[
    "thumbnailUrl",
    "https:\/\/localhost\/public\/img\/covers\/a146d01afb742b01f28ab8b556f9a75d_thumbnail.jpg"
]

HTTP Request

GET api/album/{album}/thumbnail

6. Download

Download one or several songs

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/download/songs?songs=eaque" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/download/songs");

    let params = {
            "songs": "eaque",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[]

HTTP Request

GET api/download/songs

Query Parameters

Parameter Status Description
songs optional array An array of song IDs

Download a whole album

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/download/album/1" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/download/album/1");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[]

HTTP Request

GET api/download/album/{album}

Download all songs by an artist

Don't see why one would need this, really. Let's pray to God the user doesn't trigger this on Elvis.

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/download/artist/1" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/download/artist/1");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[]

HTTP Request

GET api/download/artist/{artist}

Download a whole playlist

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/download/playlist/1" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/download/playlist/1");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[]

HTTP Request

GET api/download/playlist/{playlist}

Download all songs favorite'd by the current user

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/download/favorites" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/download/favorites");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[]

HTTP Request

GET api/download/favorites

7. User management

Create a new user

Example request:

curl -X POST "https://api-docs.koel.dev/api/user" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"name":"John Doe","email":"john@doe.com","password":"SoSecureMuchW0w","is_admin":false}'
const url = new URL("https://api-docs.koel.dev/api/user");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "name": "John Doe",
    "email": "john@doe.com",
    "password": "SoSecureMuchW0w",
    "is_admin": false
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "id": 42,
    "name": "John Doe",
    "email": "john@doe.com",
    "is_admin": true
}

HTTP Request

POST api/user

Body Parameters

Parameter Type Status Description
name string required User's name.
email string required User's email.
password string required User's password.
is_admin boolean required Whether the user is an admin

Update a user

Example request:

curl -X PUT "https://api-docs.koel.dev/api/user/1" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"name":"Johny Doe","email":"johny@doe.com","password":"soluta","is_admin":false}'
const url = new URL("https://api-docs.koel.dev/api/user/1");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "name": "Johny Doe",
    "email": "johny@doe.com",
    "password": "soluta",
    "is_admin": false
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "id": 42,
    "name": "John Doe",
    "email": "john@doe.com",
    "is_admin": true
}

HTTP Request

PUT api/user/{user}

PATCH api/user/{user}

Body Parameters

Parameter Type Status Description
name string required New name.
email string required New email.
password string optional New password (null/blank for no change)
is_admin boolean optional Whether the user is an admin

Delete a user

Example request:

curl -X DELETE "https://api-docs.koel.dev/api/user/1" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/user/1");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "DELETE",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[]

HTTP Request

DELETE api/user/{user}

Get current user's profile

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/me" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/me");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "id": 42,
    "name": "John Doe",
    "email": "john@doe.com"
}

HTTP Request

GET api/me

Update current user's profile

Example request:

curl -X PUT "https://api-docs.koel.dev/api/me" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"name":"Johny Doe","email":"johny@doe.com","password":"quaerat"}'
const url = new URL("https://api-docs.koel.dev/api/me");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "name": "Johny Doe",
    "email": "johny@doe.com",
    "password": "quaerat"
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[]

HTTP Request

PUT api/me

Body Parameters

Parameter Type Status Description
name string required New name.
email string required New email.
password string optional New password (null/blank for no change)

8. Settings

Save the application settings

Save the application settings. Right now there's only one setting to be saved (media_path).

Example request:

curl -X POST "https://api-docs.koel.dev/api/settings" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"media_path":"\/var\/www\/media\/"}'
const url = new URL("https://api-docs.koel.dev/api/settings");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "media_path": "\/var\/www\/media\/"
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[]

HTTP Request

POST api/settings

Body Parameters

Parameter Type Status Description
media_path string required Absolute path to the media folder.

AWS integration

These routes are meant for Amazon Web Services (AWS) integration with Koel. For more information, visit koel-aws.

Store a song

Create a new song or update an existing one with data sent from AWS.

Example request:

curl -X POST "https://api-docs.koel.dev/api/os/s3/song" 
const url = new URL("https://api-docs.koel.dev/api/os/s3/song");

let headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "POST",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

HTTP Request

POST api/os/s3/song

Remove a song

Remove a song whose information matches with data sent from AWS.

Example request:

curl -X DELETE "https://api-docs.koel.dev/api/os/s3/song" 
const url = new URL("https://api-docs.koel.dev/api/os/s3/song");

let headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "DELETE",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

HTTP Request

DELETE api/os/s3/song

Last.fm integration

Scrobble a song

Create a Last.fm scrobble entry for a song.

Example request:

curl -X POST "https://api-docs.koel.dev/api/1/scrobble/1" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/1/scrobble/1");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "POST",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

HTTP Request

POST api/{song}/scrobble/{timestamp}

Connect to Last.fm

Connect the current user to Last.fm. This is actually NOT an API request. The application should instead redirect the current user to this route, which will send them to Last.fm for authentication. After authentication is successful, the user will be redirected back to api/lastfm/callback?token=<Last.fm token>.

Example request:

curl -X GET -G "https://api-docs.koel.dev/api/lastfm/connect?jwt-token=ea" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/lastfm/connect");

    let params = {
            "jwt-token": "ea",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[]

Example response (500):

{
    "message": "No application encryption key has been specified.",
    "exception": "RuntimeException",
    "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Encryption\/EncryptionServiceProvider.php",
    "line": 44,
    "trace": [
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Support\/helpers.php",
            "line": 1124,
            "function": "Illuminate\\Encryption\\{closure}",
            "class": "Illuminate\\Encryption\\EncryptionServiceProvider",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Encryption\/EncryptionServiceProvider.php",
            "line": 48,
            "function": "tap"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Encryption\/EncryptionServiceProvider.php",
            "line": 24,
            "function": "key",
            "class": "Illuminate\\Encryption\\EncryptionServiceProvider",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 785,
            "function": "Illuminate\\Encryption\\{closure}",
            "class": "Illuminate\\Encryption\\EncryptionServiceProvider",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 667,
            "function": "build",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 615,
            "function": "resolve",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Application.php",
            "line": 767,
            "function": "make",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 1227,
            "function": "make",
            "class": "Illuminate\\Foundation\\Application",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Session\/SessionManager.php",
            "line": 189,
            "function": "offsetGet",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Session\/SessionManager.php",
            "line": 176,
            "function": "buildEncryptedSession",
            "class": "Illuminate\\Session\\SessionManager",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Session\/SessionManager.php",
            "line": 62,
            "function": "buildSession",
            "class": "Illuminate\\Session\\SessionManager",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Session\/SessionManager.php",
            "line": 49,
            "function": "createNativeDriver",
            "class": "Illuminate\\Session\\SessionManager",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Support\/Manager.php",
            "line": 96,
            "function": "createFileDriver",
            "class": "Illuminate\\Session\\SessionManager",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Support\/Manager.php",
            "line": 71,
            "function": "createDriver",
            "class": "Illuminate\\Support\\Manager",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Session\/SessionServiceProvider.php",
            "line": 47,
            "function": "driver",
            "class": "Illuminate\\Support\\Manager",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 785,
            "function": "Illuminate\\Session\\{closure}",
            "class": "Illuminate\\Session\\SessionServiceProvider",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 667,
            "function": "build",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 615,
            "function": "resolve",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Application.php",
            "line": 767,
            "function": "make",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 1227,
            "function": "make",
            "class": "Illuminate\\Foundation\\Application",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Auth\/AuthManager.php",
            "line": 125,
            "function": "offsetGet",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Auth\/AuthManager.php",
            "line": 94,
            "function": "createSessionDriver",
            "class": "Illuminate\\Auth\\AuthManager",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Auth\/AuthManager.php",
            "line": 68,
            "function": "resolve",
            "class": "Illuminate\\Auth\\AuthManager",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Auth\/AuthServiceProvider.php",
            "line": 43,
            "function": "guard",
            "class": "Illuminate\\Auth\\AuthManager",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 785,
            "function": "Illuminate\\Auth\\{closure}",
            "class": "Illuminate\\Auth\\AuthServiceProvider",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 667,
            "function": "build",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 615,
            "function": "resolve",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Application.php",
            "line": 767,
            "function": "make",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 927,
            "function": "make",
            "class": "Illuminate\\Foundation\\Application",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 855,
            "function": "resolveClass",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 816,
            "function": "resolveDependencies",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 667,
            "function": "build",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 615,
            "function": "resolve",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Application.php",
            "line": 767,
            "function": "make",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Route.php",
            "line": 233,
            "function": "make",
            "class": "Illuminate\\Foundation\\Application",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Route.php",
            "line": 833,
            "function": "getController",
            "class": "Illuminate\\Routing\\Route",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Route.php",
            "line": 794,
            "function": "controllerMiddleware",
            "class": "Illuminate\\Routing\\Route",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Router.php",
            "line": 693,
            "function": "gatherMiddleware",
            "class": "Illuminate\\Routing\\Route",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Router.php",
            "line": 673,
            "function": "gatherRouteMiddleware",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Router.php",
            "line": 657,
            "function": "runRouteWithinStack",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Router.php",
            "line": 623,
            "function": "runRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Router.php",
            "line": 612,
            "function": "dispatchToRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Http\/Kernel.php",
            "line": 176,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Pipeline.php",
            "line": 30,
            "function": "Illuminate\\Foundation\\Http\\{closure}",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/app\/Http\/Middleware\/ForceHttps.php",
            "line": 25,
            "function": "Illuminate\\Routing\\{closure}",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php",
            "line": 163,
            "function": "handle",
            "class": "App\\Http\\Middleware\\ForceHttps",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Http\/Middleware\/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Routing\\{closure}",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php",
            "line": 163,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Http\/Middleware\/TransformsRequest.php",
            "line": 21,
            "function": "Illuminate\\Routing\\{closure}",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php",
            "line": 163,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Http\/Middleware\/ValidatePostSize.php",
            "line": 27,
            "function": "Illuminate\\Routing\\{closure}",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php",
            "line": 163,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/app\/Http\/Middleware\/UseDifferentConfigIfE2E.php",
            "line": 23,
            "function": "Illuminate\\Routing\\{closure}",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php",
            "line": 163,
            "function": "handle",
            "class": "App\\Http\\Middleware\\UseDifferentConfigIfE2E",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Http\/Middleware\/CheckForMaintenanceMode.php",
            "line": 62,
            "function": "Illuminate\\Routing\\{closure}",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php",
            "line": 163,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\{closure}",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Pipeline\/Pipeline.php",
            "line": 104,
            "function": "Illuminate\\Routing\\{closure}",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Http\/Kernel.php",
            "line": 151,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Http\/Kernel.php",
            "line": 116,
            "function": "sendRequestThroughRouter",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/mpociot\/laravel-apidoc-generator\/src\/Strategies\/Responses\/ResponseCalls.php",
            "line": 292,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/mpociot\/laravel-apidoc-generator\/src\/Strategies\/Responses\/ResponseCalls.php",
            "line": 274,
            "function": "callLaravelRoute",
            "class": "Mpociot\\ApiDoc\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/mpociot\/laravel-apidoc-generator\/src\/Strategies\/Responses\/ResponseCalls.php",
            "line": 46,
            "function": "makeApiCall",
            "class": "Mpociot\\ApiDoc\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/mpociot\/laravel-apidoc-generator\/src\/Tools\/Generator.php",
            "line": 147,
            "function": "__invoke",
            "class": "Mpociot\\ApiDoc\\Strategies\\Responses\\ResponseCalls",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/mpociot\/laravel-apidoc-generator\/src\/Tools\/Generator.php",
            "line": 108,
            "function": "iterateThroughStrategies",
            "class": "Mpociot\\ApiDoc\\Tools\\Generator",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/mpociot\/laravel-apidoc-generator\/src\/Tools\/Generator.php",
            "line": 72,
            "function": "fetchResponses",
            "class": "Mpociot\\ApiDoc\\Tools\\Generator",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/mpociot\/laravel-apidoc-generator\/src\/Commands\/GenerateDocumentation.php",
            "line": 233,
            "function": "processRoute",
            "class": "Mpociot\\ApiDoc\\Tools\\Generator",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/mpociot\/laravel-apidoc-generator\/src\/Commands\/GenerateDocumentation.php",
            "line": 84,
            "function": "processRoutes",
            "class": "Mpociot\\ApiDoc\\Commands\\GenerateDocumentation",
            "type": "->"
        },
        {
            "function": "handle",
            "class": "Mpociot\\ApiDoc\\Commands\\GenerateDocumentation",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/BoundMethod.php",
            "line": 32,
            "function": "call_user_func_array"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/BoundMethod.php",
            "line": 90,
            "function": "Illuminate\\Container\\{closure}",
            "class": "Illuminate\\Container\\BoundMethod",
            "type": "::"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/BoundMethod.php",
            "line": 34,
            "function": "callBoundMethod",
            "class": "Illuminate\\Container\\BoundMethod",
            "type": "::"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Container\/Container.php",
            "line": 576,
            "function": "call",
            "class": "Illuminate\\Container\\BoundMethod",
            "type": "::"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Console\/Command.php",
            "line": 183,
            "function": "call",
            "class": "Illuminate\\Container\\Container",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/symfony\/console\/Command\/Command.php",
            "line": 255,
            "function": "execute",
            "class": "Illuminate\\Console\\Command",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Console\/Command.php",
            "line": 170,
            "function": "run",
            "class": "Symfony\\Component\\Console\\Command\\Command",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/symfony\/console\/Application.php",
            "line": 1012,
            "function": "run",
            "class": "Illuminate\\Console\\Command",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/symfony\/console\/Application.php",
            "line": 272,
            "function": "doRunCommand",
            "class": "Symfony\\Component\\Console\\Application",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/symfony\/console\/Application.php",
            "line": 148,
            "function": "doRun",
            "class": "Symfony\\Component\\Console\\Application",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Console\/Application.php",
            "line": 90,
            "function": "run",
            "class": "Symfony\\Component\\Console\\Application",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Console\/Kernel.php",
            "line": 133,
            "function": "run",
            "class": "Illuminate\\Console\\Application",
            "type": "->"
        },
        {
            "file": "\/opt\/build\/repo\/artisan",
            "line": 35,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Console\\Kernel",
            "type": "->"
        }
    ]
}

HTTP Request

GET api/lastfm/connect

Query Parameters

Parameter Status Description
jwt-token required The JWT token of the user.

Set Last.fm session key

Set the Last.fm session key for the current user. This call should be made after the user is connected to Last.fm.

Example request:

curl -X POST "https://api-docs.koel.dev/api/lastfm/session-key" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"key":"ut"}'
const url = new URL("https://api-docs.koel.dev/api/lastfm/session-key");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "key": "ut"
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

[]

HTTP Request

POST api/lastfm/session-key

Body Parameters

Parameter Type Status Description
key string required The Last.fm session key.

general

api/upload

Example request:

curl -X POST "https://api-docs.koel.dev/api/upload" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/api/upload");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "POST",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

HTTP Request

POST api/upload

Authenticate the request for channel access.

Example request:

curl -X GET -G "https://api-docs.koel.dev/broadcasting/auth" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://api-docs.koel.dev/broadcasting/auth");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response:

null

HTTP Request

GET broadcasting/auth

POST broadcasting/auth