Skip to content
HomeConsoleGet started

Environment variables, client options, API key permissions, worker labels, durations, timeouts and transport retries for the TypeScript and Python SDKs.

Both SDKs read the same variables. Options you pass in code take precedence.

Variable Required Default Purpose
RUNSTATE_API_KEY yes none API key, sent as Authorization: Bearer <key> on every request.
RUNSTATE_SPACE_ID yes none The space (project or environment) the key works in.
RUNSTATE_BASE_URL no https://api.getrunstate.com API address. Set it to http://localhost:8080 for a local kernel.
RUNSTATE_RUN no default The run name every process joins.

The default client reads these on first use. Importing the SDK makes no network calls. If the API key or space id is missing, the first call throws ConfigError.

In most programs you import the SDK and use it directly. To change settings in code, call configure before the first call:

import runstate from 'runstate-sdk';
runstate.configure({
apiKey: process.env.RUNSTATE_API_KEY,
spaceId: process.env.RUNSTATE_SPACE_ID,
run: 'nightly',
worker: 'research-worker-1', // label shown in the console
timeout: '10s', // per request
retries: 3, // transport retries
});

To use several spaces or runs side by side, create a Runstate instance. It has exactly the same methods as the default client.

import { Runstate } from 'runstate-sdk';
const staging = new Runstate({ spaceId: process.env.STAGING_SPACE_ID, run: 'nightly' });
const research = staging.once(researchCompany);
Option (TS / Python) Default Notes
apiKey / api_key RUNSTATE_API_KEY Required.
spaceId / space_id RUNSTATE_SPACE_ID Required.
baseUrl / base_url RUNSTATE_BASE_URL, else https://api.getrunstate.com
run RUNSTATE_RUN, else default The run this client joins.
worker <hostname>-<pid> Label for this process, shown in the console.
timeout 30s Deadline for each request.
retries 3 Transport retries after a network failure.
  • Durations are a number of seconds or a string: '500ms', '30s', '10m', '2h', '1d'. The same in both languages.
  • per (for limit) also accepts 'second', 'minute', 'hour' or 'day'.
  • Amounts are numbers or decimal strings in major units (0.40, '12.5'). The SDK converts them to exact integer minor units using the budget’s scale. Numbers are rounded half up to the scale, so float noise like 0.1 + 0.2 becomes 0.30. A string with more decimal places than the scale is a ConfigError.

Create and revoke keys in the console under API keys in a space. The secret is shown once and never stored in readable form. Organization, space and key management is console-only today.

Each key has a set of permissions. Doing the work is separate from setting things up, so a worker key doesn’t need to be able to create or resize limits, slots or budgets:

Permission Allows
coordination_read Reading runs, results, jobs, events and status, and looking up existing limits, slots, budgets and queues by name.
coordination_write Doing the work: joining, stopping and finishing runs, once, taking limit units and slots, reserving and charging budget, submitting and serving queue jobs, gather, sleep and together.
resource_config Setting up the space: creating limits, slots, budgets and queues the first time code declares them (max, per, limit), webhook destinations, and changing space limits.
usage_read Usage, space limits and webhook delivery history.

Keys created in the console start with all four. A typical least-privilege split is an admin key with all four that runs once to declare resources, and worker keys with coordination_read and coordination_write.

With a worker key, declaring a resource still works when it already exists with the same sizes: the SDK looks it up and checks the sizes. Only creating a missing resource needs resource_config. A key without the permission a call needs gets AuthError, with a message naming the permission. Every endpoint’s permission is listed in the HTTP API reference.

A key can also be limited to specific spaces; using it for another space returns AuthError.

Every process has a worker label. It defaults to <hostname>-<pid> and shows in the console next to the work the process holds. Set worker to something stable, such as the pod name, to make the console easier to read. Two processes with the same label are still told apart: each client instance also has its own random session.

  • Per-request timeout. timeout (default 30 seconds) applies to each HTTP request.
  • Transport retries. The SDKs retry network failures and timeouts up to retries times (default 3), then throw UnavailableError.
  • Busy is not an error. When a resource is busy, a limit window is used up, or your plan’s concurrency limit is reached, the SDK waits and retries, honouring Retry-After. You only see an error if the wait’s own timeout runs out (TimeoutError).
  • Idempotency. Every request that changes state carries an Idempotency-Key that stays the same across transport retries, so a retried request is never applied twice. once and queue jobs are also keyed by their arguments, so calling them again in the same run returns the same result.
  • Waits end locally. When a wait for a job result or together times out, only your wait ends. The work keeps going on the server.

The SDKs cover TypeScript and Python. Any other language can use the HTTP API with the same key and space id.