🏷️ Expose your Discord presence and activities to a RESTful API and WebSocket in less than 10 seconds
Lanyard is a service that makes it super easy to export your live Discord presence to an API endpoint (api.lanyard.rest/v1/users/:your_id
) and to a WebSocket (see below) for you to use wherever you want - for example, I use this to display what I'm listening to on Spotify on my personal website.
You can use Lanyard's API without deploying anything yourself - but if you want to self host it, you have the option to, though it'll require a tiny bit of configuration.
Just join this Discord server and your presence will start showing up when you GET api.lanyard.rest/v1/users/:your_id
. It's that easy.
GET https://api.lanyard.rest/v1/users/:user_id
Example response:
{
"success": true,
"data": {
"active_on_discord_mobile": false,
"active_on_discord_desktop": true,
"listening_to_spotify": true,
// Below is a custom crafted "spotify" object, which will be null if listening_to_spotify is false
"spotify": {
"timestamps": {
"start": 1615529820677,
"end": 1615530068733
},
"song": "Let Go",
"artist": "Ark Patrol; Veronika Redd",
"album_art_url": "https://i.scdn.co/image/ab67616d0000b27364840995fe43bb2ec73a241d",
"album": "Let Go"
},
"discord_user": {
"username": "Phineas",
"public_flags": 131584,
"id": "94490510688792576",
"discriminator": "0001",
"avatar": "a_7484f82375f47a487f41650f36d30318"
},
"discord_status": "online",
// activities contains the plain Discord activities array that gets sent down with presences
"activities": [
{
"type": 2,
"timestamps": {
"start": 1615529820677,
"end": 1615530068733
},
"sync_id": "3kdlVcMVsSkbsUy8eQcBjI",
"state": "Ark Patrol; Veronika Redd",
"session_id": "140ecdfb976bdbf29d4452d492e551c7",
"party": {
"id": "spotify:94490510688792576"
},
"name": "Spotify",
"id": "spotify:1",
"flags": 48,
"details": "Let Go",
"created_at": 1615529838051,
"assets": {
"large_text": "Let Go",
"large_image": "spotify:ab67616d0000b27364840995fe43bb2ec73a241d"
}
},
{
"type": 0,
"timestamps": {
"start": 1615438153941
},
"state": "Workspace: lanyard",
"name": "Visual Studio Code",
"id": "66b84f5317e9de6c",
"details": "Editing README.md",
"created_at": 1615529838050,
"assets": {
"small_text": "Visual Studio Code",
"small_image": "565945770067623946",
"large_text": "Editing a MARKDOWN file",
"large_image": "565945077491433494"
},
"application_id": 383226320970055681
}
]
}
}
The websocket is available at wss://api.lanyard.rest/socket
. If you would like to use compression, please specify ?compression=zlib
at the end of the URL.
Once connected, you will receive Opcode 1: Hello which will contain heartbeat_interval in the data field. You should set a repeating interval for the time specified in heartbeat_interval which should send Opcode 3: Heartbeat on the interval. You should also be sending Opcode 2: Initialize immediately once connected.
Example of Opcode 2: Initialize
:
{
op: 2,
d: {
// subscribe_to_ids should be an array of user IDs you want to subscribe to presences from
// if Lanyard doesn't monitor an ID specified, it won't be included in INIT_STATE
subscribe_to_ids: ["94490510688792576"]
}
}
If you just want to subscribe to one user, you can send subscribe_to_id
instead with a string of a single user ID to subscribe to. Then, the INIT_STATE's data will just contain the presence object for the user you've subscribed to instead of a user_id->presence map.
Once sent, you should immediately receive a INIT_STATE
event payload if connected successfully. If not, you will be disconnected with an error (see below).
Opcode | Name | Description | Client Send/Recv |
---|---|---|---|
0 | Event | This is the default opcode when receiving core events from Lanyard, like INIT_STATE |
Receive |
1 | Hello | Lanyard sends this when clients initially connect, and it includes the heartbeat interval | Receive Only |
2 | Initialize | This is what the client sends when receiving Opcode 1 from Lanyard - it should contain an array of user IDs to subscribe to | Send only |
3 | Heartbeat | Clients should send Opcode 3 every 30 seconds (or whatever the Hello Opcode says to heartbeat at) | Send only |
Events are received on Opcode 0: Event
- the event type will be part of the root message object under the t
key.
{
op: 0,
seq: 1,
t: "INIT_STATE",
d: {
"94490510688792576": {
// Full Lanyard presence (see API docs above for example)
}
}
}
{
op: 0,
seq: 2,
t: "PRESENCE_UPDATE",
d: {
// Full Lanyard presence and an extra "user_id" field
}
}
Lanyard can disconnect clients for multiple reasons, usually to do with messages being badly formatted. Please refer to your WebSocket client to see how you should handle errors - they do not get received as regular messages.
Name | Code | Data |
---|---|---|
Invalid/Unknown Opcode | 4004 | unknown_opcode |
Below is a list of sites using Lanyard right now, check them out! A lot of them will only show an activity when they're active. Create a PR to add your site below!
- alistair.cloud
- timcole.me
- dustin.sh
- phineas.io
- juan.engineer
- slayter.dev
- lafond.dev
- atzu.studio
- dont-ping.me
- astn.me
- eggsy.xyz
- crugg.de
- igalaxy.dev
- itspolar.dev
- vasc.dev
- eri.gg
- voided.dev
- thicc-thighs.de
- ademcancertel.tech
- chezzer.dev
- arda.codes
- looskie.com
- barbarbar338.fly.dev
- marino.codes
- stealthwave.dev
- miraichu.co
- bobby.systems
- dann.systems
- meric.vercel.app
- spotsync.me
- nith.codes
- callumdev.xyz
- domm.me
- rafstech.link
- Landing page?