Client SDK & API Documentation

Proximity voice for your game

Your game backend decides who can hear whom. Wave delivers the voice: keys, access control, WebRTC signaling and STUN. No registration โ€” everything is identified by a single API key.

๐Ÿ”‘ 1 key = 1 game server ๐Ÿ”Š audio is P2P (WebRTC) ๐Ÿ“ก signaling relay for allowed pairs only ๐Ÿšซ server never hears the voice

Pricing

Get a key

No registration required. Paid plans are activated after payment (automated checkout is coming soon โ€” until then an operator activates your order). The Free plan is active immediately.

Check a key

Quick start โ€” how it works

๐ŸŽฎ
Your game backend announces the player
When a character enters the world, your server registers the player in Wave with an ID (e.g. 1050_Hero). This is done by your backend team โ€” the client cannot do it itself.
๐Ÿ”‘
The client connects
The launcher / overlay opens a Socket.io connection to /voice with the key and the exact same player ID. Wave accepts it only if your backend announced this player.
๐Ÿ“ก
Wave notifies about nearby players
When your backend marks two players as "close", both clients receive voice:peer-on. When they move apart โ€” voice:peer-off.
๐Ÿค
WebRTC handshake through the relay
Clients exchange offer / answer / ICE via voice:signal. The relay works only between allowed pairs.
๐Ÿ”Š
Audio flows peer-to-peer
Voice goes directly between players (STUN helps with NAT). Wave relays signaling only and never touches the audio.

REST API

MethodEndpointDescription
GET/api/voice/plansList available plans and prices
POST/api/voice/orderIssue a key. Body: { plan, serverIp, label }. Returns the key, the secret (once), expiry and payment status
GET/api/voice/key/:id/statusKey status: active / expired, online players, traffic stats
GET/voiceReady-made voice page for the launcher: ?key=...&player=...&auto=1
examples

    

Drop-in voice page (zero code)

The fastest integration: point a WebView2 / iframe / browser window at the ready-made voice page. It handles the microphone, WebRTC, nearby list and text chat for you.

ParameterRequiredDescription
keyyesYour API key (wg-...)
playeryesPlayer ID โ€” exactly the same string your game backend announces (URL-encode it)
autono1 โ€” try to enable the microphone automatically after the first user gesture

Socket.io protocol โ€” /voice

Connection handshake: auth = { role: "player", key: "wg-...", playerId: "1050_Hero" }. The player is accepted only while the game backend keeps the player announced.

connect

    
DirectionEventDescription
YOU โ†voice:peer-on { playerId, name }A player entered your hearing range โ€” start a WebRTC call
YOU โ†voice:peer-off { playerId }A player left the range โ€” hang up
YOU โ†voice:peer-name { playerId, name }Display name update for a connected peer
YOU โ†’voice:signal { to, data }WebRTC signaling (offer / answer / ICE) to an allowed peer
YOU โ†voice:signal { from, data }Incoming signaling from an allowed peer
YOU โ†’chat { text }Text message to everyone currently in range (max 500 chars)
YOU โ†chat { from, text }Incoming proximity text message
YOU โ†voice:error { error }Key expired / character left the game / kicked

WebRTC voice flow

Full reference implementation of the call logic. The deterministic initiator rule (myId < peerId creates the offer) prevents double offers when both players appear in range at the same moment.

webrtc-flow.js

    

Errors & rate limits

Error (connect_error / voice:error)Meaning
ERRInvalid key โ€” the key does not exist
ERRKey expired / Key revoked โ€” renew or replace the key
ERRKey not paid yet โ€” the order is waiting for payment
ERRPlayer not announced by game server โ€” the character is not in the game
ERRKey player limit โ€” the CCU cap of the plan is reached
LimitValue
Signaling messages30 / second per player
Chat messages5 / second, max 500 characters
Player ID formatAโ€“Z aโ€“z 0โ€“9 _ -, length 2โ€“80
Online playersper plan: 30 / 50 / 100 / 500 / 1000

Integration examples

๐Ÿ–ฅ
C# launcher โ€” WebView2
voice page embedded into a WinForms / WPF launcher

NuGet: Microsoft.Web.WebView2. The key is public and safe to ship in the launcher config. The secret must never be here.

LauncherVoice.cs

      
๐ŸŒ
HTML / JS โ€” full standalone client
mic, WebRTC, nearby list โ€” one page, no frameworks
voice-client.html

      
๐ŸŸข
Node.js โ€” headless client / testing
socket.io-client, events and chat
test-client.js

      

Dedicated server โ€” installation & full setup

Prefer your own infrastructure? We will deploy a dedicated Wave Voice instance on your own VPS and integrate it with your game โ€” you own the server, the keys and the data. Or let us run it for you.

๐Ÿ› 
Install & Configure
$79 one-time
  • Deployment on your VPS (Ubuntu / Debian / Docker)
  • Domain, ports & firewall configuration
  • Security hardening + first API keys
  • Documentation walkthrough for your team
  • 7 days of support
Request setup
๐ŸŽฎ
Setup + Game Integration
$199 one-time
  • Everything in "Install & Configure"
  • Java bridge for your emulator (Aion, Lineage 2, custom)
  • C# launcher integration (WebView2)
  • Proximity radius tuning for your game world
  • Joint testing with your team
  • 14 days of support
Request full setup
๐Ÿ—
Managed Dedicated
$39 / month
  • We host & operate a dedicated instance for you
  • Updates, monitoring & backups
  • Unlimited plan changes & key management
  • Priority support (24h response)
Go managed

FAQ

Can Wave hear or record the voice?
No. Audio always travels peer-to-peer via WebRTC. Wave relays only small signaling messages between pairs that your own game backend has allowed.
Can someone connect with the key while not in the game?
No. A player is accepted only while your game backend keeps that character announced. No character in the world โ€” Player not announced by game server.
Is it safe to ship the key inside the launcher?
Yes. The key only controls the plan quota. Impersonation is impossible because the game backend decides which player IDs exist. The secret, however, must stay on your server side only.
What is the player ID format?
Whatever your backend announces โ€” typically <characterId>_<characterName>. The launcher must build exactly the same string.
Our key leaked โ€” what do we do?
Ask support to revoke it and issue a new one. Revocation disconnects all players on the old key instantly.
What if players are behind strict NAT?
STUN covers most cases. For symmetric NATs a TURN relay can be enabled on the instance โ€” included free in the Managed Dedicated package.
๐ŸŒŠ Wave Game Voice API โ€” keys ยท proximity voice ยท P2P audio
The server never hears or stores your voice.