Skip to content

Jobs API ​

The Jobs API allows you to manage individual jobs on the Nosana Network. Jobs are single execution units that can be posted directly using credits, without requiring a deployment.

Overview ​

Jobs are different from deployments:

  • Jobs: Single execution units, posted directly with credits using an IPFS hash
  • Deployments: Orchestration layer that manages multiple job instances with strategies

Use the Jobs API when you need to:

  • Post a one-time job execution using credits
  • Get information about a specific job
  • Extend a running job's execution time
  • Stop a running job

Idempotency ​

The Post, Extend, and Stop operations accept an optional idempotency key. When you provide one, it is sent as the Idempotency-Key request header and the API de-duplicates retried requests that share the same key — so a network retry won't create a second job or apply an action twice.

The key is completely optional: omitting it leaves request behaviour unchanged. Generate a unique value per logical operation and reuse the same value when you retry that operation — a different key per attempt provides no de-duplication.

The SDK ships a generateIdempotencyKey() helper (a UUID generator that works in Node and the browser) so you don't have to reach for crypto yourself.

Pass an idempotencyKey in the options object (the last argument):

ts
import { function generateIdempotencyKey(): string
Generates a unique idempotency key suitable for the optional `idempotencyKey` option on the jobs API (`list`, `extend`, `stop`). Reuse the returned value when retrying the *same* logical operation so the API can de-duplicate the retry. Generate a fresh key for each new operation — a different key per attempt provides no de-duplication. Uses the Web Crypto API, which is available in Node 20+ and modern browsers.
@exampleconst key = generateIdempotencyKey(); await api.jobs.list(request, { idempotencyKey: key }); // ...later, retrying the SAME request: await api.jobs.list(request, { idempotencyKey: key }); // de-duplicated
generateIdempotencyKey
} from '@nosana/kit';
const const key: stringkey = function generateIdempotencyKey(): string
Generates a unique idempotency key suitable for the optional `idempotencyKey` option on the jobs API (`list`, `extend`, `stop`). Reuse the returned value when retrying the *same* logical operation so the API can de-duplicate the retry. Generate a fresh key for each new operation — a different key per attempt provides no de-duplication. Uses the Web Crypto API, which is available in Node 20+ and modern browsers.
@exampleconst key = generateIdempotencyKey(); await api.jobs.list(request, { idempotencyKey: key }); // ...later, retrying the SAME request: await api.jobs.list(request, { idempotencyKey: key }); // de-duplicated
generateIdempotencyKey
();
const
const result: {
    tx: string;
    job: string;
    run: string;
    credits: {
        costUSD: number;
        creditsUsed: number;
        reservationId: string;
        project: string;
    };
}
result
= await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.list: (request: NosanaApiListJobRequest, options?: NosanaJobActionOptions) => Promise<NosanaApiListJobResponse>list(
{ ipfsHash: stringipfsHash: 'QmYourJobDefinitionIPFSHash', market: stringmarket: 'CA5pMpqkYFKtme7K31pNB1s62X2SdhEv1nN9RdxKCpuQ', }, { NosanaJobActionOptions.idempotencyKey?: string | undefined
Optional idempotency key. When provided it is sent as the `Idempotency-Key` request header so the API can safely de-duplicate retried requests. The header is fully optional and omitting it leaves behaviour unchanged.
idempotencyKey
: const key: stringkey },
); // Retrying the SAME operation? Pass the SAME key so it is de-duplicated: await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.list: (request: NosanaApiListJobRequest, options?: NosanaJobActionOptions) => Promise<NosanaApiListJobResponse>list( { ipfsHash: stringipfsHash: 'QmYourJobDefinitionIPFSHash', market: stringmarket: 'CA5pMpqkYFKtme7K31pNB1s62X2SdhEv1nN9RdxKCpuQ', }, { NosanaJobActionOptions.idempotencyKey?: string | undefined
Optional idempotency key. When provided it is sent as the `Idempotency-Key` request header so the API can safely de-duplicate retried requests. The header is fully optional and omitting it leaves behaviour unchanged.
idempotencyKey
: const key: stringkey },
);

Control responses ​

A rejected request throws a NosanaApiError. error.statusCode is always set, and error.retryAfter (seconds) is populated from Retry-After when present.

The key distinction is code, not the HTTP status: a 409 that carries a machine-readable code is a control signal (retry / fresh-key / fatal); any error without a code is an ordinary rejection. Use isIdempotencyControlSignal to make that split, then branch on the exported IdempotencyCode constants — what each code means for your retry policy is up to you.

