Your first conversation, without the infrastructure.
Create a project, issue a grant, connect a browser. DeVoice handles signaling and audio forwarding.
Download browser SDK01Keep your keys on the server.
Create a project and a named API key in the developer console. The key is shown once; store it as a server environment variable. Each key can access only its own project.
02Create a place to talk.
Set DEVOICE_URL to your API deployment origin (locally: http://localhost:8080). A room belongs to the project that created it. Save the returned id.
curl -X POST "$DEVOICE_URL/v1/developer/rooms" \
-H "Authorization: Bearer $DEVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Squad Alpha","capacity":4}'03Give each player a room grant.
Your server authenticates the player and verifies they belong in this room. Then request a short-lived grant. Use a stable identity unique within the room. Set can_speak to false for listeners.
// Your server: authenticate the player before issuing a grant.
const response = await fetch(
process.env.DEVOICE_URL + '/v1/developer/rooms/' + roomId + '/tokens',
{
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.DEVOICE_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
identity: authenticatedPlayer.id,
name: authenticatedPlayer.name,
can_speak: true
})
}
);
// Forward the grant JSON to this authenticated player only.
const roomGrant = await response.json();The response contains token, ws_url, ice_servers, can_speak and room. Admission expires after 5 minutes and each grant works once. Request a fresh grant for reconnects. Connected sessions last up to 6 hours.
04Connect from your app.
Download devoice.js and serve it with your app. Use HTTPS outside localhost. Call connect from a user gesture; catch connection and microphone errors.
import { DeVoiceClient } from './devoice.js';
const voice = new DeVoiceClient();
voice.addEventListener('members', event => {
renderParticipants(event.detail);
});
voice.addEventListener('error', event => {
showError(event.detail);
});
// Run inside a button click so the user initiates microphone access.
await voice.connect(roomGrant);
voice.setMuted(false);
voice.setDeafened(false);
voice.setPushToTalk(true);
// Key down / key up:
voice.pushToTalk(true);
voice.pushToTalk(false);
// On leaving the room or navigating away:
voice.disconnect();Events: state, members, speaking, mute, quality, error and playback-blocked. Audio output selection depends on browser support. The SDK queues ICE candidates and serializes signaling.
API reference
All endpoints below require Authorization: Bearer YOUR_API_KEY. JSON request and response bodies. Errors use { "error": "code" }.
| METHOD | ENDPOINT | DESCRIPTION |
|---|---|---|
| GET | /v1/developer/rooms | List project rooms |
| POST | /v1/developer/rooms | Create a voice room |
| DELETE | /v1/developer/rooms/:id | Close a room and disconnect its peers |
| POST | /v1/developer/rooms/:id/tokens | Issue a 5-minute, single-use admission grant |
| GET | /v1/developer/rooms/:id/members | Get the current participant roster |
| DELETE | /v1/developer/rooms/:id/members/:peer | Disconnect a participant |
Know what counts.
Each project starts with 1,000 lifetime trial participant-minutes and 10 concurrent connections. Connected time is metered in seconds, including muted participants and listeners. Community rooms do not use API credit.
You can lower or raise a project’s monthly minute cap in the console. The cap resets at the UTC calendar month boundary; trial and purchased credits do not reset. Connections stop at the cap or credit limit.
Self-hosted deployment: configure a reachable TURN server and TLS for internet use. Billing is disabled until the operator configures pricing and a payment provider. This release runs as one API/SFU instance.