Connect
Connect links dash.uebliche.net to in-game servers. The API stores pending commands, publishes settings updates, and keeps per-server membership data.
Authentication
Server auth (Connect mod/plugin)
Connect servers authenticate with:
Authorization: Bearer <CONNECT_SERVER_SECRET>X-Server-Id: <CONNECT_SERVER_ID>
Servers can request credentials via the registration endpoint and persist them locally (for example in connect.json).
Dashboard auth
Dash uses the API JWT in the Authorization: Bearer <token> header.
Permissions
Dash requests are gated by these permission nodes:
connect:commands:readconnect:commands:writeconnect:settings:readconnect:settings:writeconnect:members:readconnect:members:writeuebliche.connect.extensions.<extensionId>(extension actions)
Endpoints
Networks
Dash creates shared networks for Connect servers. Servers are claimed first via single-use keys, then assigned to a network in Dash. There are no fixed network keys.
List networks
GET /v1/connect/networks
Response:
{
"items": [
{
"id": "object-id",
"networkId": "uuid",
"name": "My Network",
"ownerId": "user-uuid",
"createdAt": "2026-01-15T12:00:00Z",
"updatedAt": "2026-01-15T12:00:00Z"
}
]
}Create network
POST /v1/connect/networks
{
"name": "My Network"
}Response:
{
"network": {
"id": "object-id",
"networkId": "uuid",
"name": "My Network",
"ownerId": "user-uuid",
"createdAt": "2026-01-15T12:00:00Z",
"updatedAt": "2026-01-15T12:00:00Z"
}
}Create network join token
POST /v1/connect/networks/{networkId}/join-token
Response:
{
"joinToken": "jwt",
"expiresIn": 900,
"networkId": "uuid"
}The join token is single-use and already embeds the network ID. It is consumed by POST /v1/connect/networks/join.
Join network (single-use token)
POST /v1/connect/networks/join
{
"joinToken": "jwt",
"name": "host-eu-1"
}Response:
{
"serverId": "uuid",
"serverSecret": "uuid",
"networkId": "uuid",
"serverType": "agent",
"name": "host-eu-1"
}Domains (TXT claim)
Networks can claim domains with a TXT record. Create a claim to get the TXT value, add it to DNS, then verify.
List domains
GET /v1/connect/networks/{networkId}/domains
Response:
{
"items": [
{
"id": "object-id",
"networkId": "uuid",
"domain": "example.com",
"token": "token",
"verified": false,
"verifiedAt": null,
"createdAt": "2026-01-15T12:00:00Z",
"updatedAt": "2026-01-15T12:00:00Z"
}
]
}Create domain claim
POST /v1/connect/networks/{networkId}/domains
{
"domain": "example.com"
}Response:
{
"domain": {
"id": "object-id",
"networkId": "uuid",
"domain": "example.com",
"token": "token",
"verified": false,
"verifiedAt": null,
"createdAt": "2026-01-15T12:00:00Z",
"updatedAt": "2026-01-15T12:00:00Z"
},
"txt": {
"name": "_uebliche.example.com",
"value": "uebliche-network=token"
}
}Verify domain
POST /v1/connect/networks/{networkId}/domains/{domainId}/verify
Response:
{
"domain": {
"id": "object-id",
"networkId": "uuid",
"domain": "example.com",
"token": "token",
"verified": true,
"verifiedAt": "2026-01-15T12:00:00Z",
"createdAt": "2026-01-15T12:00:00Z",
"updatedAt": "2026-01-15T12:00:00Z"
}
}Servers
Register server credentials
POST /v1/connect/servers/register
{
"serverType": "paper",
"serverName": "hub-eu-1",
"templateId": "template-server-id",
"tempInstance": true
}Response:
{
"serverId": "uuid",
"serverSecret": "uuid",
"networkId": null,
"claimKey": "single-use-claim-key",
"serverType": "paper",
"serverName": "hub-eu-1",
"networkName": null
}Registering a server always returns a single-use claimKey (valid for about 5 minutes). Dash users claim the server with the key and then assign the server to a network.
Templates are marked in Dash by updating the server:
PATCH /v1/connect/servers/{serverId}
{
"isTemplate": true
}Hosts
Agents registered through network join tokens appear as hosts.
GET /v1/connect/hosts
Response:
{
"items": [
{
"id": "object-id",
"serverId": "uuid",
"networkId": "uuid",
"serverType": "agent",
"name": "host-eu-1",
"ownerId": "user-uuid",
"lastSeenAt": "2026-01-22T09:00:00Z",
"lastSeenIp": "203.0.113.1",
"createdAt": "2026-01-22T09:00:00Z",
"updatedAt": "2026-01-22T09:00:00Z"
}
]
}List claimed servers
GET /v1/connect/servers
Response:
{
"items": [
{
"id": "object-id",
"serverId": "uuid",
"networkId": "uuid-or-null",
"serverType": "paper",
"name": "hub-eu-1",
"ownerId": "user-uuid",
"createdAt": "2026-01-15T12:00:00Z",
"updatedAt": "2026-01-15T12:00:00Z"
}
]
}Claim server (single-use key)
POST /v1/connect/servers/claim
{
"claimKey": "single-use-key"
}Response:
{
"server": {
"id": "object-id",
"serverId": "uuid",
"networkId": null,
"serverType": "paper",
"name": "hub-eu-1",
"ownerId": "user-uuid",
"createdAt": "2026-01-15T12:00:00Z",
"updatedAt": "2026-01-15T12:00:00Z"
}
}Claim keys are generated by server registration. They are single-use and expire after roughly 5 minutes. If the claim key expires, the server can request a fresh key via the claim-key endpoint.
Request a fresh claim key (server auth)
GET /v1/connect/servers/{serverId}/claim-key
Response (unclaimed server):
{
"claimKey": "single-use-key",
"claimed": false,
"expiresAt": "2026-01-15T12:05:00Z"
}Response (already claimed):
{
"claimKey": null,
"claimed": true,
"expiresAt": null
}Assign a server to a network
PATCH /v1/connect/servers/{serverId}
{
"networkId": "uuid-or-null"
}GET /v1/profile/servers
Returns the list of servers the current account can access, including Connect-registered servers (the id will match the Connect serverId).
Commands
Dash creates commands, servers poll and acknowledge them.
POST /v1/connect/servers/{serverId}/commands
{
"action": "kick",
"payload": {
"player": "playerNameOrUuid",
"reason": "Optional reason"
}
}GET /v1/connect/servers/{serverId}/commands?limit=25
POST /v1/connect/servers/{serverId}/commands/{commandId}/ack
{
"status": "success",
"result": {
"message": "Optional response payload"
}
}Settings
GET /v1/connect/servers/{serverId}/settings?source=<extensionId>
PUT /v1/connect/servers/{serverId}/settings
{
"data": {
"example": true
},
"schema": {
"version": "hub.v1",
"fields": [
{
"key": "debug.enabled",
"label": "Debug enabled",
"type": "bool"
}
]
},
"source": "hub",
"schemaVersion": "v1"
}schema is optional. When present, Dash can render typed inputs for the fields. source scopes settings to an extension. Dash should pass the extension ID. Use source connect with a temp boolean in the payload to flag temporary instances:
{
"data": {
"temp": true
},
"source": "connect"
}GET /v1/connect/servers/{serverId}/settings/history?limit=25&source=<extensionId>
Extensions
Extension catalogs are managed in Dash. Servers publish extension availability per server.
GET /v1/connect/extensions
POST /v1/connect/extensions
{
"extensionId": "hub",
"name": "Hub",
"description": "Lobby and compass controls"
}PUT /v1/connect/extensions/{extensionId}
GET /v1/connect/servers/{serverId}/extensions
PUT /v1/connect/servers/{serverId}/extensions/{extensionId}
{
"name": "Hub",
"description": "Lobby and compass controls",
"actions": [
{
"id": "reload_config",
"label": "Reload config",
"description": "Reload the hub config on the server",
"schema": {
"version": "hub.actions.v1",
"fields": [
{ "key": "broadcast", "label": "Broadcast", "type": "bool" }
]
}
}
]
}Settings stream (WebSocket)
GET /v1/connect/servers/{serverId}/stream
- Servers authenticate via headers.
- Dash can pass the JWT as a query param:
/v1/connect/servers/{serverId}/stream?token=<api-jwt>
Members
GET /v1/connect/servers/{serverId}/members
PUT /v1/connect/servers/{serverId}/members/{userId}
{
"role": "viewer"
}DELETE /v1/connect/servers/{serverId}/members/{userId}