TypeScript SDK
TypeScript SDK
Section titled “TypeScript SDK”@trucklinemp/sdk is the official TypeScript and JavaScript toolkit for TrucklineMP integrations. It covers:
- Public API client (
Truckline) with typed models, retries, and pagination helpers - OAuth helpers (
TrucklineOAuth, PKCE) for user sign-in - Webhooks signature verification and delivery handlers (Node.js)
The OpenAPI spec remains the source of truth for every field. The SDK tracks common resources and stays intentionally thin.
| Package | @trucklinemp/sdk |
| Version | 0.2.x |
| Registry | npmjs.com |
| Repository | github.com/trucklinemp/sdk |
| License | MIT |
| Runtime | Node.js 18+ (global fetch); browser-capable for the HTTP client |
Install
Section titled “Install”npm install @trucklinemp/sdkEntry points
Section titled “Entry points”| Import | Contents |
|---|---|
@trucklinemp/sdk | Full client, models, errors; OAuth + webhooks re-exported |
@trucklinemp/sdk/oauth | OAuth / PKCE only |
@trucklinemp/sdk/webhooks | Webhook verify / handler only (uses Node crypto) |
Prefer the subpath imports when you want a smaller surface (for example OAuth in a separate service).
Quick start (Public API)
Section titled “Quick start (Public API)”- Enable Developer Mode and create a project in the Developer Console.
- Create an API key (
tlmp_api_...) and store it securely. - Call the API:
import { Truckline, TrucklineError } from "@trucklinemp/sdk";
const tl = new Truckline({ apiKey: process.env.TRUCKLINE_API_KEY,});
console.log(tl.version); // SDK version string
const { user } = await tl.users.get("some-handle");console.log(user.webId, user.steamId, user.name);
const bySteam = await tl.users.getBySteam("76561198000000000");
try { await tl.vtcs.get("missing-vtc");} catch (err) { if (err instanceof TrucklineError) { console.error(err.status, err.code, err.requestId, err.message); if (err.isRateLimited) console.error("retry after", err.retryAfter); }}Anonymous calls work on many public routes with lower rate limits. Always send a key in production.
Configuration
Section titled “Configuration”new Truckline({ apiKey: "tlmp_api_...", baseUrl: undefined, // default https://api.trucklinemp.com timeoutMs: 30_000, maxRetries: 1, // retries on 429 and 5xx retryOnServerError: true, headers: { "X-App": "my-bot" }, userAgent: "my-bot/1.0", // Node only; default includes SDK version debug: false, onRequest: ({ method, url, attempt }) => {}, onResponse: ({ status, requestId, durationMs }) => {}, fetch: customFetch, // optional});Base URL
Section titled “Base URL”| Option | Base URL |
|---|---|
| Default | https://api.trucklinemp.com |
| Local Web | http://localhost:3000/api/v1 |
Do not append an extra /v1 on api.trucklinemp.com. See Public API base URLs.
Rate limit info
Section titled “Rate limit info”After a request, inspect the last parsed rate-limit headers:
await tl.meta.version();console.log(tl.lastRateLimit);// { retryAfter, limit, remaining, reset }Typed models
Section titled “Typed models”The package exports TypeScript types for public payloads (shapes may grow as the API does; optional fields stay optional):
- Users:
PublicUser,PublicUserSearchResult,PublicUserBans, … - VTCs / members:
VtcListItem,VtcMember,VtcNewsItem,VtcRole - Events:
PublicEvent,PublicEventAttendee,PublicEventSlot - News, bans, partners, badges, game servers, OAuth userinfo, webhook delivery
Dates from the API are typed as ISO strings (IsoDateString).
Example:
import type { PublicUser } from "@trucklinemp/sdk";
const { user } = await tl.users.get("driver");const profile: PublicUser = user;Resources
Section titled “Resources”Meta / platform
Section titled “Meta / platform”await tl.meta.version();await tl.meta.status();await tl.meta.stats();await tl.meta.partners();await tl.meta.rules();await tl.meta.session();await tl.meta.recruitmentOpen();await tl.users.search({ q: "alex", page: 1, limit: 20 });await tl.users.get("handle-or-id-or-steamId64");await tl.users.getBySteam("7656119…");await tl.users.resolve("handle"); // returns PublicUserawait tl.users.batch(["id1", "id2"]); // auto-chunks at 50await tl.users.bans(userId);await tl.users.events(userId, { tab: "upcoming" });
for await (const page of tl.users.iterateSearch({ q: "a", limit: 20 })) { console.log(page.length);}
const allMatches = await tl.users.searchAll({ q: "a", maxItems: 100 });Public user objects include steamId when the account is linked.
await tl.vtcs.list({ limit: 20, q: "logistics" });await tl.vtcs.get("handle-or-id");await tl.vtcs.batch([1, 2, 3]);await tl.vtcs.members("handle");await tl.vtcs.news(vtcId);await tl.vtcs.events(vtcId);await tl.vtcs.roles(vtcId);await tl.vtcs.gallery(vtcId);await tl.vtcs.tier(vtcId);await tl.vtcs.liveEvents(vtcId);await tl.vtcs.upcomingEvents(vtcId);
for await (const members of tl.vtcs.iterateMembers("my-vtc", { limit: 50 })) { for (const m of members) console.log(m.name, m.steamId);}
const everyVtc = await tl.vtcs.listAll({ maxPages: 10 });Events, news, bans, programs, game
Section titled “Events, news, bans, programs, game”await tl.events.list();await tl.events.get(eventId);await tl.events.attendees(eventId);await tl.events.slots(eventId);
await tl.news.list();await tl.news.get(newsId);
await tl.bans.list({ page: 1, pageSize: 25, q: "cheat" });await tl.bans.get(banId);for await (const page of tl.bans.iterate({ pageSize: 50 })) { /* … */ }
await tl.programs.badge("bug-hunter");await tl.programs.recognition();await tl.game.servers();Escape hatch
Section titled “Escape hatch”await tl.get("/version");await tl.request("GET", "/vtcs", { query: { limit: 5 } });await tl.post("/path", { body: { … } }); // if a future write route is documentedErrors and retries
Section titled “Errors and retries”Failed HTTP responses throw TrucklineError:
| Field / flag | Meaning |
|---|---|
status | HTTP status (0 for network / timeout / abort) |
code | API or client code (NOT_FOUND, TIMEOUT, ABORTED, …) |
requestId | Correlation id for support |
retryAfter | Seconds from Retry-After when present |
details | Extra API payload |
isRateLimited / isNotFound / isUnauthorized / isForbidden | Helpers |
isTimeout / isNetworkError / isServerError / isValidationError | Helpers |
Default retries: up to maxRetries (default 1) on 429 and 5xx, with jitter. Set maxRetries: 0 to disable. Network failures also retry when maxRetries > 0.
Platform limit tables: Rate limits.
Use OAuth when you need data as a signed-in user (not with an API key alone). Full product flow: OAuth Apps.
import { TrucklineOAuth, generatePkce } from "@trucklinemp/sdk/oauth";
const oauth = new TrucklineOAuth({ clientId: process.env.CLIENT_ID!, clientSecret: process.env.CLIENT_SECRET, // omit for public + PKCE clients redirectUri: "https://myapp.com/callback", // siteUrl: "https://trucklinemp.com",});
const pkce = generatePkce();const url = oauth.getAuthorizeUrl({ scope: ["profile", "vtc:read", "presence:read"], state: "csrf-token", codeChallenge: pkce.codeChallenge,});
// After redirect:const tokens = await oauth.exchangeCode(code, { codeVerifier: pkce.codeVerifier,});const me = await oauth.userinfo(tokens.access_token);console.log(me.sub, me.steam_id, me.handle);
const refreshed = await oauth.refresh(tokens.refresh_token!);await oauth.revoke(tokens.access_token, "access_token");Redirect URI rules (localhost / private LAN / https): OAuth Apps — redirect URIs.
userinfo with profile includes steam_id when linked.
Webhooks (Node.js)
Section titled “Webhooks (Node.js)”Deliveries are signed with HMAC-SHA256 over the raw body:
X-TrucklineMP-Signature: sha256=<hex>X-TrucklineMP-Event: user.bannedX-TrucklineMP-Delivery: <id>import { createWebhookHandler, verifyWebhookSignature, WEBHOOK_SIGNATURE_HEADER,} from "@trucklinemp/sdk/webhooks";
const handle = createWebhookHandler({ secret: process.env.WEBHOOK_SECRET!, onEvent: async (event, meta) => { console.log(meta.type, meta.deliveryId, event); },});
// Express: use express.raw() so body is not re-parsed firstapp.post("/hooks/truckline", express.raw({ type: "*/*" }), async (req, res) => { const result = await handle({ rawBody: req.body, headers: req.headers }); res.status(result.ok ? 200 : 401).json(result);});Low-level:
verifyWebhookSignature(rawBody, req.headers[WEBHOOK_SIGNATURE_HEADER], secret);Event catalog and retries: Webhooks.
Examples
Section titled “Examples”In the SDK repository (after npm run build):
| File | Purpose |
|---|---|
examples/basic.mjs | Version + user search |
examples/oauth-pkce.mjs | Print authorize URL + verifier |
examples/webhook-express.mjs | Minimal Express receiver |
Versioning
Section titled “Versioning”- SDK methods, options, and error class follow semver (
Truckline.VERSION/ package version). - Server JSON fields can evolve; treat new optional fields as optional.
- Breaking client changes ship as major versions. See the package CHANGELOG.
Privacy
Section titled “Privacy”API traffic with your key is subject to the same logging and rate limiting as raw HTTP. See the Privacy Policy and Public API telemetry notes.
Contributing
Section titled “Contributing”Package layout, PRs, and adding methods: Contributing to the TypeScript SDK.
Related guides
Section titled “Related guides”| Guide | Topics |
|---|---|
| Platform Overview | Developer Mode, integration types |
| Public API | Auth, base URLs, rate limits, endpoint map |
| OAuth Apps | Authorize, tokens, scopes, redirect URIs |
| Webhooks | Events, signatures, retries |
| Developer Console | Projects, keys, playground |
| Contributing to the SDK | Local setup and PRs |
| Leaked API Keys & Secrets | Rotation after exposure |