Creates a version-specific TrueNAS API client.
GET /api/versions), asking every hostname in
parallel. The first usable answer wins.v25.10.x -> TrueNasApiClientV2510,
v26.x.y -> TrueNasApiClientV26).Resolves exactly once with a single client instance — dispose of it with
client.close() when done.
DThe version is discovered at runtime; the query verbs are typed at compile
time. Something has to bridge that, and D is where the caller says which
API surface they are writing against:
const client = await createTrueNasClient(opts);
client.api.query('user.query'); // typed against v25.10
const client = await createTrueNasClient<ApiDirectoryV26_0_0>(opts);
client.api.query('container.query'); // v26-only methods reachable
It defaults to the oldest supported version's directory, which is the
conservative direction: against a newer server the types understate what is
available rather than promising methods that are not there. Move it in step
with --min-version in the generate:api script.
Note this is a claim, not a guarantee — the connected server may be any
supported version. Operations that must work across versions belong on
client.ops, which resolves them at runtime.
the generated API surface the client is typed against, as a
whole (call, job, event). Every verb resolves method names against
it, so naming a method this surface does not have is a build error.
a Promise that resolves with the created client, or rejects with a
VersionDiscoveryError subclass (or a client-selection error).
Rejects if version discovery on all hostnames fails and is not recoverable.
Note that when the selected failure is a VersionDiscoveryNetworkError,
this function attempts to use a fallback API version (see FALLBACK_VERSION)
because network errors are actually expected on 25.10.0 systems due to a CORS
bug. A network error alongside a version-compatibility error or a 404 does
not reach the fallback — see selectRepresentativeFailure.
@truenas/api-client— a framework-agnostic, RxJS-first client for the TrueNAS JSON-RPC 2.0 (versioned) API.The curated public API. Everything exported here is the package's contract under semver; connection/socket internals are intentionally not re-exported (reach them via
client.connection/client.api/client.authenticator).