{"openapi":"3.0.3","info":{"title":"NexusHub public API","version":"1"},"paths":{"/health":{"get":{"summary":"Liveness probe.","description":"Auth: none. Example: {\u0022ok\u0022:true,\u0022service\u0022:\u0022nexushub-api\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"service":{"type":"string"}}}}}}}}},"/v1/account/resolve":{"post":{"summary":"Resolve the account behind an install id.","description":"Auth: none. Example: {\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"installId":{"type":"string"}}},"example":"{\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022}"}}}}},"/v1/balance":{"get":{"summary":"Coin balance of the caller (query installId when no session).","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: GET /v1/balance?installId=\u003Cinstall-id\u003E","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"balanceCoins":{"type":"number"}}}}}}}}},"/v1/coins/credit":{"post":{"summary":"Credit coins (idempotent by key).","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: {\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022,\u0022coins\u0022:10,\u0022key\u0022:\u0022\u003Cidem-key\u003E\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"balanceAfterCoins":{"type":"number"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"installId":{"type":"string"},"coins":{"type":"number"},"key":{"type":"string"}}},"example":"{\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022,\u0022coins\u0022:10,\u0022key\u0022:\u0022\u003Cidem-key\u003E\u0022}"}}}}},"/v1/coins/purchase":{"post":{"summary":"Record a coin purchase.","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: {\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022,\u0022coins\u0022:100,\u0022key\u0022:\u0022\u003Cidem-key\u003E\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"balanceAfterCoins":{"type":"number"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"installId":{"type":"string"},"coins":{"type":"number"},"key":{"type":"string"}}},"example":"{\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022,\u0022coins\u0022:100,\u0022key\u0022:\u0022\u003Cidem-key\u003E\u0022}"}}}}},"/v1/coins/debit":{"post":{"summary":"Spend coins (idempotent by key).","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: {\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022,\u0022coins\u0022:5,\u0022key\u0022:\u0022\u003Cidem-key\u003E\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"balanceAfterCoins":{"type":"number"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"installId":{"type":"string"},"coins":{"type":"number"},"key":{"type":"string"}}},"example":"{\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022,\u0022coins\u0022:5,\u0022key\u0022:\u0022\u003Cidem-key\u003E\u0022}"}}}}},"/v1/highscores/{game}":{"get":{"summary":"Top 10 scores of a game.","description":"Auth: none. Example: GET /v1/highscores/atomarium","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"game":{"type":"string"},"top":{"type":"array"}}}}}}},"parameters":[{"name":"game","in":"path","required":true,"schema":{"type":"string"}}]},"post":{"summary":"Submit a score.","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: {\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022,\u0022score\u0022:1200,\u0022name\u0022:\u0022Player\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"rank":{"type":"number"},"personalBest":{"type":"boolean"},"top":{"type":"array"}}}}}}},"parameters":[{"name":"game","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"installId":{"type":"string"},"score":{"type":"number"},"name":{"type":"string"}}},"example":"{\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022,\u0022score\u0022:1200,\u0022name\u0022:\u0022Player\u0022}"}}}}},"/v1/catalogue":{"get":{"summary":"Apps in the portfolio (aliases /v1/apps, /v1/lobby/catalogue).","description":"Auth: none. Example: GET /v1/catalogue","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"apps":{"type":"array"},"count":{"type":"number"}}}}}}}}},"/v1/pair/new":{"post":{"summary":"Website asks for a QR pairing token.","description":"Auth: none. Example: {}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"token":{"type":"string"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{}},"example":"{}"}}}}},"/v1/pair/claim":{"post":{"summary":"App claims a pairing token.","description":"Auth: none. Example: {\u0022token\u0022:\u0022\u003Ctoken\u003E\u0022,\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"installId":{"type":"string"}}},"example":"{\u0022token\u0022:\u0022\u003Ctoken\u003E\u0022,\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022}"}}}}},"/v1/pair/status":{"get":{"summary":"Website polls a pairing token.","description":"Auth: none. Example: GET /v1/pair/status?token=\u003Ctoken\u003E","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"status":{"type":"string"}}}}}}}}},"/v1/rooms":{"post":{"summary":"Create a game room; /v1/rooms/{code}/{action} joins/starts.","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: {\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"room":{"type":"object"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"installId":{"type":"string"}}},"example":"{\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022}"}}}}},"/v1/rooms/{code}":{"get":{"summary":"Read a room\u0027s public state.","description":"Auth: none. Example: GET /v1/rooms/ABCD","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"room":{"type":"object"}}}}}}},"parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}]}},"/v1/login":{"post":{"summary":"Sign in (also /login on the site host).","description":"Auth: none. Example: {\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"installId":{"type":"string"}}},"example":"{\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022}"}}}}},"/v1/logout":{"post":{"summary":"Sign out.","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: {}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{}},"example":"{}"}}}}},"/v1/session":{"get":{"summary":"Who am I.","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: GET /v1/session","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"authenticated":{"type":"boolean"}}}}}}}}},"/v1/subscription":{"get":{"summary":"Subscriber flag of the caller.","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: GET /v1/subscription","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"subscribed":{"type":"boolean"}}}}}}}}},"/v1/subscription/report":{"post":{"summary":"App reports its subscription state.","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: {\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022,\u0022subscribed\u0022:true}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"installId":{"type":"string"},"subscribed":{"type":"boolean"}}},"example":"{\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022,\u0022subscribed\u0022:true}"}}}}},"/v1/coins/history":{"get":{"summary":"Coin history of the caller.","description":"Auth: session cookie required. Example: GET /v1/coins/history","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"entries":{"type":"array"}}}}}}}}},"/v1/entitlement":{"get":{"summary":"Entitlement decision of the caller.","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: GET /v1/entitlement","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"state":{"type":"string"}}}}}}}}},"/v1/entitlement/first-run":{"post":{"summary":"Record first run of an app.","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: {\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"installId":{"type":"string"}}},"example":"{\u0022installId\u0022:\u0022\u003Cinstall-id\u003E\u0022}"}}}}},"/v1/subscription/purchase":{"post":{"summary":"Record a subscription purchase.","description":"Auth: session cookie (signed nh_session); optional unless stated. Example: {\u0022purchaseToken\u0022:\u0022\u003Ctoken\u003E\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"purchaseToken":{"type":"string"}}},"example":"{\u0022purchaseToken\u0022:\u0022\u003Ctoken\u003E\u0022}"}}}}},"/v1/trial/touch":{"post":{"summary":"Start or touch this device\u0027s trial.","description":"Auth: none. Example: {\u0022deviceId\u0022:\u0022\u003Cdevice-id\u003E\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"string"}}},"example":"{\u0022deviceId\u0022:\u0022\u003Cdevice-id\u003E\u0022}"}}}}},"/v1/trial/status":{"get":{"summary":"Trial status of this device.","description":"Auth: none. Example: GET /v1/trial/status","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"active":{"type":"boolean"}}}}}}}}},"/v1/trial/link":{"post":{"summary":"Link this device\u0027s trial to the signed-in account.","description":"Auth: session cookie required. Example: {}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{}},"example":"{}"}}}}},"/v1/account/play-provision":{"post":{"summary":"Provision an account from a Play sign-in.","description":"Auth: none. Example: {\u0022token\u0022:\u0022\u003Cplay-token\u003E\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"}}},"example":"{\u0022token\u0022:\u0022\u003Cplay-token\u003E\u0022}"}}}}},"/v1/account/play-install/nonce":{"get":{"summary":"Nonce for a Play Integrity install proof.","description":"Auth: none. Example: GET /v1/account/play-install/nonce","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"nonce":{"type":"string"}}}}}}}}},"/v1/account/play-install":{"post":{"summary":"Prove a Play install (Integrity token).","description":"Auth: none. Example: {\u0022nonce\u0022:\u0022\u003Cnonce\u003E\u0022,\u0022integrityToken\u0022:\u0022\u003Ctoken\u003E\u0022}","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"nonce":{"type":"string"},"integrityToken":{"type":"string"}}},"example":"{\u0022nonce\u0022:\u0022\u003Cnonce\u003E\u0022,\u0022integrityToken\u0022:\u0022\u003Ctoken\u003E\u0022}"}}}}}}}