GAME DEVELOPERS

The Play API

Achievements, leaderboards and cloud saves for your game, on the OpenVibe network. One API, one player account, nothing to host yourself. This is the same API the boards and achievements on this site are drawn from.

Make a project Browse the public titles JSON

Base address and errors

Every call is under https://play.openvibe.network/api/v1. The API stays on that host; this page is the documentation, moved here with the rest of the player pages.

Errors are RFC 9457 problem+json with a stable code.

Reading: anyone, any site

  • GET /titles: every game, with its achievements and boards.
  • GET /titles/:title: one game.
  • GET /titles/:title/boards/:board?period=week|all&page=1: 25 entries a page, rank, name, score, never a player id.
  • GET /people/:subject/achievements: a person's unlocks in every game, what their OpenVibe profile shows.

Writing: your game's own token

Your server uses an OpenVibe Network service or app token for audience openvibe.play. Only the principal that registered a title writes to it.

  • PUT /titles/:title (play.title.manage): the name, url, summary, achievements and boards. A definition left out is retired, never deleted.
  • POST /titles/:title/scores (play.result.write): { board, ref, entries: [{ player, name, score }] }. Posting the same ref again changes nothing.
  • POST /titles/:title/unlocks (play.result.write): { player, achievements: [id] }, and it answers the new ones.
  • POST /titles/:title/players/:guest/adopt: a guest signed in, so their unlocks and scores become the person's.
  • GET /titles/:title/players/:player/achievements (play.player.read): what one player unlocked in your game.

Cloud saves

Up to 8 slots per player in your game, each any JSON value of at most 64 KB. Every write names the version it read; if another device saved in between, the write is refused with 409 play.save_conflict so the game can merge instead of losing progress.

  • PUT /titles/:title/players/:player/saves/:slot (play.result.write): { data, version }.
  • GET /titles/:title/players/:player/saves/:slot (play.player.read): the slot and its version.
  • GET /me/saves: a signed-in person's slots in every game.

Start in the sandbox

  1. Sign in on OpenVibe Services and make a project. New projects are sandbox-only.
  2. Add a sandbox app and ask for play.title.manage, play.result.write and play.player.read. A sandbox app gets them without waiting for anyone.
  3. Get a token for audience openvibe.play and PUT /titles/sandbox-your-game. Sandbox titles are never listed, counted or indexed; their players are guests only.

When the game is ready, staff turn production on for your project and its production app registers the real name.

From your game server

The openvibe-sdk/play client wraps the same calls; plain HTTPS works too.

const { createClient } = require('openvibe-sdk/core');
const { createPlayClient } = require('openvibe-sdk/play');

const play = createPlayClient(createClient({ tokenProvider: tokens }));
await play.titles.define('gem-run', {
  name: 'Gem Run',
  achievements: [{ id: 'first-gem', name: 'First Gem' }],
  boards: [{ id: 'high-score', name: 'High score', kind: 'best' }],
});
await play.scores.post('gem-run', {
  board: 'high-score', ref: 'round-42',
  entries: [{ player: 'usr_…', name: 'kim', score: 1200 }],
});
await play.achievements.unlock('gem-run', {
  player: 'usr_…', achievements: ['first-gem'],
});
await play.saves.put('gem-run', 'usr_…', 'main', { data: { level: 3 }, version: 0 });

Where players see it

Every unlock and board score is on Achievements and Leaderboards here, and on the player's OpenVibe profile. A guest plays at once; when they sign in, their progress moves to their account.

Read more about the service in the OpenVibe.Play README.