Libraries
TypeScript SDK

TypeScript SDK

@truetick/sdk is a small, typed client for the TrueTick API. It handles the x-api-key header, coerces JSON int64 strings to numbers, derives server identifiers from names, and exposes everything as ergonomic resource methods.

Install

npm install @truetick/sdk

Authenticate

import { TrueTickClient } from "@truetick/sdk";
 
// Explicit key
const client = new TrueTickClient({ apiKey: "ttk_your_key" });
 
// …or from the environment (TRUETICK_API_KEY)
const client2 = new TrueTickClient();
 
// Point at a non-default base URL (default: https://api.truetick.gg)
const client3 = new TrueTickClient({ apiKey: "ttk_…", baseUrl: "https://api.truetick.gg" });

ClientOptions: { apiKey?: string; baseUrl?: string }. apiKey falls back to TRUETICK_API_KEY, baseUrl to TRUETICK_API_URL. The constructor throws if no key is found.

Account

const me = await client.whoami();
// { accountId, email, emailVerified }

Servers

// List / get
const servers = await client.servers.list();
const server  = await client.servers.get("my-smp");   // id, hostname, state, ramMb, type, version, region, plan, …
 
// Create (id/hostname/container derived from name)
const created = await client.servers.create({
  name: "My SMP",
  ramMb: 4096,
  type: "PAPER",      // optional
  version: "1.21.1",  // optional
  region: "na",       // optional
  plan: "metered",    // optional
});
 
// Lifecycle
await client.servers.start("my-smp");
await client.servers.stop("my-smp");
await client.servers.restart("my-smp");
await client.servers.delete("my-smp");   // permanent
 
// Configure
await client.servers.updateVersion("my-smp", { type: "PURPUR", version: "1.21.1" }); // stopped only
await client.servers.setMotd("my-smp", "Welcome!");
await client.servers.setProperties("my-smp", {
  properties: { difficulty: "hard", pvp: "true" },
  idleTimeoutMinutes: 20,
});
 
// Templates
const templates = await client.templates.list();
const fromTpl   = await client.servers.createFromTemplate("paper-survival", "my-server", { ramMb: 8192 });

Metrics

const m = await client.servers.metrics("my-smp");
// { tps, mspt, players, live }  — live:false is an honest "no data", not zero

See Honesty metrics for how to read these.

Console (RCON)

const { output } = await client.console.run("my-smp", "say Hello from the SDK!");

Logs

// Snapshot (+ cursor for incremental polling)
const { lines, cursor, containerMissing } = await client.servers.recentLogs("my-smp", { tail: 100 });
 
// Live stream — async iterable of plain lines (heartbeats filtered)
for await (const line of client.servers.streamLogs("my-smp", { tail: 50 })) {
  console.log(line);
}

Full streaming guide: Stream logs.

Files & SFTP

const entries = await client.files.list("my-smp", "/data");        // [{ name, isDir, size }]
const text    = await client.files.read("my-smp", "/data/server.properties");
await client.files.write("my-smp", "/data/motd.txt", "New motd");   // text, base64-encoded for you
await client.files.delete("my-smp", "/data/old.txt");
 
// Binary uploads (jars): use SFTP credentials
const cred = await client.servers.enableSftp("my-smp");            // { host, port, username, password }
⚠️

The file API encodes content as UTF-8 text → base64. For binary artifacts like plugin jars, use the SFTP credentials from enableSftp instead. See Deploy a plugin.

Backups

const backup  = await client.backups.create("my-smp");             // { id, serverId, createdAt, sizeBytes }
const backups = await client.backups.list("my-smp");
await client.backups.restore("my-smp", backup.id);                  // server must be stopped

Mods

const mods = await client.mods.list("my-smp");
await client.mods.add("my-smp", { source: "modrinth", projectId: "sodium", versionSpec: "0.5.11" });
await client.mods.remove("my-smp", { source: "modrinth", projectId: "sodium" });

Wallet & billing

const wallet = await client.wallet.get();                          // { accountId, balanceMicros }
console.log(`$${(wallet.balanceMicros / 1_000_000).toFixed(2)}`);
 
const { checkoutUrl } = await client.billing.createCheckout(10);   // Paddle checkout for $10

Standalone auth helpers

For sign-up / login flows (minting a key from credentials) the SDK also exports standalone functions — these hit the public auth endpoints directly and don't need a client:

import { signup, login, deviceStart, devicePoll } from "@truetick/sdk";
 
const minted = await login("https://api.truetick.gg", "you@example.com", "password");
// { apiKey, accountId, email, emailVerified }

Error handling

Every failed call throws a TrueTickError with status (HTTP code) and code:

import { TrueTickError } from "@truetick/sdk";
 
try {
  await client.servers.start("my-smp");
} catch (e) {
  if (e instanceof TrueTickError) {
    if (e.status === 401) console.error("invalid key");
    if (e.status === 403) console.error("missing scope");
    if (e.status === 404) console.error("not found / not yours");
    if (e.status === 429) console.error("rate limited — back off");
  }
}

See Errors for the full status/code reference.

Exported types

TrueTickClient, ClientOptions, TrueTickError, Server, ServerMetrics, Wallet, Backup, FileEntry, Mod, WhoAmI, CreateServerInput, Template, TemplateOverrides, SftpCredential, plus the naming helpers parseLabel, serverHostname, gameDomainFromBaseUrl and the auth helpers above.