# JavaScript SDK

> Official JavaScript/TypeScript SDK for PromptRails with full type safety, ESM and CJS support, and automatic retries.

Source: https://0.0.0.0:8080/docs/javascript-sdk

The official JavaScript/TypeScript SDK for PromptRails provides a fully typed client for interacting with the PromptRails API from Node.js, Deno, or browser environments.

<div style={{ display: 'flex', gap: '0.75rem', marginBottom: '0.5rem' }}>
  <a href="https://github.com/promptrails/javascript-sdk" target="_blank" rel="noopener noreferrer">
    GitHub
  </a>
  <span style={{ color: 'var(--color-muted-foreground)' }}>·</span>
  <a
    href="https://www.npmjs.com/package/@promptrails/sdk"
    target="_blank"
    rel="noopener noreferrer"
  >
    npm
  </a>
</div>

## Installation

```bash
npm install @promptrails/sdk
```

Or with other package managers:

```bash
yarn add @promptrails/sdk
pnpm add @promptrails/sdk
```

Supports both ESM and CommonJS module formats.

Current release: **v0.3.1** — streaming chat & executions, typed
`AgentConfig` union, `VERSION` export. See the
[changelog](https://github.com/promptrails/javascript-sdk/releases).

## Client Initialization

```typescript
import { PromptRails } from '@promptrails/sdk'

const client = new PromptRails({
  apiKey: 'your-api-key',
  baseUrl: 'https://api.promptrails.ai', // default
  timeout: 30000, // milliseconds, default
  maxRetries: 3, // default
})
```

## Configuration

| Parameter    | Type   | Default                      | Description                     |
| ------------ | ------ | ---------------------------- | ------------------------------- |
| `apiKey`     | string | Required                     | PromptRails API key             |
| `baseUrl`    | string | `https://api.promptrails.ai` | API base URL                    |
| `timeout`    | number | 30000                        | Request timeout in milliseconds |
| `maxRetries` | number | 3                            | Maximum retry attempts          |

## Available Resources

| Resource         | Property                 | Description                             |
| ---------------- | ------------------------ | --------------------------------------- |
| Agents           | `client.agents`          | Agent CRUD, versioning, execution       |
| Prompts          | `client.prompts`         | Prompt CRUD, versioning, execution      |
| Executions       | `client.executions`      | Execution listing and details           |
| Credentials      | `client.credentials`     | Credential management                   |
| Data Sources     | `client.dataSources`     | Data source CRUD, versioning, execution |
| Chat             | `client.chat`            | Send messages to chat sessions          |
| Sessions         | `client.sessions`        | Chat session management                 |
| Memories         | `client.memories`        | Agent memory CRUD and search            |
| Traces           | `client.traces`          | Trace listing and filtering             |
| Costs            | `client.costs`           | Cost analysis and summaries             |
| MCP Tools        | `client.mcpTools`        | MCP tool management                     |
| MCP Templates    | `client.mcpTemplates`    | MCP template browsing                   |
| Guardrails       | `client.guardrails`      | Guardrail configuration                 |
| Approvals        | `client.approvals`       | Approval request management             |
| Scores           | `client.scores`          | Scoring and evaluation                  |
| Templates        | `client.templates`       | Flow templates                          |
| Dashboard        | `client.dashboard`       | Agent UI deployments                    |
| Sessions         | `client.sessions`        | Session management                      |
| A2A              | `client.a2a`             | Agent-to-Agent protocol                 |
| LLM Models       | `client.llmModels`       | Available LLM models                    |
| Webhook Triggers | `client.webhookTriggers` | Webhook trigger management              |

## Common Operations

### Execute an Agent

```typescript
const result = await client.agents.execute('agent-id', {
  input: { message: 'Hello, world!' },
  metadata: { source: 'api' },
})

console.log(result.data.output)
console.log(`Cost: $${result.data.cost.toFixed(6)}`)
```

### List Agents

```typescript
const agents = await client.agents.list({ page: 1, limit: 20 })

for (const agent of agents.data) {
  console.log(`${agent.name} (${agent.type})`)
}
```

### Create a Prompt

```typescript
const prompt = await client.prompts.create({
  name: 'Summarizer',
  description: 'Summarizes text',
})

const version = await client.prompts.createVersion(prompt.data.id, {
  systemPrompt: 'You are a concise summarizer.',
  userPrompt: 'Summarize: {{ text }}',
  temperature: 0.5,
  message: 'Initial version',
})
```

### Chat

```typescript
const session = await client.chat.createSession({
  agentId: 'agent-id',
})

const response = await client.chat.sendMessage(session.id, {
  content: 'What is PromptRails?',
})

console.log(response.content)
```

### Stream a Chat Turn

`sendMessageStream` posts a user message and yields typed
Server-Sent Events on the same HTTP connection — useful for showing the
agent's reasoning, tool calls, and token-by-token deltas in the UI.

```typescript
const session = await client.chat.createSession({ agentId: 'agent-id' })

const controller = new AbortController()

for await (const event of client.chat.sendMessageStream(
  session.id,
  { content: 'What is PromptRails?' },
  { signal: controller.signal },
)) {
  switch (event.type) {
    case 'execution':
      console.log('execution_id:', event.executionId)
      break
    case 'thinking':
      console.log('[thinking]', event.content)
      break
    case 'tool_start':
      console.log('[tool_start]', event.name)
      break
    case 'tool_end':
      console.log('[tool_end]', event.name, event.summary)
      break
    case 'content':
      process.stdout.write(event.content)
      break
    case 'done':
      console.log('\n[done]', event.tokenUsage)
      break
    case 'error':
      console.error('[error]', event.message)
      break
  }
}
```

Cancel an in-flight stream with `controller.abort()`. All event shapes are
exported via the `StreamEvent` discriminated union:

```typescript
import type { StreamEvent } from '@promptrails/sdk'
```

### Stream an Existing Execution

When an execution was started outside a chat (e.g. `client.agents.execute`),
subscribe to its live event stream with `client.executions.stream`:

```typescript
for await (const event of client.executions.stream(executionId)) {
  if (event.type === 'content') process.stdout.write(event.content)
  if (event.type === 'done') break
}
```

### Search Memories

```typescript
const results = await client.memories.search({
  agentId: 'agent-id',
  query: 'refund policy',
  limit: 5,
})
```

### Create a Score

```typescript
await client.scores.create({
  traceId: 'trace-id',
  name: 'quality',
  dataType: 'numeric',
  value: 4.5,
  source: 'manual',
})
```

### Approve an Execution

```typescript
await client.approvals.decide('approval-id', {
  decision: 'approved',
  reason: 'Looks good',
})
```

## Typed Agent Config

`createVersion` takes a typed `AgentConfig` — a discriminated union by
agent type. The SDK injects the `type` discriminator automatically, so
renames in the backend schema (e.g. `prompt_version_id` → `prompt_id`)
surface as TypeScript errors instead of silent runtime failures.

```typescript
import {
  SimpleAgentConfig,
  ChainAgentConfig,
  MultiAgentConfig,
  WorkflowAgentConfig,
  CompositeAgentConfig,
  PromptLink,
} from '@promptrails/sdk'

// Simple agent — one prompt per execution
const simple: SimpleAgentConfig = {
  type: 'simple',
  prompt_id: 'prompt-id',
  approval_required: false,
}

// Chain agent — prompts run sequentially, output of step N feeds step N+1
const chain: ChainAgentConfig = {
  type: 'chain',
  prompt_ids: [
    { prompt_id: 'p1', role: 'step1', sort_order: 0 },
    { prompt_id: 'p2', role: 'step2', sort_order: 1 },
  ],
}

await client.agents.createVersion('agent-id', {
  version: '1.0.0',
  config: simple,
  set_current: true,
})
```

Available variants: `SimpleAgentConfig`, `ChainAgentConfig`,
`MultiAgentConfig`, `WorkflowAgentConfig`, `CompositeAgentConfig`. Chain
and multi-agent configs use `PromptLink[]`; workflow uses `WorkflowNode[]`;
composite uses `CompositeStep[]`. See
[Agent Versioning](/docs/agent-versioning) for the per-type field
reference.

## SDK Version

```typescript
import { VERSION } from '@promptrails/sdk'
console.log(VERSION) // "0.3.1"
```

The SDK also sends `User-Agent: promptrails-js/<version>` on every
request (except in browsers, where fetch ignores the header).

## TypeScript Types

The SDK includes full TypeScript type definitions. All request and response types are exported:

```typescript
import type {
  Agent,
  Prompt,
  Execution,
  Trace,
  Score,
  Credential,
  ChatSession,
} from '@promptrails/sdk'
```

## Error Handling

The SDK throws typed errors for different HTTP status codes:

```typescript
import {
  PromptRailsError,
  ValidationError,
  UnauthorizedError,
  ForbiddenError,
  NotFoundError,
  RateLimitError,
  ServerError,
} from '@promptrails/sdk'

try {
  const result = await client.agents.execute('invalid-id', { input: {} })
} catch (error) {
  if (error instanceof NotFoundError) {
    console.log(`Agent not found: ${error.message}`)
  } else if (error instanceof ValidationError) {
    console.log(`Invalid input: ${error.message}`)
    console.log(`Details:`, error.details)
  } else if (error instanceof RateLimitError) {
    console.log(`Rate limited: ${error.message}`)
  } else if (error instanceof UnauthorizedError) {
    console.log(`Invalid API key: ${error.message}`)
  } else if (error instanceof ForbiddenError) {
    console.log(`Insufficient permissions: ${error.message}`)
  } else if (error instanceof ServerError) {
    console.log(`Server error (${error.statusCode}): ${error.message}`)
  } else if (error instanceof PromptRailsError) {
    console.log(`Unexpected error: ${error.message}`)
  }
}
```

### Error Classes

| Exception           | HTTP Status | Description                |
| ------------------- | ----------- | -------------------------- |
| `ValidationError`   | 400         | Invalid request parameters |
| `UnauthorizedError` | 401         | Invalid or missing API key |
| `ForbiddenError`    | 403         | Insufficient permissions   |
| `NotFoundError`     | 404         | Resource not found         |
| `RateLimitError`    | 429         | Rate limit exceeded        |
| `ServerError`       | 5xx         | Server-side error          |
| `PromptRailsError`  | Any         | Base class for all errors  |

All error instances include:

- `message` -- Error description
- `statusCode` -- HTTP status code
- `code` -- Optional error code
- `details` -- Optional additional details object

## ESM and CJS Support

The SDK ships with both ESM and CommonJS builds:

```typescript
// ESM
import { PromptRails } from '@promptrails/sdk'

// CommonJS
const { PromptRails } = require('@promptrails/sdk')
```

## Pagination

```typescript
// Page-based pagination
const page1 = await client.agents.list({ page: 1, limit: 20 })
const page2 = await client.agents.list({ page: 2, limit: 20 })
```

## Related Topics

- [Examples](https://github.com/promptrails/examples/tree/main/javascript) -- Ready-to-run code examples
- [Quickstart](/docs/quickstart) -- Getting started guide
- [Python SDK](/docs/python-sdk) -- Python alternative
- [Go SDK](/docs/go-sdk) -- Go alternative
- [API Keys and Scopes](/docs/api-keys-and-scopes) -- API key management
- [REST API Reference](/docs/rest-api-reference) -- Underlying REST API
