NodeLink REST
Use node.rest for typed helpers. Authentication and the configured request
timeout are applied by the client. Helpers require a valid session for
player-scoped operations; prefer calls after the node's ready handshake.
Shared Endpointsโ
| Helper | HTTP route |
|---|---|
manager.search() | GET /v4/loadtracks?identifier=... |
getPlayer(guildId) | GET /v4/sessions/{sessionId}/players/{guildId} |
getPlayers() | GET /v4/sessions/{sessionId}/players |
updatePlayer(options) | PATCH /v4/sessions/{sessionId}/players/{guildId} |
destroyPlayer(guildId) | DELETE /v4/sessions/{sessionId}/players/{guildId} |
updateSession(resuming, timeout) | PATCH /v4/sessions/{sessionId} |
decodeTrack(encoded) | GET /v4/decodetrack?encodedTrack=... |
decodeTracks(encoded[]) | POST /v4/decodetracks |
getInfo() | GET /v4/info |
getStats() | GET /v4/stats |
Bulk decoding sends a JSON array, not a double-encoded JSON string. A NodeLink
{ tracks } response is normalized to the returned array.
NodeLink's cpu.nodelinkLoad is accepted and supplies the fallback
cpu.lavalinkLoad value in normalized REST stats.
const remotePlayers = await node.rest.getPlayers();
const info = await node.rest.getInfo();
const decoded = await node.rest.decodeTracks([track.track]);
Sessions and Bulk-Player Fallbackโ
getPlayers() returns [] when there is no active session. If a server rejects
the bulk endpoint with HTTP 400, it can fall back to individual requests for
players this manager already knows on that node. This fallback is not a complete
inventory of remote players belonging to other clients or unknown local state.
With no active session, getPlayer(), updatePlayer(), and updateSession()
currently return null at runtime despite their declared promise types;
destroyPlayer() becomes a no-op. Do not use disconnected-node return values
as confirmation of a server-side update.
Native REST Helpersโ
These reject when the node is not NodeLink.
| Helper | HTTP route |
|---|---|
getNodeLinkConnection() | GET /v4/connection |
encodeNodeLinkTrack(metadata) | GET /v4/encodetrack?track=... |
encodeNodeLinkTracks(metadata[]) | POST /v4/encodedtracks |
getNodeLinkMeaning(encoded, language?) | GET /v4/meaning?encodedTrack=...&lang=... |
getNodeLinkTrackStream(encoded, itag?) | GET /v4/trackstream?encodedTrack=...&itag=... |
loadNodeLinkPcmStream(encoded, options?) | POST /v4/loadstream |
The batch encode path is spelled encodedtracks by the backend.
The default meaning language is en. The stream-resolution helper returns
metadata/URL JSON; it is not the raw audio body.
const encoded = await node.rest.encodeNodeLinkTrack({
title: "Example audio",
author: "Example author",
length: 60000,
identifier: "https://example.com/audio.mp3",
isStream: false,
uri: "https://example.com/audio.mp3",
artworkUrl: null,
isrc: null,
sourceName: "http",
position: 0,
details: [],
});
This is metadata encoding only. Replace the example URL with an actual supported audio resource before attempting playback. The batch encoder rejects an empty input array.
Consume PCM Responsesโ
const response = await node.rest.loadNodeLinkPcmStream(track.track, {
volume: 100,
position: 0,
});
const reader = response.body?.getReader();
if (reader) {
try {
while (true) {
const chunk = await reader.read();
if (chunk.done) break;
consumePcmChunk(chunk.value);
}
} finally {
await reader.cancel();
reader.releaseLock();
}
}
consumePcmChunk is your consumer, not a Magmastream method.
The return value is an Undici Response. Consume or cancel the body, rather than
treating it as JSON. The configured timeout covers opening the response; it is
cleared after headers arrive and is not a total-duration limit for the body.
Non-2xx responses reject.
Player-Scoped Native Routesโ
The following routes are relative to /v4/sessions/{sessionId}/players/{guildId}.
Use the Node/Player wrappers for backend guards and local behavior.
| Operation | Native route |
|---|---|
| Preload, fading, normalization, audio-track selection | PATCH player with Update Player extras |
| List/add mixer layers | GET /mix, POST /mix |
| Update/remove mixer layer | PATCH /mix/{mixId}, DELETE /mix/{mixId} |
| Read/update SponsorBlock state | GET /sponsorblock, PATCH /sponsorblock |
| Replace SponsorBlock segments | POST /sponsorblock with { segments } |
| Delete SponsorBlock configuration | DELETE /sponsorblock |
| Subscribe/unsubscribe lyrics | POST /lyrics/subscribe, DELETE /lyrics/subscribe |
Track metadata uses GET /v4/loadlyrics?encodedTrack=...&lang=... and
GET /v4/loadchapters?encodedTrack=.... Voice receive uses the separate
/v4/websocket/voice/{guildId} WebSocket.
See playback, metadata, and voice for high-level examples.
Lavalink Route Plannerโ
Typed route-planner helpers target Lavalink's contract:
getRoutePlannerStatus():GET /v4/routeplanner/statusfreeRoutePlannerAddress(address):POST /v4/routeplanner/free/addressfreeAllRoutePlannerAddresses():POST /v4/routeplanner/free/all
Do not assume NodeLink administrative responses match RoutePlannerStatus.
Generic Requestsโ
get<T>(), patch<T>(), post<T>(), put<T>(), and delete() remain
available for routes without a dedicated helper. Supply an endpoint path and a
structured body where applicable; post() now accepts an omitted body.
Generic requests do not imply validation or typed normalization of arbitrary backend/plugin endpoints. These release docs cover the implemented client surface, not every operational/server-admin feature.