Sign in
Documentation

Everything you need to plug in Lavahost.

These docs cover how to point your Discord bot at Lavahost, search for and play tracks, and manage your account. They're aimed at developers integrating an existing Lavalink client — no prior infrastructure setup needed.

── 01

Quick start

From zero to playing audio in about a minute:

  1. 1
    Open the dashboard, click Create key, copy the key it shows (it's only displayed once).
  2. 2
    Drop the host, port, and key into your Lavalink client's config. Endpoint values are shown above on the dashboard:
    host: "gateway.lavahost.net", port: 443, secure: true
  3. 3
    In your bot, call player.search("your query") then player.play(). That's it.
New to Lavalink? It's a JVM-based audio-sending server that Discord bots talk to over WebSocket and REST. Your bot sends commands like "play this track", Lavalink streams the audio into the Discord voice channel. We host the Lavalink — you just speak the protocol.
── 02

Connection details

Your account gets one endpoint shared across every bot you connect. The same host serves both the WebSocket (events) and the REST API (commands).

Host
gateway.lavahost.net
Port
443
Secure
yes
Authentication
Authorization header
WebSocket
wss://gateway.lavahost.net:443/v4/websocket
REST base
https://gateway.lavahost.net:443/v4

Every request must include your API key in the Authorization header. WebSocket connections also need User-Id (your bot's Discord user-id) and an optional Client-Name for logging.

Headers on the WebSocket upgrade
Authorizationlh_<your-key>
User-Id123456789012345678
Client-Namemy-bot/1.0 (optional)
Session-Id<previous-session-id> (optional, for resume)
── 03

Client libraries

Lavahost speaks Lavalink v4 — anything that supports the v4 protocol works without modification. Below are configs for the most common clients.

lavalink-client (Node.js, TypeScript)v4
$ npm install lavalink-client
import { LavalinkManager } from "lavalink-client"; const manager = new LavalinkManager({ nodes: [ { id: "lavahost", host: "gateway.lavahost.net", port: 443, authorization: process.env.LAVAHOST_KEY, secure: true, }, ], sendToShard: (id, p) => client.guilds.cache.get(id)?.shard?.send(p), client: { id: client.user.id }, }); client.on("raw", (d) => manager.sendRawData(d)); client.once("ready", () => manager.init({ id: client.user.id }));
shoukaku (Node.js)v4
$ npm install shoukaku
import { Shoukaku, Connectors } from "shoukaku"; const nodes = [{ name: "lavahost", url: "gateway.lavahost.net:443", auth: process.env.LAVAHOST_KEY, secure: true, }]; const shoukaku = new Shoukaku( new Connectors.DiscordJS(client), nodes, );
lavalink.py (Python)v4
$ pip install lavalink
import lavalink client.lavalink = lavalink.Client(bot.user.id) client.lavalink.add_node( host="gateway.lavahost.net", port=443, password=os.environ["LAVAHOST_KEY"], region="global", ssl=True, )
Lavalink4NET (C#)v4
$ dotnet add package Lavalink4NET
services.AddLavalink(); services.ConfigureLavalink(options => { options.BaseAddress = new Uri("https://gateway.lavahost.net:443/"); options.WebSocketUri = new Uri("wss://gateway.lavahost.net:443/v4/websocket"); options.Passphrase = Environment.GetEnvironmentVariable("LAVAHOST_KEY"); });
Don't see your library? If it speaks Lavalink v4, it will work — the host, port, and authorisation values are all you need.
── 05

API keys

API keys are how your bot identifies itself to Lavahost. Keys are scoped to your account; one key can connect any number of bots, but issuing one per bot makes usage easier to attribute and lets you revoke a single bot without affecting the others.

Format

lh_ followed by 48 hex characters. Always send it as the Authorization header on every WebSocket upgrade and every REST call:

Authorization: lh_a1b2c3d4e5f6…

Storage

The full plaintext key is shown only once, when you click Create key on the dashboard. Store it in your bot's secret manager (a .env file, a hosted secret store, etc.) and never commit it to a public repo. We never display it again — if you lose it, revoke and reissue.

Revoking

Hit Revoke on the dashboard. The next request the bot makes with that key returns 401 Unauthorized. Revocation is instant — no propagation delay.

If you suspect a key has leaked, revoke it immediately and reissue. Sessions opened with the revoked key stay alive until the bot reconnects (so the next reconnect attempt fails fast), or you can cycle the bot to disconnect now.
── 06

Sessions & resume

A "session" is one WebSocket connection. When your bot reconnects after a network blip, you can resume the previous session and Lavalink replays any events you missed — no audio interruption, no need to recreate players.

Enabling resume

After the first ready op:

PATCH /v4/sessions/{sessionId} { "resuming": true, "timeout": 60 }

Timeout is in seconds. Maximum allowed is 600. Most Lavalink client libraries configure this for you automatically.

Reconnecting

Reopen the WebSocket and include the previous Session-Id in the upgrade headers. The server responds with { op: "ready", resumed: true, sessionId: <same> } if the session was still alive, otherwise resumed: false and a fresh sessionId — rebuild your players from scratch when that happens.

Per-account scope

Sessions belong to the account that opened them. Another account using a guessed sessionId gets a 403 on every REST call and a clean close on WS resume.

── 07

Troubleshooting

401 Unauthorized on WS upgrade
  • API key is wrong or has been revoked.
  • Missing Authorization header.
  • Passing the key with a leading "Bot " prefix (Discord-style) — drop the prefix.
403 Forbidden on a sticky REST call
  • The sessionId in the path doesn't exist (expired, never opened, or typo).
  • The sessionId belongs to a different account.
400 Bad Request with "invalid" in the body
  • Your client sent an unrecognised field in the player update body (newer Lavalink protocol field, or a typo).
  • voice.endpoint isn't a valid Discord voice endpoint — usually means your client is forwarding the wrong Discord event payload.
  • volume out of range (allowed 0–1000), position negative, etc.
trackEnd with reason loadFailed immediately after trackStart
  • The track exists in our catalogue but couldn't be streamed (rare; usually a transient issue with the source). Try a different result from the same search.
  • Your bot lacks Speak permission in the voice channel.
Bot connects, plays, but no audio is heard
  • Bot is server-deafened or self-deafened (check Discord, not just Lavalink).
  • Voice channel permissions block Speak.
  • Voice region mismatch — Discord assigned a region the voice connection can't reach. Try moving to a different VC.
trackStuck event after a few seconds
  • Backend stopped producing frames — usually transient. The client should auto-skip after the threshold.
── 08

FAQ

Which Lavalink version does this support?
Lavalink v4 — every op, every event, every REST endpoint. Earlier versions (v3 and below) are not supported.
Can I run multiple bots on one account?
Yes. Best practice is one API key per bot — that way revoking one bot doesn't affect the others, and the dashboard's per-bot analytics stay clean. You can also share one key across all your bots if you prefer.
Do I need to set up YouTube / Spotify source plugins?
No. The built-in search source handles all of that. Just call search() with a query or a Spotify URL — no plugins to install, no API keys to manage, no rate limits to worry about.
What about audio quality?
Tracks stream as Opus in WebM at 192 kbps. The encoded bitrate is well above Discord's 96 kbps voice ceiling, so nothing is lost in transit.
What's the player limit?
Depends on your plan — see the dashboard for your current ceiling. Going over the limit returns a 503 on the next play request. PAYG accounts have no fixed cap.
Can I migrate from a self-hosted Lavalink?
Yes — point your bot at our host/port/key and remove the local Lavalink container. The protocol is identical, so no code changes are needed in your bot.
How do I contact support?
Email [email protected]. Include your account's Discord username and (if applicable) the sessionId from your dashboard for fast triage.