Table of Contents

Class PlayitApiService

Namespace
McServerLauncher.Services
Assembly
McServerLauncher.dll

Playit.gg API client.

  • Preferred: a per-user self-managed agent secret key from the partner setup-code flow (PlayitPartnerService), set app-wide via SetAgentKey(string?) and used as agent-key for both reads AND writes.
  • Fallback (legacy): the agent's secret_key from playit.toml (reads) and a user-pasted write key (writes, sent as Api-Key/Agent-Key). Auth is resolved by trying the schemes in order, so a caller doesn't need to know which kind of key it holds.
public class PlayitApiService
Inheritance
PlayitApiService
Inherited Members

Methods

DeleteTunnelForPortAsync(string, int, bool, CancellationToken)

Deletes the tunnel with this local port and this protocol. True if one was deleted. key is the per-user agent secret key (preferred) or a legacy write key.

public Task<bool> DeleteTunnelForPortAsync(string key, int localPort, bool udp, CancellationToken ct = default)

Parameters

key string
localPort int
udp bool
ct CancellationToken

Returns

Task<bool>

Remarks

The protocol is half the identity, the same as in GetTunnelAsync(int, bool, CancellationToken) and EnsureMinecraftTunnelAsync(string, string, int, TunnelEdition, CancellationToken): a crossplay server owns two tunnels, Java over TCP and Bedrock over UDP, and matching on the port alone deletes whichever the account happens to list first. Deleting a tunnel is not undoable, so this is the one place where guessing is least acceptable.

EnsureMinecraftTunnelAsync(string, string, int, TunnelEdition, CancellationToken)

Creates a tunnel for the server if one doesn't already exist for that port and edition. Returns true if it created one, false if it already existed. key is the per-user agent secret key (preferred) or a legacy write key.

public Task<bool> EnsureMinecraftTunnelAsync(string key, string name, int localPort, PlayitApiService.TunnelEdition edition = TunnelEdition.Java, CancellationToken ct = default)

Parameters

key string
name string
localPort int
edition PlayitApiService.TunnelEdition
ct CancellationToken

Returns

Task<bool>

GetAddressForPortAsync(int, CancellationToken)

Public address of the tunnel whose local port matches port, or null.

public Task<string?> GetAddressForPortAsync(int port, CancellationToken ct = default)

Parameters

port int
ct CancellationToken

Returns

Task<string>

GetRunDataAsync(string, CancellationToken)

Reads agent_id and tunnels using key (agent secret or write key).

public Task<(string AgentId, List<PlayitApiService.PlayitTunnel> Tunnels)> GetRunDataAsync(string key, CancellationToken ct = default)

Parameters

key string
ct CancellationToken

Returns

Task<(string AgentId, List<PlayitApiService.PlayitTunnel> Tunnels)>

GetTunnelAsync(int, bool, CancellationToken)

The tunnel on a local port for one protocol, or null. Callers that need the public port — Bedrock does, since players type it in — need the whole tunnel, not just its address.

public Task<PlayitApiService.PlayitTunnel?> GetTunnelAsync(int localPort, bool udp, CancellationToken ct = default)

Parameters

localPort int
udp bool
ct CancellationToken

Returns

Task<PlayitApiService.PlayitTunnel>

Remarks

Matched on the protocol as well as the port, because a crossplay server has two tunnels and the port alone would return whichever came first.

GetUdpTunnelPortsAsync(CancellationToken)

Local ports of every UDP tunnel on the account, or null when the account could not be asked.

public Task<IReadOnlyCollection<int>?> GetUdpTunnelPortsAsync(CancellationToken ct = default)

Parameters

ct CancellationToken

Returns

Task<IReadOnlyCollection<int>>

Remarks

For picking a Bedrock port. The system's UDP table only knows what is bound right now, and the app only knows its own servers, so neither sees a tunnel left behind by a deleted server, one made by hand on playit's site, or one belonging to another machine on the same account. Creating a tunnel on a port one of those already holds does not fail — it silently adopts the other tunnel, and two servers end up advertising one address.

Null rather than an empty set on failure, so "the account has no UDP tunnels" cannot be confused with "I could not reach playit".

ReadSecretKey()

Reads the (read-only) secret_key from playit.toml (cached ~30 s). Null if not found.

public string? ReadSecretKey()

Returns

string

SetAgentKey(string?)

Sets (or clears) the per-user agent secret key used for all Playit API auth. Called once at startup from settings and again after the setup-code flow mints a new key. Drops the shared tunnel cache so the next refresh uses the new credential.

public static void SetAgentKey(string? agentSecretKey)

Parameters

agentSecretKey string