Your First Job via the API
This guide walks you through posting your first job on the Nosana Network, end to end: pick a GPU market, write and validate a job definition, upload it to IPFS, post the job with credits, and fetch the results.
Every step uses the @nosana/kit TypeScript SDK. For the raw HTTP equivalents of each call, see the Jobs API reference.
Prerequisites
- API key — see How to Get an API Key
- Credits — your account needs credits to pay for the job; check the Credits API
- Node.js — a recent LTS version
Install the SDK:
npm install @nosana/kitStep 1 — Initialize the client
Create a client for mainnet with your API key, and confirm you have credits to spend:
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 },
});
const const balance: {
assignedCredits: number;
reservedCredits: number;
settledCredits: number;
}
balance = await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.credits: NosanaCreditsApicredits.NosanaCreditsApi.balance: () => Promise<Balance>balance();
var console: ConsoleThe `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
```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.log('Available credits:', const balance: {
assignedCredits: number;
reservedCredits: number;
settledCredits: number;
}
balance.assignedCredits: numberassignedCredits - const balance: {
assignedCredits: number;
reservedCredits: number;
settledCredits: number;
}
balance.reservedCredits: numberreservedCredits - const balance: {
assignedCredits: number;
reservedCredits: number;
settledCredits: number;
}
balance.settledCredits: numbersettledCredits);Step 2 — Pick a market
Jobs run on a GPU market: a pool of hosts with a specific GPU type and hourly price. List the markets and pick one that fits your workload:
const const markets: Market[]markets = await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.markets: NosanaMarketsApimarkets.NosanaMarketsApi.list: () => Promise<Market[]>list();
for (const const market: Marketmarket of const markets: Market[]markets) {
var console: ConsoleThe `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
```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.log(`${const market: Marketmarket.unknownname} (${const market: Marketmarket.unknownaddress}) — ${const market: Marketmarket.unknownvram}GB VRAM`);
}Note the address of the market you want — you'll pass it when posting the job. See Markets for pricing and resource requirements. The examples below use the NVIDIA RTX 3090 market.
Step 3 — Write and validate the job definition
A job definition is a JSON document describing the container to run. Validate it locally before spending anything — the validator catches misspelled fields and schema mistakes:
import { const validateJobDefinition: (input: unknown) => IValidation<JobDefinitionWithRule>validateJobDefinition } from '@nosana/kit';
const const validation: IValidation<JobDefinitionWithRule>validation = function validateJobDefinition(input: unknown): IValidation<JobDefinitionWithRule>validateJobDefinition({
version: stringversion: '0.1',
type: stringtype: 'container',
meta: {
trigger: string;
}
meta: { trigger: stringtrigger: 'api' },
ops: {
type: string;
id: string;
args: {
cmd: string;
image: string;
};
}[]
ops: [
{
type: stringtype: 'container/run',
id: stringid: 'hello-world',
args: {
cmd: string;
image: string;
}
args: {
cmd: stringcmd: 'echo hello world',
image: stringimage: 'ubuntu',
},
},
],
});
if (!const validation: IValidation<JobDefinitionWithRule>validation.success: booleanIndicates validation failure
Indicates validation successsuccess) {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error(
const validation: IValidation.IFailurevalidation.IValidation<T = unknown>.IFailure.errors: IValidation.IError[]Array of detailed validation errorserrors.Array<IValidation<T = unknown>.IError>.map<string>(callbackfn: (value: IValidation<T = unknown>.IError, index: number, array: IValidation.IError[]) => string, thisArg?: any): string[]Calls a defined callback function on each element of an array, and returns an array that contains the results.map((e: IValidation.IErrore) => `${e: IValidation.IErrore.IValidation<T = unknown>.IError.path: stringThe path to the property that failed validation
Dot-notation path using $input prefix indicating the exact location of
the validation failure within the input object structure. Examples
include "$input.member.age", "$input.categories[0]",
"$input.user.profile.email"path}: expected ${e: IValidation.IErrore.IValidation<T = unknown>.IError.expected: stringThe expected type name or type expression
Technical type specification that describes what type was expected at
this path. This follows TypeScript-like syntax with embedded constraint
information, such as "string", "number & Type<'uint32'>",
"Array<string>", "string & Format<'uuid'> & MinLength<8>", etc.expected}`).Array<string>.join(separator?: string): stringAdds all the elements of an array into a string, separated by the specified separator string.join('\n'),
);
}
const const jobDefinition: JobDefinitionWithRulejobDefinition = const validation: IValidation.ISuccess<JobDefinitionWithRule>validation.IValidation<T = unknown>.ISuccess<JobDefinitionWithRule>.data: JobDefinitionWithRuleThe validated data of type Tdata;See Validation for details on the validator.
Step 4 — Upload the job definition to IPFS
Jobs reference their definition by IPFS hash. Pin the validated definition with the built-in IPFS service:
const const ipfsHash: stringipfsHash = await const client: NosanaClientclient.NosanaClient.ipfs: NosanaIpfsClientipfs.pin: (data: object) => Promise<string>pin(const jobDefinition: JobDefinitionjobDefinition);
var console: ConsoleThe `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
```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.log('Job definition pinned:', const ipfsHash: stringipfsHash);Step 5 — Post the job
Post the job to your chosen market, paid with credits. The timeout is the maximum runtime in seconds (default: 3600) — you're only charged for what the job actually uses:
const const posted: {
tx: string;
job: string;
run: string;
credits: {
costUSD: number;
creditsUsed: number;
reservationId: string;
project: string;
};
}
posted = await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.list: (request: NosanaApiListJobRequest, options?: NosanaJobActionOptions) => Promise<NosanaApiListJobResponse>list({
ipfsHash: stringipfsHash,
market: stringmarket: 'CA5pMpqkYFKtme7K31pNB1s62X2SdhEv1nN9RdxKCpuQ',
timeout?: number | undefinedtimeout: 600, // seconds
});
var console: ConsoleThe `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
```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.log('Job address:', const posted: {
tx: string;
job: string;
run: string;
credits: {
costUSD: number;
creditsUsed: number;
reservationId: string;
project: string;
};
}
posted.job: stringjob);
var console: ConsoleThe `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
```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.log('Credits used:', const posted: {
tx: string;
job: string;
run: string;
credits: {
costUSD: number;
creditsUsed: number;
reservationId: string;
project: string;
};
}
posted.credits: {
costUSD: number;
creditsUsed: number;
reservationId: string;
project: string;
}
credits.creditsUsed: numbercreditsUsed);For safe retries, pass an idempotency key — see Idempotency.
Step 6 — Wait for the job and fetch the results
Poll the job until its results land on IPFS, then retrieve them:
let let job: NodeJobjob = await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.get: (request: NosanaApiGetJobByAddressRequest) => Promise<NodeJob>get(const posted: {
job: string;
}
posted.job: stringjob);
// When the job finishes, its results are pinned to IPFS
while (!let job: NodeJobjob.ipfsResult: string | nullipfsResult) {
var console: ConsoleThe `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
```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.log('Waiting… current state:', let job: NodeJobjob.state: numberstate);
await new var Promise: PromiseConstructor
new <unknown>(executor: (resolve: (value: unknown) => void, reject: (reason?: any) => void) => void) => Promise<unknown>
Creates a new Promise.Promise((resolve: (value: unknown) => voidresolve) => function setTimeout(callback: (_: void) => void, delay?: number): NodeJS.Timeout (+2 overloads)[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/setTimeout)setTimeout(resolve: (value: unknown) => voidresolve, 10_000));
let job: NodeJobjob = await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.get: (request: NosanaApiGetJobByAddressRequest) => Promise<NodeJob>get(const posted: {
job: string;
}
posted.job: stringjob);
}
const const results: unknownresults = await const client: NosanaClientclient.NosanaClient.ipfs: NosanaIpfsClientipfs.retrieve: <unknown>(hash: string | Array<number>) => Promise<unknown>retrieve(let job: NodeJobjob.ipfsResult: stringipfsResult);
var console: ConsoleThe `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
```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.log('Results:', var JSON: JSONAn intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.JSON.JSON.stringify(value: any, replacer?: (number | string)[] | null, space?: string | number): string (+1 overload)Converts a JavaScript value to a JavaScript Object Notation (JSON) string.stringify(const results: unknownresults, null, 2));Step 7 — Extend or stop (optional)
While the job is running you can give it more time, or stop it early — the unused credits are refunded:
// Add 10 more minutes
await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.extend: (request: NosanaApiExtendJobRequest, options?: NosanaJobActionOptions) => Promise<NosanaApiExtendJobResponse>extend({ address: stringaddress: const posted: {
job: string;
}
posted.job: stringjob, seconds: string | numberseconds: 600 });
// Or stop it early (remaining credits are refunded)
await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.stop: (request: NosanaApiStopJobRequest, options?: NosanaJobActionOptions) => Promise<NosanaApiStopJobResponse>stop(const posted: {
job: string;
}
posted.job: stringjob);Complete script
Everything above as one runnable script:
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, const validateJobDefinition: (input: unknown) => IValidation<JobDefinitionWithRule>validateJobDefinition } 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 },
});
// 1. Validate the job definition
const const validation: IValidation<JobDefinitionWithRule>validation = function validateJobDefinition(input: unknown): IValidation<JobDefinitionWithRule>validateJobDefinition({
version: stringversion: '0.1',
type: stringtype: 'container',
meta: {
trigger: string;
}
meta: { trigger: stringtrigger: 'api' },
ops: {
type: string;
id: string;
args: {
cmd: string;
image: string;
};
}[]
ops: [
{
type: stringtype: 'container/run',
id: stringid: 'hello-world',
args: {
cmd: string;
image: string;
}
args: {
cmd: stringcmd: 'echo hello world',
image: stringimage: 'ubuntu',
},
},
],
});
if (!const validation: IValidation<JobDefinitionWithRule>validation.success: booleanIndicates validation failure
Indicates validation successsuccess) {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error(
const validation: IValidation.IFailurevalidation.IValidation<T = unknown>.IFailure.errors: IValidation.IError[]Array of detailed validation errorserrors.Array<IValidation<T = unknown>.IError>.map<string>(callbackfn: (value: IValidation<T = unknown>.IError, index: number, array: IValidation.IError[]) => string, thisArg?: any): string[]Calls a defined callback function on each element of an array, and returns an array that contains the results.map((e: IValidation.IErrore) => `${e: IValidation.IErrore.IValidation<T = unknown>.IError.path: stringThe path to the property that failed validation
Dot-notation path using $input prefix indicating the exact location of
the validation failure within the input object structure. Examples
include "$input.member.age", "$input.categories[0]",
"$input.user.profile.email"path}: expected ${e: IValidation.IErrore.IValidation<T = unknown>.IError.expected: stringThe expected type name or type expression
Technical type specification that describes what type was expected at
this path. This follows TypeScript-like syntax with embedded constraint
information, such as "string", "number & Type<'uint32'>",
"Array<string>", "string & Format<'uuid'> & MinLength<8>", etc.expected}`).Array<string>.join(separator?: string): stringAdds all the elements of an array into a string, separated by the specified separator string.join('\n'),
);
}
// 2. Pin it to IPFS
const const ipfsHash: stringipfsHash = await const client: NosanaClientclient.NosanaClient.ipfs: NosanaIpfsClientipfs.pin: (data: object) => Promise<string>pin(const validation: IValidation.ISuccess<JobDefinitionWithRule>validation.IValidation<T = unknown>.ISuccess<JobDefinitionWithRule>.data: JobDefinitionWithRuleThe validated data of type Tdata);
// 3. Post the job with credits
const const posted: {
tx: string;
job: string;
run: string;
credits: {
costUSD: number;
creditsUsed: number;
reservationId: string;
project: string;
};
}
posted = await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.list: (request: NosanaApiListJobRequest, options?: NosanaJobActionOptions) => Promise<NosanaApiListJobResponse>list({
ipfsHash: stringipfsHash,
market: stringmarket: 'CA5pMpqkYFKtme7K31pNB1s62X2SdhEv1nN9RdxKCpuQ',
timeout?: number | undefinedtimeout: 600, // seconds
});
var console: ConsoleThe `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
```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.log('Job posted:', const posted: {
tx: string;
job: string;
run: string;
credits: {
costUSD: number;
creditsUsed: number;
reservationId: string;
project: string;
};
}
posted.job: stringjob);
// 4. Wait for the results
let let job: NodeJobjob = await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.get: (request: NosanaApiGetJobByAddressRequest) => Promise<NodeJob>get(const posted: {
tx: string;
job: string;
run: string;
credits: {
costUSD: number;
creditsUsed: number;
reservationId: string;
project: string;
};
}
posted.job: stringjob);
while (!let job: NodeJobjob.ipfsResult: string | nullipfsResult) {
await new var Promise: PromiseConstructor
new <unknown>(executor: (resolve: (value: unknown) => void, reject: (reason?: any) => void) => void) => Promise<unknown>
Creates a new Promise.Promise((resolve: (value: unknown) => voidresolve) => function setTimeout(callback: (_: void) => void, delay?: number): NodeJS.Timeout (+2 overloads)[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/setTimeout)setTimeout(resolve: (value: unknown) => voidresolve, 10_000));
let job: NodeJobjob = await const client: NosanaClientclient.NosanaClient.api: NosanaApiClientapi.jobs: NosanaJobsApijobs.get: (request: NosanaApiGetJobByAddressRequest) => Promise<NodeJob>get(const posted: {
tx: string;
job: string;
run: string;
credits: {
costUSD: number;
creditsUsed: number;
reservationId: string;
project: string;
};
}
posted.job: stringjob);
}
// 5. Fetch and print the results
const const results: unknownresults = await const client: NosanaClientclient.NosanaClient.ipfs: NosanaIpfsClientipfs.retrieve: <unknown>(hash: string | Array<number>) => Promise<unknown>retrieve(let job: NodeJobjob.ipfsResult: stringipfsResult);
var console: ConsoleThe `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
```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.log(var JSON: JSONAn intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.JSON.JSON.stringify(value: any, replacer?: (number | string)[] | null, space?: string | number): string (+1 overload)Converts a JavaScript value to a JavaScript Object Notation (JSON) string.stringify(const results: unknownresults, null, 2));Next steps
- Run many instances with lifecycle management — jobs are single execution units; for replicas, revisions, and scheduling use Deployments
- Post jobs in bulk — see Batch Operations
- Make retries safe — see Idempotency
- Explore every endpoint — see the API Reference overview