PACKRELAY.cloud
DOCS · API

Public API

PackRelay's read API exposes the catalog — packs, servers, and signed manifests — so third-party tooling can browse and integrate. A write surface lets server-owners publish packs and heartbeat their servers without a browser session.

v1 is live. These are the endpoints the launcher and server tools use today. The surface is stable; additive changes (new fields, new routes) ship without a version bump, breaking changes would land under /api/v2.

Conventions

  • Base URL: https://packrelay.cloud. Routes are versioned in the path (/api/v1/).
  • All responses are JSON. Errors follow { "error": string, "code"?: string } with a standard HTTP status.
  • Timestamps are ISO 8601 in UTC.
  • List endpoints page two ways: an opaque cursor token (preferred — round-trip nextCursor, don't parse it) or a numeric offset. Responses carry hasMore plus whichever of nextCursor/nextOffset applies.

Authentication

Public endpoints require no authentication and are rate-limited per IP.

Signed-in and Server-owner endpoints require an API token minted at /account/tokens, passed as Authorization: Bearer <token>. Each token is scoped to one account and its role; publishing and heartbeat endpoints additionally require the server-owner role. Favorite toggles also accept a logged-in session cookie, so the website can call them directly.

Endpoints

MethodPathTier
GET
/api/v1/packs
List public packs. Supports q (full-text), tag, sort, and either cursor or offset pagination.
Public
GET
/api/v1/packs/:slug/manifest
Return the signed manifest JSON for the pack's latest published version.
Public
GET
/api/v1/packs/:slug/manifest/:version
Signed manifest pinned to a specific version (immutable).
Public
GET
/api/v1/packs/:slug/download
302-redirect to the CDN URL for the latest version's bundle (charges publisher egress).
Public
GET
/api/v1/servers
List public servers, filterable by region and attached pack. Includes derived online status + uptime.
Public
GET
/api/v1/servers/:slug/manifest
Signed manifest for the pack currently attached to this server (server-slug indirection).
Public
GET
/api/v1/servers/:slug/metrics
Player/CPU/RAM time-series buckets for sparklines. ?window= and ?buckets= supported.
Public
GET
/api/v1/me
The authenticated token's profile (id, displayName, role, plan). Used to validate a token.
Signed-in
GET
/api/v1/me/favorites
Slugs of the packs and servers you've favorited.
Signed-in
POST
/api/v1/packs/:slug/favorite
Toggle a pack favorite. Returns the new favorited state.
Signed-in
POST
/api/v1/servers/:slug/favorite
Toggle a server favorite. Returns the new favorited state.
Signed-in
POST
/api/v1/packs/:slug/versions
Publish a new signed pack version. Body is the signed manifest; referenced files must already be uploaded.
Server-owner
POST
/api/v1/servers/:slug/heartbeat
Server-side check-in — reports current player count (+ optional inventory). Stamps last-seen.
Server-owner

Example response

GET /api/v1/packs?limit=1 returns a page of packs plus paging fields:

response.json
{
  "packs": [
    {
      "slug": "the-veiled-eclipse",
      "name": "The Veiled Eclipse",
      "summary": "Atmospheric dark-fantasy survival.",
      "description": "…",
      "publisherName": "darkrising.gg",
      "latestVersion": "1.4.2",
      "coverImage": "/packs/default-1.png",
      "tags": ["horror", "atmosphere", "overhaul"],
      "fileCount": 312,
      "totalSizeBytes": 1503238553,
      "downloadCount": 8492,
      "favoriteCount": 17,
      "isFeatured": false,
      "createdAt": "2026-05-10T18:42:00Z",
      "updatedAt": "2026-05-10T18:42:00Z"
    }
  ],
  "sort": "popular",
  "limit": 1,
  "hasMore": true,
  "nextCursor": "eyJzIjoicG9wdWxhciIsImYi…",
  "nextOffset": 1
}

Fetch the signed manifest (file list + hashes + signature) separately via /api/v1/packs/:slug/manifest.

Webhooks

Publishers can register outbound webhooks to react to pack events (e.g. pack.version_published). Each request body is HMAC-SHA256 signed with the webhook's secret, carried in the X-PackRelay-Signature: sha256=<hex> header; recompute it on your end to verify. Manage webhooks at /account/webhooks.

Related