ts
import { 
type IdempotencyCode = "IDEMPOTENCY_KEY_IN_PROGRESS" | "IDEMPOTENCY_KEY_EXPIRED" | "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH"
const IdempotencyCode: {
    readonly IN_PROGRESS: "IDEMPOTENCY_KEY_IN_PROGRESS";
    readonly EXPIRED: "IDEMPOTENCY_KEY_EXPIRED";
    readonly PAYLOAD_MISMATCH: "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH";
}
Machine-readable control codes the API returns (as a `409` with the code in the body, lifted onto {@link NosanaApiError.code } ) for an idempotent request. The kit owns only this wire contract — *which* code maps to retry / fatal / fresh-key is the caller's policy. Removing or renaming a member is a breaking change, so consumers branching on these get a compile signal if they drift. These constants mirror the `IdempotencyCode` enum in the client-manager OpenAPI spec; keep them in sync when the spec changes. - `IN_PROGRESS` — a matching request is still in flight; retry the same key later (honouring `retryAfter`). - `EXPIRED` — the prepared transaction is provably dead; re-post with a fresh key. - `PAYLOAD_MISMATCH` — the same key was reused with a different payload; fatal.
IdempotencyCode
,
function isIdempotencyControlSignal(err: unknown): err is NosanaApiError & {
    code: IdempotencyCode;
}
Narrows a caught value to a coded idempotency **control signal** — a `409` whose body carries a known {@link IdempotencyCode } (`IN_PROGRESS` → retry the same key, `EXPIRED` → fresh key, `PAYLOAD_MISMATCH` → fatal). The membership check is what makes the `code: IdempotencyCode` narrowing sound: `NosanaApiError.code` is a free-form server code, so this returns `false` for a code-less error, a network failure, *and* any non-idempotency code — all of which the caller should treat as ordinary rejections. An exhaustive `switch` over the narrowed `code` is therefore genuinely exhaustive.
isIdempotencyControlSignal
} from '@nosana/kit';
try { await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.list: (request: NosanaApiListJobRequest, options?: NosanaJobActionOptions) => Promise<NosanaApiListJobResponse>list(const request: NosanaApiListJobRequestrequest, { NosanaJobActionOptions.idempotencyKey?: string | undefined
Optional idempotency key. When provided it is sent as the `Idempotency-Key` request header so the API can safely de-duplicate retried requests. The header is fully optional and omitting it leaves behaviour unchanged.
idempotencyKey
: const key: stringkey });
} catch (var error: unknownerror) { if (!
function isIdempotencyControlSignal(err: unknown): err is NosanaApiError & {
    code: IdempotencyCode;
}
Narrows a caught value to a coded idempotency **control signal** — a `409` whose body carries a known {@link IdempotencyCode } (`IN_PROGRESS` → retry the same key, `EXPIRED` → fresh key, `PAYLOAD_MISMATCH` → fatal). The membership check is what makes the `code: IdempotencyCode` narrowing sound: `NosanaApiError.code` is a free-form server code, so this returns `false` for a code-less error, a network failure, *and* any non-idempotency code — all of which the caller should treat as ordinary rejections. An exhaustive `switch` over the narrowed `code` is therefore genuinely exhaustive.
isIdempotencyControlSignal
(var error: unknownerror)) throw var error: unknownerror; // ordinary error or network failure
switch (
var error: NosanaApiError & {
    code: IdempotencyCode;
}
error
.code: "IDEMPOTENCY_KEY_IN_PROGRESS" | "IDEMPOTENCY_KEY_EXPIRED" | "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH"
Free-form server machine code, when present. May be an {@link IdempotencyCode } (a control signal) or another domain code — so do not assume it is one of the idempotency codes. Use {@link isIdempotencyControlSignal } to detect and narrow to the idempotency control codes.
code
) {
case
const IdempotencyCode: {
    readonly IN_PROGRESS: "IDEMPOTENCY_KEY_IN_PROGRESS";
    readonly EXPIRED: "IDEMPOTENCY_KEY_EXPIRED";
    readonly PAYLOAD_MISMATCH: "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH";
}
Machine-readable control codes the API returns (as a `409` with the code in the body, lifted onto {@link NosanaApiError.code } ) for an idempotent request. The kit owns only this wire contract — *which* code maps to retry / fatal / fresh-key is the caller's policy. Removing or renaming a member is a breaking change, so consumers branching on these get a compile signal if they drift. These constants mirror the `IdempotencyCode` enum in the client-manager OpenAPI spec; keep them in sync when the spec changes. - `IN_PROGRESS` — a matching request is still in flight; retry the same key later (honouring `retryAfter`). - `EXPIRED` — the prepared transaction is provably dead; re-post with a fresh key. - `PAYLOAD_MISMATCH` — the same key was reused with a different payload; fatal.
IdempotencyCode
.type IN_PROGRESS: "IDEMPOTENCY_KEY_IN_PROGRESS"IN_PROGRESS:
// A matching request is still in flight — retry the SAME key later. // error.retryAfter holds the suggested delay in seconds, when provided. break; case
const IdempotencyCode: {
    readonly IN_PROGRESS: "IDEMPOTENCY_KEY_IN_PROGRESS";
    readonly EXPIRED: "IDEMPOTENCY_KEY_EXPIRED";
    readonly PAYLOAD_MISMATCH: "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH";
}
Machine-readable control codes the API returns (as a `409` with the code in the body, lifted onto {@link NosanaApiError.code } ) for an idempotent request. The kit owns only this wire contract — *which* code maps to retry / fatal / fresh-key is the caller's policy. Removing or renaming a member is a breaking change, so consumers branching on these get a compile signal if they drift. These constants mirror the `IdempotencyCode` enum in the client-manager OpenAPI spec; keep them in sync when the spec changes. - `IN_PROGRESS` — a matching request is still in flight; retry the same key later (honouring `retryAfter`). - `EXPIRED` — the prepared transaction is provably dead; re-post with a fresh key. - `PAYLOAD_MISMATCH` — the same key was reused with a different payload; fatal.
IdempotencyCode
.type EXPIRED: "IDEMPOTENCY_KEY_EXPIRED"EXPIRED:
// The prepared transaction is dead — re-post with a fresh key. break; case
const IdempotencyCode: {
    readonly IN_PROGRESS: "IDEMPOTENCY_KEY_IN_PROGRESS";
    readonly EXPIRED: "IDEMPOTENCY_KEY_EXPIRED";
    readonly PAYLOAD_MISMATCH: "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH";
}
Machine-readable control codes the API returns (as a `409` with the code in the body, lifted onto {@link NosanaApiError.code } ) for an idempotent request. The kit owns only this wire contract — *which* code maps to retry / fatal / fresh-key is the caller's policy. Removing or renaming a member is a breaking change, so consumers branching on these get a compile signal if they drift. These constants mirror the `IdempotencyCode` enum in the client-manager OpenAPI spec; keep them in sync when the spec changes. - `IN_PROGRESS` — a matching request is still in flight; retry the same key later (honouring `retryAfter`). - `EXPIRED` — the prepared transaction is provably dead; re-post with a fresh key. - `PAYLOAD_MISMATCH` — the same key was reused with a different payload; fatal.
IdempotencyCode
.type PAYLOAD_MISMATCH: "IDEMPOTENCY_KEY_PAYLOAD_MISMATCH"PAYLOAD_MISMATCH:
// Same key reused with a different payload — do not retry. break; } }

Get Job by Address ​

Retrieve information about a specific job:

ts
import { 
function createNosanaClient(network: NosanaNetwork | undefined, customConfig: PartialClientConfig & {
    connect: ConnectFactoryConfig & {
        clientSecret: string;
    };
}): NosanaClient & {
    connect: ServerConnect;
} (+3 overloads)
createNosanaClient
,
type NosanaNetwork = "mainnet" | "devnet" | "localnet"
const NosanaNetwork: {
    readonly MAINNET: "mainnet";
    readonly DEVNET: "devnet";
    readonly LOCALNET: "localnet";
}
NosanaNetwork
} from '@nosana/kit';
const const client: NosanaClientclient = function createNosanaClient(network?: NosanaNetwork, customConfig?: PartialClientConfig): NosanaClient (+3 overloads)createNosanaClient(
const NosanaNetwork: {
    readonly MAINNET: "mainnet";
    readonly DEVNET: "devnet";
    readonly LOCALNET: "localnet";
}
NosanaNetwork
.type MAINNET: "mainnet"MAINNET, {
PartialClientConfig.api?: Partial<APIConfig> | undefinedapi: { apiKey?: string | undefinedapiKey:
const process: {
    env: Record<string, string>;
}
process
.env: Record<string, string>env.stringNOSANA_API_KEY,
}, }); // Get job information const const job: NodeJobjob = await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.get: (request: NosanaApiGetJobByAddressRequest) => Promise<NodeJob>get('job-address-here'); var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
('Job State:', const job: NodeJobjob.state: numberstate);
var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
('Node:', const job: NodeJobjob.node: stringnode);
var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
('Job Definition IPFS hash:', const job: NodeJobjob.ipfsJob: string | nullipfsJob);
// The node job API rides on the same object — no extra fetch, no local wallet. // Stream task logs (history first, then live). `logs()` returns a subscription; // call close() when you're done. const const logs: StreamSubscriptionlogs = const job: NodeJobjob.NodeJobApi.logs(handlers: NodeStreamHandlers<NodeTaskLog>, filter?: NodeLogsFilter, options?: NodeSocketOptions): NodeStreamSubscription
Task manager logs over WebSocket: history first, then live.
logs
({
NodeStreamHandlers<{ opId: string; group: string; type: string; timestamp: number; message: unknown; }>.onData: (data: {
    opId: string;
    group: string;
    type: string;
    timestamp: number;
    message: unknown;
}) => void
onData
: (
log: {
    opId: string;
    group: string;
    type: string;
    timestamp: number;
    message: unknown;
}
log
) => var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
(`[${
log: {
    opId: string;
    group: string;
    type: string;
    timestamp: number;
    message: unknown;
}
log
.opId: stringopId}]`,
log: {
    opId: string;
    group: string;
    type: string;
    timestamp: number;
    message: unknown;
}
log
.message: unknownmessage),
StreamLifecycleHandlers.onError?: ((error: unknown) => void) | undefinedonError: (err: unknownerr) => var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.error(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stderr` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const code = 5; console.error('error #%d', code); // Prints: error #5, to stderr console.error('error', code); // Prints: error 5, to stderr ``` If formatting elements (e.g. `%d`) are not found in the first string then [`util.inspect()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilinspectobject-options) is called on each argument and the resulting string values are concatenated. See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
error
('log stream error:', err: unknownerr),
}); // …later const logs: StreamSubscriptionlogs.close: () => voidclose(); // Connect over SSH: authorize a public key, then print the ready-to-run command. await const job: NodeJobjob.NodeJobApi.ssh: NodeJobSshssh.NodeJobSsh.add(publicKey: string, options?: NodeSshAddKeyOptions): Promise<NodeSshAuthorization>add('ssh-ed25519 AAAA... you@laptop'); const const ssh: SshConnectionDescriptorssh = const job: NodeJobjob.NodeJobApi.ssh: NodeJobSshssh.NodeJobSsh.command(options?: SshCommandOptions): SshConnectionDescriptor
The `ssh` command that reaches the job; `identityFile` picks the private key to connect with.
command
({ SshCommandOptions.identityFile?: string | undefined
The private key to connect with, passed to `ssh -i`.
identityFile
: '~/.ssh/id_ed25519' });
var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
(const ssh: SshConnectionDescriptorssh.SshConnectionDescriptor.formattedCommand: string
The full command, shell-quoted for copy and paste.
formattedCommand
);

The returned job merges the indexer state (state, node, ipfsJob, …) with the live node job API, so definition(), results(), logs(), ssh and terminal() all live on the one object. The node calls are authorized on your behalf (signer, API key, or a browser session), so they work without a local wallet; under unauthenticated public access the shape is identical but those node calls will fail.

Manage an Active Job ​

Once a job is running, the object returned by jobs.get(id) exposes the node's live job API — inspect its operations, stream stats, restart or stop individual operations, collect results, or open an interactive terminal. These reach the node directly and require an authenticated client, so they are SDK-only.

With an API key or an app's token, the SDK signs these node requests through your account, which needs the wallet:sign permission. To read job data with a narrower key, use Read Job Data instead.

ts
const const job: NodeJobjob = await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.get: (request: NosanaApiGetJobByAddressRequest) => Promise<NodeJob>get('job-address-here');

// Inspect the job's operations and the endpoints it exposes.
var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
('Operations:', await const job: NodeJobjob.NodeJobApi.operations(): Promise<NodeOperationStatuses>operations());
var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
('Endpoints:', await const job: NodeJobjob.NodeJobApi.endpoints(): Promise<NodeJobEndpoints>endpoints());
// Stream resource stats (CPU / memory / …) as the node samples them. const const stats: StreamSubscriptionstats = const job: NodeJobjob.NodeJobApi.streamStats(handlers: NodeStreamHandlers<NodeTaskStat[]>, query?: Pick<NodeStatsQuery, "interval">): NodeStreamSubscriptionstreamStats( {
NodeStreamHandlers<{ opId: string; timestamp: number; cpu: { cpu_percent: number; }; memory: { memory_usage: number; memory_limit: number; memory_percent: number; }; disk: { read: number; write: number; }; network: { received: number; sent: number; }; gpu?: components["schemas"]["TaskGpuStat"]; }[]>.onData: (data: {
    opId: string;
    timestamp: number;
    cpu: {
        cpu_percent: number;
    };
    memory: {
        memory_usage: number;
        memory_limit: number;
        memory_percent: number;
    };
    disk: {
        read: number;
        write: number;
    };
    network: {
        received: number;
        sent: number;
    };
    gpu?: components["schemas"]["TaskGpuStat"];
}[]) => void
onData
: (
samples: {
    opId: string;
    timestamp: number;
    cpu: {
        cpu_percent: number;
    };
    memory: {
        memory_usage: number;
        memory_limit: number;
        memory_percent: number;
    };
    disk: {
        read: number;
        write: number;
    };
    network: {
        received: number;
        sent: number;
    };
    gpu?: components["schemas"]["TaskGpuStat"];
}[]
samples
) => var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
('stats:',
samples: {
    opId: string;
    timestamp: number;
    cpu: {
        cpu_percent: number;
    };
    memory: {
        memory_usage: number;
        memory_limit: number;
        memory_percent: number;
    };
    disk: {
        read: number;
        write: number;
    };
    network: {
        received: number;
        sent: number;
    };
    gpu?: components["schemas"]["TaskGpuStat"];
}[]
samples
) },
{ interval?: number | undefined
Seconds between samples.
interval
: 5 },
); // …later const stats: StreamSubscriptionstats.close: () => voidclose(); // Restart or stop a single operation within a group. await const job: NodeJobjob.NodeJobApi.restartOperation(group: string, op: string): Promise<void>restartOperation('default', 'my-op'); await const job: NodeJobjob.NodeJobApi.stopOperation(group: string, op: string): Promise<void>stopOperation('default', 'my-op'); // Stop the whole job. await const job: NodeJobjob.NodeJobApi.stop(): Promise<void>stop(); // Once finished, collect the flow results (the node hands them over once). var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
('Results:', await const job: NodeJobjob.NodeJobApi.results(): Promise<FlowState>
The finished flow; the node hands it over once and marks it collected.
results
());

Open an Interactive Terminal ​

Attach a PTY to the running job. The node streams output through onData; write back with sendInput, resize with resize, and end the session with close.

ts
const const terminal: TerminalSessionterminal = await const job: NodeJobjob.NodeJobApi.terminal(options: NodeTerminalOptions): Promise<TerminalSession>
Opens a web terminal into the job; progress arrives through `onStatus`.
terminal
({
NodeTerminalOptions.cols: numbercols: 80, NodeTerminalOptions.rows: numberrows: 24, NodeTerminalOptions.onData: (data: Uint8Array) => voidonData: (bytes: Uint8Array<ArrayBufferLike>bytes) => var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
(new var TextDecoder: new (label?: string, options?: TextDecoderOptions) => TextDecoder
The **`TextDecoder`** interface represents a decoder for a specific text encoding, such as `UTF-8`, `ISO-8859-2`, `KOI8-R`, `GBK`, etc. [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder) `TextDecoder` class is a global reference for `import { TextDecoder } from 'node:util'` https://nodejs.org/api/globals.html#textdecoder
@sincev11.0.0
TextDecoder
().TextDecoder.decode(input?: AllowSharedBufferSource, options?: TextDecodeOptions): string
The **`TextDecoder.decode()`** method returns a string containing text decoded from the buffer passed as a parameter. [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/decode)
decode
(bytes: Uint8Array<ArrayBufferLike>bytes)),
NodeTerminalOptions.onStatus?: ((status: TerminalStatus, detail?: string) => void) | undefinedonStatus: (status: TerminalStatusstatus) => var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
('terminal:', status: TerminalStatusstatus),
}); const terminal: TerminalSessionterminal.TerminalSession.sendInput(data: string): voidsendInput('ls -la\n'); const terminal: TerminalSessionterminal.TerminalSession.resize(cols: number, rows: number): voidresize(120, 40); const terminal: TerminalSessionterminal.TerminalSession.close(): voidclose();

Read Job Data ​

With the jobs:read permission, you can read a running job's data from its node over plain HTTP. Nosana signs the request to the node for you, so the key doesn't need wallet:sign, and it can't change the job.

bash
curl https://api.nosana.com/jobs/{address}/node/ops \
  -H "Authorization: Bearer nos_xxx_your_api_key"
PathReturns
GET /jobs/{address}/node/infoA live stream (server-sent events) of the job's state and task status, until the job ends
GET /jobs/{address}/node/job-definitionThe job definition the node is running
GET /jobs/{address}/node/endpointsThe URLs the job exposes, and whether they answer yet
GET /jobs/{address}/node/statsCPU, memory, disk and network samples. Accepts interval, start and end
GET /jobs/{address}/node/opsThe status of every operation
GET /jobs/{address}/node/ops/{opId}The status of one operation
GET /jobs/{address}/node/group/currentThe status of the operations in the group that's running
GET /jobs/{address}/node/group/{group}The status of the operations in one group
GET /jobs/{address}/node/resultsThe finished flow state

WARNING

results is only available once the job is waiting for its results to be collected, and reading it lets the node finish the job. Don't call it just to check on a running job.

Only jobs posted from your account can be read, including your deployments' jobs.

StatusMeaning
404No job with that address, or it wasn't posted from your account
409The job hasn't been picked up by a node yet
502The node running the job couldn't be reached

Any other status comes from the node itself, for example a 400 when a resource isn't available in the job's current state.

Post Job ​

Post a job to the Nosana Network using credits. The job definition must be uploaded to IPFS first, and you provide the IPFS hash.

ts
// Post a job using credits
const 
const job: {
    tx: string;
    job: string;
    run: string;
    credits: {
        costUSD: number;
        creditsUsed: number;
        reservationId: string;
        project: string;
    };
}
job
= await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.list: (request: NosanaApiListJobRequest, options?: NosanaJobActionOptions) => Promise<NosanaApiListJobResponse>list(
{ ipfsHash: stringipfsHash: 'QmYourJobDefinitionIPFSHash', market: stringmarket: 'CA5pMpqkYFKtme7K31pNB1s62X2SdhEv1nN9RdxKCpuQ', timeout?: number | undefinedtimeout: 600, // Optional: max runtime in seconds (default: 3600) node?: string | undefinednode: 'node-address', // Optional: specific node to run on }, // Optional: see the "Idempotency" section above. { NosanaJobActionOptions.idempotencyKey?: string | undefined
Optional idempotency key. When provided it is sent as the `Idempotency-Key` request header so the API can safely de-duplicate retried requests. The header is fully optional and omitting it leaves behaviour unchanged.
idempotencyKey
: function generateIdempotencyKey(): string
Generates a unique idempotency key suitable for the optional `idempotencyKey` option on the jobs API (`list`, `extend`, `stop`). Reuse the returned value when retrying the *same* logical operation so the API can de-duplicate the retry. Generate a fresh key for each new operation — a different key per attempt provides no de-duplication. Uses the Web Crypto API, which is available in Node 20+ and modern browsers.
@exampleconst key = generateIdempotencyKey(); await api.jobs.list(request, { idempotencyKey: key }); // ...later, retrying the SAME request: await api.jobs.list(request, { idempotencyKey: key }); // de-duplicated
generateIdempotencyKey
() },
); var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
('Job Address:',
const job: {
    tx: string;
    job: string;
    run: string;
    credits: {
        costUSD: number;
        creditsUsed: number;
        reservationId: string;
        project: string;
    };
}
job
.job: stringjob);

Job Definition on IPFS ​

Before posting a job, you need to upload your job definition to IPFS. You can use the Nosana IPFS service. It's a good idea to validate the job definition first — it catches schema mistakes before you upload or spend credits:

ts
import { 
function createNosanaClient(network: NosanaNetwork | undefined, customConfig: PartialClientConfig & {
    connect: ConnectFactoryConfig & {
        clientSecret: string;
    };
}): NosanaClient & {
    connect: ServerConnect;
} (+3 overloads)
createNosanaClient
,
type NosanaNetwork = "mainnet" | "devnet" | "localnet"
const NosanaNetwork: {
    readonly MAINNET: "mainnet";
    readonly DEVNET: "devnet";
    readonly LOCALNET: "localnet";
}
NosanaNetwork
} from '@nosana/kit';
const const client: NosanaClientclient = function createNosanaClient(network?: NosanaNetwork, customConfig?: PartialClientConfig): NosanaClient (+3 overloads)createNosanaClient(
const NosanaNetwork: {
    readonly MAINNET: "mainnet";
    readonly DEVNET: "devnet";
    readonly LOCALNET: "localnet";
}
NosanaNetwork
.type MAINNET: "mainnet"MAINNET, {
PartialClientConfig.api?: Partial<APIConfig> | undefinedapi: { apiKey?: string | undefinedapiKey:
const process: {
    env: Record<string, string>;
}
process
.env: Record<string, string>env.stringNOSANA_API_KEY,
}, }); // Upload (pin) the job definition to IPFS const const ipfsHash: stringipfsHash = await const client: NosanaClientclient.NosanaClient.ipfs: NosanaIpfsClientipfs.pin: (data: object) => Promise<string>pin(const jobDefinitionJson: JobDefinitionjobDefinitionJson); // Then post the job using the IPFS hash const
const result: {
    tx: string;
    job: string;
    run: string;
    credits: {
        costUSD: number;
        creditsUsed: number;
        reservationId: string;
        project: string;
    };
}
result
= await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.list: (request: NosanaApiListJobRequest, options?: NosanaJobActionOptions) => Promise<NosanaApiListJobResponse>list({
ipfsHash: stringipfsHash: const ipfsHash: stringipfsHash, market: stringmarket: 'CA5pMpqkYFKtme7K31pNB1s62X2SdhEv1nN9RdxKCpuQ', }); var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
('Job Address:',
const result: {
    tx: string;
    job: string;
    run: string;
    credits: {
        costUSD: number;
        creditsUsed: number;
        reservationId: string;
        project: string;
    };
}
result
.job: stringjob);
var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
('Credits Used:',
const result: {
    tx: string;
    job: string;
    run: string;
    credits: {
        costUSD: number;
        creditsUsed: number;
        reservationId: string;
        project: string;
    };
}
result
.
credits: {
    costUSD: number;
    creditsUsed: number;
    reservationId: string;
    project: string;
}
credits
.creditsUsed: numbercreditsUsed);

:::

Extend Job ​

Extend the execution time of a running job:

ts
// Extend job execution time
const 
const result: {
    tx: (string | null) | null;
    job: string;
    credits?: {
        costUSD: number;
        creditsUsed: number;
        reservationId: string;
    };
}
result
= await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.extend: (request: NosanaApiExtendJobRequest, options?: NosanaJobActionOptions) => Promise<NosanaApiExtendJobResponse>extend(
{ address: string
@descriptionJob address
address
: 'job-address-here',
seconds: string | number
@descriptionNumber of seconds to extend the job
seconds
: 3600, // Additional seconds
}, // Optional: see the "Idempotency" section above. { NosanaJobActionOptions.idempotencyKey?: string | undefined
Optional idempotency key. When provided it is sent as the `Idempotency-Key` request header so the API can safely de-duplicate retried requests. The header is fully optional and omitting it leaves behaviour unchanged.
idempotencyKey
: function generateIdempotencyKey(): string
Generates a unique idempotency key suitable for the optional `idempotencyKey` option on the jobs API (`list`, `extend`, `stop`). Reuse the returned value when retrying the *same* logical operation so the API can de-duplicate the retry. Generate a fresh key for each new operation — a different key per attempt provides no de-duplication. Uses the Web Crypto API, which is available in Node 20+ and modern browsers.
@exampleconst key = generateIdempotencyKey(); await api.jobs.list(request, { idempotencyKey: key }); // ...later, retrying the SAME request: await api.jobs.list(request, { idempotencyKey: key }); // de-duplicated
generateIdempotencyKey
() },
); // `tx` is null (and `credits` is omitted) when the job was already terminal — // a confirmed no-op, nothing was charged. Extending a terminal job never errors. if (
const result: {
    tx: (string | null) | null;
    job: string;
    credits?: {
        costUSD: number;
        creditsUsed: number;
        reservationId: string;
    };
}
result
.tx: string | nulltx === null) {
// already finished — nothing to do }

Stop Job ​

Stop a running job:

ts
// Stop a running job
const 
const result: {
    tx: (string | null) | null;
    job: string;
    delisted: boolean;
    outcome?: "delisted" | "ended" | "already_terminal";
}
result
= await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.stop: (request: NosanaApiStopJobRequest, options?: NosanaJobActionOptions) => Promise<NosanaApiStopJobResponse>stop('job-address-here');
// Optionally pass an idempotency key (see the "Idempotency" section above): const
const stopped: {
    tx: (string | null) | null;
    job: string;
    delisted: boolean;
    outcome?: "delisted" | "ended" | "already_terminal";
}
stopped
= await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.stop: (request: NosanaApiStopJobRequest, options?: NosanaJobActionOptions) => Promise<NosanaApiStopJobResponse>stop('job-address-here', {
NosanaJobActionOptions.idempotencyKey?: string | undefined
Optional idempotency key. When provided it is sent as the `Idempotency-Key` request header so the API can safely de-duplicate retried requests. The header is fully optional and omitting it leaves behaviour unchanged.
idempotencyKey
: function generateIdempotencyKey(): string
Generates a unique idempotency key suitable for the optional `idempotencyKey` option on the jobs API (`list`, `extend`, `stop`). Reuse the returned value when retrying the *same* logical operation so the API can de-duplicate the retry. Generate a fresh key for each new operation — a different key per attempt provides no de-duplication. Uses the Web Crypto API, which is available in Node 20+ and modern browsers.
@exampleconst key = generateIdempotencyKey(); await api.jobs.list(request, { idempotencyKey: key }); // ...later, retrying the SAME request: await api.jobs.list(request, { idempotencyKey: key }); // de-duplicated
generateIdempotencyKey
(),
});

Batch Operations ​

Post, extend, or stop many jobs in one request, packed into the fewest transactions. Unlike the single-job calls, batch endpoints require an Idempotency-Key header (one key per batch) — the request is rejected with 400 if it is missing.

Every batch returns per-item results addressed by request index:

json
{
  "items": [
    { "index": 0, "status": "confirmed", "job": "job-address", "run": "run-address", "tx": "tx-signature" },
    { "index": 1, "status": "expired" }
  ]
}
  • confirmed — the item landed (its job/run are included for posts).
  • expired — the item did not land; re-post only those items under a fresh key.
  • tx — the on-chain signature, useful for tracing. Items packed into the same transaction share one tx; it's absent on expired items and on already-terminal no-ops (extend/stop of a finished job, where nothing is sent).

If a batch is still confirming you'll get a 409 IDEMPOTENCY_KEY_IN_PROGRESS — retry with the same batch key; items that already landed stay landed. See Control responses for the error contract.

Batch Post ​

ts
import { function generateIdempotencyKey(): string
Generates a unique idempotency key suitable for the optional `idempotencyKey` option on the jobs API (`list`, `extend`, `stop`). Reuse the returned value when retrying the *same* logical operation so the API can de-duplicate the retry. Generate a fresh key for each new operation — a different key per attempt provides no de-duplication. Uses the Web Crypto API, which is available in Node 20+ and modern browsers.
@exampleconst key = generateIdempotencyKey(); await api.jobs.list(request, { idempotencyKey: key }); // ...later, retrying the SAME request: await api.jobs.list(request, { idempotencyKey: key }); // de-duplicated
generateIdempotencyKey
} from '@nosana/kit';
const
const result: {
    items: {
        index: number;
        status: "confirmed" | "expired";
        job?: string;
        run?: string;
        tx?: string;
    }[];
}
result
= await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.listBatch: (request: NosanaApiListJobBatchRequest, options: NosanaJobBatchOptions) => Promise<NosanaApiJobsBatchResponse>listBatch(
{
jobs: {
    ipfsHash: string;
    market: string;
    timeout?: number;
}[]
@descriptionJobs to bulk-create
jobs
: [
{ ipfsHash: string
@descriptionIPFS hash of the job definition
ipfsHash
: 'QmJobDefinitionA', market: string
@descriptionMarket address
market
: 'CA5pMpqkYFKtme7K31pNB1s62X2SdhEv1nN9RdxKCpuQ', timeout?: number | undefined
@descriptionJob timeout in seconds (default: 3600). Same 3600-second minimum as single LIST; one too-short item rejects the whole batch with 400.
timeout
: 3600 },
{ ipfsHash: string
@descriptionIPFS hash of the job definition
ipfsHash
: 'QmJobDefinitionB', market: string
@descriptionMarket address
market
: 'CA5pMpqkYFKtme7K31pNB1s62X2SdhEv1nN9RdxKCpuQ' },
], }, { NosanaJobBatchOptions.idempotencyKey: string
Idempotency key for the batch (one key per batch). **Required** — the batch endpoints reject the request with `400` if it is omitted. Reuse the same key when retrying the batch; already-landed items stay landed.
idempotencyKey
: function generateIdempotencyKey(): string
Generates a unique idempotency key suitable for the optional `idempotencyKey` option on the jobs API (`list`, `extend`, `stop`). Reuse the returned value when retrying the *same* logical operation so the API can de-duplicate the retry. Generate a fresh key for each new operation — a different key per attempt provides no de-duplication. Uses the Web Crypto API, which is available in Node 20+ and modern browsers.
@exampleconst key = generateIdempotencyKey(); await api.jobs.list(request, { idempotencyKey: key }); // ...later, retrying the SAME request: await api.jobs.list(request, { idempotencyKey: key }); // de-duplicated
generateIdempotencyKey
() }, // required
); const
const expired: {
    index: number;
    status: "confirmed" | "expired";
    job?: string;
    run?: string;
    tx?: string;
}[]
expired
=
const result: {
    items: {
        index: number;
        status: "confirmed" | "expired";
        job?: string;
        run?: string;
        tx?: string;
    }[];
}
result
.
items: {
    index: number;
    status: "confirmed" | "expired";
    job?: string;
    run?: string;
    tx?: string;
}[]
items
.
Array<{ index: number; status: "confirmed" | "expired"; job?: string; run?: string; tx?: string; }>.filter(predicate: (value: {
    index: number;
    status: "confirmed" | "expired";
    job?: string;
    run?: string;
    tx?: string;
}, index: number, array: {
    index: number;
    status: "confirmed" | "expired";
    job?: string;
    run?: string;
    tx?: string;
}[]) => unknown, thisArg?: any): {
    index: number;
    status: "confirmed" | "expired";
    job?: string;
    run?: string;
    tx?: string;
}[] (+1 overload)
Returns the elements of an array that meet the condition specified in a callback function.
@parampredicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array.@paramthisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.
filter
((
i: {
    index: number;
    status: "confirmed" | "expired";
    job?: string;
    run?: string;
    tx?: string;
}
i
) =>
i: {
    index: number;
    status: "confirmed" | "expired";
    job?: string;
    run?: string;
    tx?: string;
}
i
.status: "confirmed" | "expired"status === 'expired');
// re-post `expired` under a fresh key

Batch Extend ​

ts
const 
const result: {
    items: {
        index: number;
        status: "confirmed" | "expired";
        job?: string;
        run?: string;
        tx?: string;
    }[];
}
result
= await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.extendBatch: (request: NosanaApiExtendJobBatchRequest, options: NosanaJobBatchOptions) => Promise<NosanaApiJobsBatchResponse>extendBatch(
{
jobs: {
    jobAddress: string;
    seconds: number;
}[]
@descriptionJobs to bulk-extend
jobs
: [
{ jobAddress: string
@descriptionJob address
jobAddress
: 'job-address-1', seconds: number
@descriptionSeconds to extend by
seconds
: 3600 },
{ jobAddress: string
@descriptionJob address
jobAddress
: 'job-address-2', seconds: number
@descriptionSeconds to extend by
seconds
: 600 },
], }, { NosanaJobBatchOptions.idempotencyKey: string
Idempotency key for the batch (one key per batch). **Required** — the batch endpoints reject the request with `400` if it is omitted. Reuse the same key when retrying the batch; already-landed items stay landed.
idempotencyKey
: function generateIdempotencyKey(): string
Generates a unique idempotency key suitable for the optional `idempotencyKey` option on the jobs API (`list`, `extend`, `stop`). Reuse the returned value when retrying the *same* logical operation so the API can de-duplicate the retry. Generate a fresh key for each new operation — a different key per attempt provides no de-duplication. Uses the Web Crypto API, which is available in Node 20+ and modern browsers.
@exampleconst key = generateIdempotencyKey(); await api.jobs.list(request, { idempotencyKey: key }); // ...later, retrying the SAME request: await api.jobs.list(request, { idempotencyKey: key }); // de-duplicated
generateIdempotencyKey
() }, // required
);

Batch Stop ​

ts
const 
const result: {
    items: {
        index: number;
        status: "confirmed" | "expired";
        job?: string;
        run?: string;
        tx?: string;
    }[];
}
result
= await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.stopBatch: (request: NosanaApiStopJobBatchRequest, options: NosanaJobBatchOptions) => Promise<NosanaApiJobsBatchResponse>stopBatch(
{
jobs: {
    jobAddress: string;
}[]
@descriptionJobs to bulk-stop
jobs
: [{ jobAddress: string
@descriptionJob address
jobAddress
: 'job-address-1' }, { jobAddress: string
@descriptionJob address
jobAddress
: 'job-address-2' }] },
{ NosanaJobBatchOptions.idempotencyKey: string
Idempotency key for the batch (one key per batch). **Required** — the batch endpoints reject the request with `400` if it is omitted. Reuse the same key when retrying the batch; already-landed items stay landed.
idempotencyKey
: function generateIdempotencyKey(): string
Generates a unique idempotency key suitable for the optional `idempotencyKey` option on the jobs API (`list`, `extend`, `stop`). Reuse the returned value when retrying the *same* logical operation so the API can de-duplicate the retry. Generate a fresh key for each new operation — a different key per attempt provides no de-duplication. Uses the Web Crypto API, which is available in Node 20+ and modern browsers.
@exampleconst key = generateIdempotencyKey(); await api.jobs.list(request, { idempotencyKey: key }); // ...later, retrying the SAME request: await api.jobs.list(request, { idempotencyKey: key }); // de-duplicated
generateIdempotencyKey
() }, // required
);

Job States ​

Jobs progress through the following states:

  • pending - Job is queued and waiting to be scheduled
  • running - Job is currently executing
  • completed - Job finished successfully
  • failed - Job encountered an error
  • stopped - Job was manually stopped

Posting vs Deployments ​

The Jobs API allows you to post individual jobs using credits. For more advanced use cases with orchestration, scheduling, and lifecycle management, use Deployments instead.