Gateman
Documentation/Canonical Node.js client

Official Gateman Node.js client

The official Gateman Node.js client is an ESM implementation of the authenticated transport and authentication boundary defined by Contract v1. PHP, Node.js, Python, and Go are equally official Gateman clients.

Client version: 1.0.0.

Requirements and acquisition

The client supports Node.js 22 or newer and has zero runtime dependencies. It is server-side ESM and does not support browser use, Deno, or CommonJS.

Gateman distributes a compiled local package archive from:

GET https://getgateman.com/client/node

The archive contains dist/src, declaration files, package.json, and README. It is not evidence of npm registry publication. Install it as a local npm dependency:

mkdir -p vendor
curl --fail --silent --show-error https://getgateman.com/client/node -o /tmp/gateman-node-client.tar.gz
tar -xzf /tmp/gateman-node-client.tar.gz --strip-components=1 -C vendor
npm install ./vendor

The package identity is @getgateman/client.

Configuration and initialization

GatemanClientConfig contains baseUrl, appId, privateKey, appSecret, and environment. Configuration is explicit; the client does not load .env files or read process.env automatically.

baseUrl must use http or https and contain no query or fragment. appId is required. privateKey is canonical standard Base64 containing a raw 32-byte Ed25519 seed. It takes precedence over appSecret. Invalid private-key material is a configuration error and does not fall back to HMAC.

environment, when supplied, must be production, staging, or development. The client does not select a default.

import { GatemanClient } from '@getgateman/client';
const client = new GatemanClient({
  baseUrl: 'https://getgateman.com',
  appId: 'app-id-from-gateman',
  appSecret: 'application-secret-from-gateman',
});
const response = await client.request('/client/get', {});
if (response.status >= 200 && response.status < 300) {
  console.log(response.json);
}

POST /client/get requires client:read. The values shown are placeholders, not credentials.

Public API

new GatemanClient(config)

Constructs a client and validates the URL, application ID, environment, and authentication material. Invalid configuration throws GatemanClientError with kind configuration.

client.request<T>(path, payload?, options?)

request<T = unknown>(
  path: string,
  payload: unknown = {},
  options: GatemanRequestOptions = {},
): Promise<GatemanResponse<T>>

The payload must be a non-null object and cannot be an array. The method sends one authenticated JSON POST and never retries.

GatemanRequestOptions contains:

idempotencyKey?: string
credentialRequestId?: string
timeoutMs?: number

The idempotency key is trimmed around spaces and tabs, omitted when empty, limited to 255 UTF-8 bytes, and signed. It does not itself provide route-level idempotency. credentialRequestId is valid only for /secrets/get and /db/get; those routes generate a fresh lowercase 32-hex-character ID when it is omitted. timeoutMs must be finite and greater than zero; the default is 10,000 milliseconds.

Paths must begin with / and may not contain queries, fragments, controls, unencoded spaces, Unicode, dot segments, or other transport-normalizing forms. Already percent-encoded transport-equivalent paths are accepted.

client.health()

Performs unauthenticated GET /health with a fixed three-second timeout. It does not authenticate the application or validate provider configuration.

Environment handling

The client receives the application environment through the configuration object’s environment property. It accepts production, staging, and development, and trims and lowercases the value during initialization. Requests to routes that require an environment fail locally when no valid environment is configured; the normalized value is injected automatically. See Contract v1 for the authoritative route classification.

If a request payload already supplies environment, its normalized value must match the configured value or the request fails with a validation error. The client copies the top-level payload before injection. Environment-independent routes receive no automatic environment, and no implicit default is selected.

Responses and errors

GatemanResponse<T> contains:

status: number
headers: Headers
rawBody: string
json?: T
requestId?: string
retryAfter?: number
decodeError?: GatemanClientError

All received HTTP responses, including non-2xx statuses, resolve normally. status is authoritative. rawBody is the body decoded as UTF-8. Valid JSON is available as json. A non-empty malformed JSON body remains in rawBody and sets decodeError with kind decode.

requestId is populated only for an exactly 16-character lowercase hexadecimal X-Gateman-Request-ID. retryAfter is populated for a valid safe integer Retry-After value. Local failures throw GatemanClientError with kind configuration, validation, serialization, transport, timeout, or decode.

Redirects are rejected as transport failures. Requests are never retried automatically.

The shared wire protocol is defined by Contract v1.