Introduction
Add play tracking to your app
retroshelf's API lets your emulator, launcher, or app record what a player plays to their retroshelf activity. When a play session ends, send the game, play time, and timestamp, and retroshelf logs it automatically.
Begin by applying for a client ID. Once approved, link players with the device-code flow and send completed play sessions in the background.
Authentication
Device flow overview
Request a device code with your approved client ID.
Show the user code and verification URL to the user.
Poll the token endpoint until the user approves access.
Send the bearer token with completeLink and syncSessions.
/api/auth/device/codeRequest a device code
Creates a short user code and verification URL for the OAuth device flow.
| Field | Type | Required | Description |
|---|---|---|---|
| client_id | string | Yes | The client ID issued after your integration application is approved. |
Request
{
"client_id": "rs_your_client_id"
}Response
{
"device_code": "internal-device-code",
"user_code": "483921",
"verification_uri": "https://retroshelf.org/link",
"expires_in": 1800,
"interval": 5
}/api/auth/device/tokenPoll for an access token
Poll at the returned interval until the user approves the code.
| Field | Type | Required | Description |
|---|---|---|---|
| grant_type | string | Yes | Use urn:ietf:params:oauth:grant-type:device_code. |
| device_code | string | Yes | The internal device code returned by the device-code endpoint. |
| client_id | string | Yes | The same approved client ID used to request the device code. |
Request
{
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
"device_code": "internal-device-code",
"client_id": "rs_your_client_id"
}Response
{
"access_token": "bearer_access_token",
"token_type": "Bearer"
}/api/syncClient/completeLinkRegister or reconnect an installation
Creates the sync client record used by later play-session uploads.
Authorization: Bearer access_token
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | No | A user-visible name for the emulator, launcher, or device installation. |
| platform | string | Yes | Currently supported values: onionos, knulli, muos, rocknix, android, spruceos. |
| fingerprint | string | No | A stable local identifier used to reconnect the same installation. |
| deviceSlug | string | No | Known retroshelf device slug when the integration can identify hardware. |
| metadata | object | No | Version or implementation details useful for support and debugging. |
Request
{
"name": "ExampleEmu",
"platform": "android",
"fingerprint": "stable-device-id",
"deviceSlug": "retroid-pocket-5",
"metadata": {
"version": "1.2.3"
}
}Response
{
"syncClientId": "sync_client_id",
"lastSyncCursor": null
}/api/syncClient/syncSessionsUpload play sessions
Sends completed play sessions. Offline clients should queue sessions locally and retry with the same values.
Authorization: Bearer access_token
| Field | Type | Required | Description |
|---|---|---|---|
| syncClientId | string | Yes | The sync client ID returned by completeLink. |
| sessions[].romPath | string | Yes | The path or filename available to the emulator or launcher. |
| sessions[].duration | number | Yes | Session length in seconds. |
| sessions[].devicePlayedAt | number | Yes | Unix timestamp, in seconds, for when the session happened on the device. |
| sessions[].romName | string | No | Clean game name when available. Used before falling back to romPath matching. |
| sessions[].romHash | string | No | ROM hash when available. |
| sessions[].platformHint | string | No | Console or platform hint, such as snes, gba, psx, or arcade. |
Request
{
"syncClientId": "sync_client_id_from_completeLink",
"sessions": [
{
"romPath": "Roms/SFC/Chrono Trigger.sfc",
"romName": "Chrono Trigger",
"romHash": "optional-rom-hash",
"duration": 5400,
"devicePlayedAt": 1781229600,
"platformHint": "snes"
}
]
}Response
{
"synced": 1,
"matched": 1,
"unmatched": 0,
"results": [
{
"romPath": "Roms/SFC/Chrono Trigger.sfc",
"matched": true,
"gameId": "game_id",
"gameName": "Chrono Trigger"
}
]
}