> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Async Jobs

> Server-based asynchronous job execution in TypeScript

Server-based job execution with persistence, webhooks, and streaming — ideal for production deployments.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    Client([Client]) --> API[Jobs API]
    API --> Job[Async Job]
    Job --> Result([Result])

    classDef agent fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef tool fill:#189AB4,stroke:#7C90A0,color:#fff

    class Job agent
    class API,Client,Result tool
    classDef agent fill:#8B0000,color:#fff
    classDef tool fill:#189AB4,color:#fff
```

## Quick Start

**1. Simple Usage**

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
npm install praisonai-ts
```

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { recipe } from 'praisonai-ts';

const job = await recipe.submitJob('my-recipe', {
  input: { query: 'What is AI?' },
  wait: true,
});
console.log(job.status);
```

**2. With Configuration**

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
const job = await recipe.submitJob('my-recipe', {
  input: { query: 'What is AI?' },
  webhookUrl: 'https://example.com/webhook',
  timeoutSec: 3600,
});
```

***

## Basic Usage

### Submitting a Job

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { recipe } from 'praisonai-ts';

// Submit recipe as async job
const job = await recipe.submitJob('my-recipe', {
  input: { query: 'What is AI?' },
  config: { maxTokens: 1000 },
  sessionId: 'session_123',
  timeoutSec: 3600,
  webhookUrl: 'https://example.com/webhook',
  idempotencyKey: 'unique-key-123',
  apiUrl: 'http://127.0.0.1:8005',
});

console.log(`Job ID: ${job.jobId}`);
console.log(`Status: ${job.status}`);
```

### JobHandle Interface

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
interface JobHandle {
  jobId: string;
  recipeName: string;
  status: JobStatus;
  
  getStatus(): Promise<JobStatus>;
  getResult(): Promise<any>;
  cancel(): Promise<boolean>;
  wait(pollInterval?: number, timeout?: number): Promise<any>;
}

type JobStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled';
```

### Waiting for Completion

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
// Submit and wait
const job = await recipe.submitJob('my-recipe', {
  input: 'test',
  wait: true,
});

// Or wait after submission
const job = await recipe.submitJob('my-recipe', { input: 'test' });
const result = await job.wait(5, 300); // poll every 5s, timeout 300s
console.log(`Result: ${result}`);
```

## Using the Jobs API Client

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { JobsClient, JobSubmitRequest } from 'praisonai-ts';

const client = new JobsClient('http://127.0.0.1:8005');

// Submit job
const request: JobSubmitRequest = {
  prompt: 'Analyze this data',
  recipeName: 'data-analyzer',
  recipeConfig: { format: 'json' },
  timeout: 3600,
  webhookUrl: 'https://example.com/callback',
};

const job = await client.submit(request);
console.log(`Job ID: ${job.jobId}`);

// Get status
const status = await client.getStatus(job.jobId);

// Get result
const result = await client.getResult(job.jobId);

// Stream progress
for await (const event of client.stream(job.jobId)) {
  console.log(`Progress: ${event.progress}%`);
}
```

## Webhooks

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
const job = await recipe.submitJob('my-recipe', {
  input: 'test',
  webhookUrl: 'https://example.com/webhook',
});
```

Webhook payload:

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "jobId": "run_abc123",
  "status": "succeeded",
  "result": {"output": "..."},
  "completedAt": "2024-01-15T10:30:00Z",
  "durationSeconds": 45.2
}
```

## Idempotency

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
// Same key = same job (no duplicate)
const job1 = await recipe.submitJob('my-recipe', {
  idempotencyKey: 'order-123',
});
const job2 = await recipe.submitJob('my-recipe', {
  idempotencyKey: 'order-123',
});

console.log(job1.jobId === job2.jobId); // true
```

## Configuration

### TEMPLATE.yaml Runtime Block

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
runtime:
  job:
    enabled: true
    timeout_sec: 3600
    webhook_url: "${WEBHOOK_URL}"
    idempotency_scope: "session"
```

## Error Handling

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { recipe, JobError } from 'praisonai-ts';

try {
  const job = await recipe.submitJob('my-recipe', { input: 'test' });
  const result = await job.wait(5, 60);
  
  if (result.status === 'failed') {
    console.error(`Job failed: ${result.error}`);
  }
} catch (error) {
  if (error instanceof JobError) {
    console.error(`Job error: ${error.message}`);
  }
}
```

## Related

> [card] [Async Jobs CLI](https://praison.ai/docs/js/async-jobs-cli.md)
>
> CLI commands

> [card] [Background Tasks](https://praison.ai/docs/js/background-tasks.md)
>
> In-process execution

> [card] [Scheduler](https://praison.ai/docs/js/scheduler.md)
>
> Periodic scheduling


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.