Docs
search Esc

REST API Reference

Endpoint schemas for the UbuntuPlay Developer API. Base URL: https://ubuntuplay.fly.dev (or your custom hub).

Authentication

Developer endpoints accept either a Better Auth session cookie (portal) or an API key in the X-Api-Key header. The signing endpoint also accepts an admin JWT Authorization: Bearer <token>.

Account

POST /hub/api/dev/signup

Create a developer profile. Requires a Better Auth session for the same email.

JSON
{
  "name": "Zed Games",
  "email": "dev@example.com",
  "organisation": "Zed Games Ltd",
  "website": "https://zedgames.zm",
  "description": "Educational maths games",
  "inviteToken": "optional-token"
}

GET /hub/api/dev/me

Returns the authenticated developer profile, API keys (masked), games, wallet, and payout account.

GET /hub/api/dev/games

Lists games registered under the developer's account.

API Keys

POST /hub/api/dev/api-keys

Create a new API key. Returns the raw key once.

JSON
{
  "name": "CI Bot",
  "scopes": ["sign:game", "publish:plugin"]
}

DELETE /hub/api/dev/api-keys/:id

Revoke an API key. Key ID is returned in the profile.

Game Signing

POST /hub/api/dev/sign

Signs a game manifest. Requires an active account and an API key with sign:game scope (or admin JWT).

JSON
{
  "manifest": {
    "type": "game_add",
    "version": "1.0.0",
    "gameId": "my-maths-game",
    "name": "My Maths Game",
    "icon": "🧮",
    "files": [
      { "src": "index.html", "dest": "games/my-maths-game/index.html" }
    ]
  }
}

Response:

JSON
{
  "ok": true,
  "signedManifest": { /* your manifest plus a "signature" field (base64url Ed25519) */ },
  "devId": "dev_abc123",
  "signedBy": "UbuntuPlay Hub"
}

POST /hub/api/dev/games/:id/marketplace

Update marketplace metadata for a game you own.

JSON
{
  "name": "My Maths Game",
  "description": "Fun fractions practice",
  "category": "Numeracy",
  "price": 0
}

POST /hub/api/dev/games/:id/upload

Upload the playable single-file HTML for a community game you own (max 2 MB, must be a complete HTML document). Buyers download this file from the marketplace — a paid game cannot be purchased until its file is uploaded.

JSON
{
  "html": "<!DOCTYPE html><html>…your complete game…</html>"
}

Analytics

GET /hub/api/dev/analytics

Sales, installs, and earnings summary for your games and plugins, plus wallet totals.

JSON
{
  "ok": true,
  "games":   [ { "id": "my-maths-game", "status": "active", "installCount": 12, "sales": 3, "earnings": 72, "hasFile": true } ],
  "plugins": [ { "id": "sheets-export", "status": "approved", "installs": 4, "sales": 2, "earnings": 140 } ],
  "totals":  { "balance": 212, "totalEarned": 212, "salesCount": 5, "pendingPayouts": 0 }
}

Invites

POST /hub/api/dev/redeem-invite

Activate your pending account with an admin-issued invite token. Requires a signed-in session. Body: { "token": "invite_…" }. Invite tokens can also be supplied at signup (inviteToken field) for instant approval.

Plugins

POST /hub/api/dev/plugins

Publish or update a plugin. Authenticate with the portal session cookie, or with an API key (X-Api-Key) carrying the publish:plugin scope. Changing an approved plugin's code, permissions, or triggers returns it to pending review.

JSON
{
  "id": "google-sheets-export",
  "name": "Google Sheets Export",
  "version": "1.0.0",
  "description": "Exports impact reports to Google Sheets.",
  "category": "export",
  "icon": "📊",
  "permissions": ["reports:read", "schools:read"],
  "triggers": ["manual", "schedule:daily"],
  "settingsSchema": [ /* see plugin docs */ ],
  "code": "async function run(context) { ... }\nmodule.exports = { run };"
}

GET /hub/api/dev/plugins

List your published plugins (code excluded).

GET /hub/api/dev/plugins/:id/code

Fetch your own plugin code for editing.

DELETE /hub/api/dev/plugins/:id

Delete a plugin you own. Official plugins cannot be deleted.

Payouts

POST /hub/api/dev/payment-account

Set or update your payout destination.

JSON
{
  "type": "mobile_money",
  "number": "+26097xxxxxxx",
  "bankName": "",
  "holderName": "Zed Games"
}

POST /hub/api/dev/payout-request

Request a payout of your current wallet balance. Minimum balance is K50, and a payment account must be saved first. Returns { ok, amount, payoutId }; the payout appears as a pending transaction until the hub administrator settles it.

payments
Revenue share Plugin sales credit your wallet at the standard 70% developer share. Game listings currently default to an 80% developer split (set per listing by the hub administrator, never below the published 70% share).

Public Marketplace

GET /hub/api/marketplace

List approved plugins available to organisations (no authentication required).