Claude
Skills
Sign in
Back

openai-assistants

Included with Lifetime
$97 forever

Complete guide for OpenAI's Assistants API v2: stateful conversational AI with built-in tools (Code Interpreter, File Search, Function Calling), vector stores for RAG (up to 10,000 files), thread/run lifecycle management, and streaming patterns. Both Node.js SDK and fetch approaches. ⚠️ DEPRECATION NOTICE: OpenAI plans to sunset Assistants API in H1 2026 in favor of Responses API. This skill remains valuable for existing apps and migration planning. Use when: building stateful chatbots with OpenAI, implementing RAG with vector stores, executing Python code with Code Interpreter, using file search for document Q&A, managing conversation threads, streaming assistant responses, or encountering errors like "thread already has active run", vector store indexing delays, run polling timeouts, or file upload issues. Keywords: openai assistants, assistants api, openai threads, openai runs, code interpreter assistant, file search openai, vector store openai, openai rag, assistant streaming, thread persistence, stateful chatbot, thread already has active run, run status polling, vector store error

Backend & APIs

What this skill does


# OpenAI Assistants API v2

**Status**: Production Ready (Deprecated H1 2026)
**Package**: [email protected]
**Last Updated**: 2025-10-25
**v1 Deprecated**: December 18, 2024
**v2 Sunset**: H1 2026 (migrate to Responses API)

---

## ⚠️ Important: Deprecation Notice

**OpenAI announced that the Assistants API will be deprecated in favor of the [Responses API](../openai-responses/SKILL.md).**

**Timeline:**
- ✅ **Dec 18, 2024**: Assistants API v1 deprecated
- ⏳ **H1 2026**: Planned sunset of Assistants API v2
- ✅ **Now**: Responses API available (recommended for new projects)

**Should you still use this skill?**
- ✅ **Yes, if**: You have existing Assistants API code (12-18 month migration window)
- ✅ **Yes, if**: You need to maintain legacy applications
- ✅ **Yes, if**: Planning migration from Assistants → Responses
- ❌ **No, if**: Starting a new project (use openai-responses skill instead)

**Migration Path:**
See `references/migration-to-responses.md` for complete migration guide.

---

## Table of Contents

1. [Quick Start](#quick-start)
2. [Core Concepts](#core-concepts)
3. [Assistants](#assistants)
4. [Threads](#threads)
5. [Messages](#messages)
6. [Runs](#runs)
7. [Streaming Runs](#streaming-runs)
8. [Tools](#tools)
   - [Code Interpreter](#code-interpreter)
   - [File Search](#file-search)
   - [Function Calling](#function-calling)
9. [Vector Stores](#vector-stores)
10. [File Uploads](#file-uploads)
11. [Thread Lifecycle Management](#thread-lifecycle-management)
12. [Error Handling](#error-handling)
13. [Production Best Practices](#production-best-practices)
14. [Relationship to Other Skills](#relationship-to-other-skills)

---

## Quick Start

### Installation

```bash
npm install [email protected]
```

### Environment Setup

```bash
export OPENAI_API_KEY="sk-..."
```

### Basic Assistant (Node.js SDK)

```typescript
import OpenAI from 'openai';

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

// 1. Create an assistant
const assistant = await openai.beta.assistants.create({
  name: "Math Tutor",
  instructions: "You are a personal math tutor. Write and run code to answer math questions.",
  tools: [{ type: "code_interpreter" }],
  model: "gpt-4o",
});

// 2. Create a thread
const thread = await openai.beta.threads.create();

// 3. Add a message to the thread
await openai.beta.threads.messages.create(thread.id, {
  role: "user",
  content: "I need to solve the equation `3x + 11 = 14`. Can you help me?",
});

// 4. Create a run
const run = await openai.beta.threads.runs.create(thread.id, {
  assistant_id: assistant.id,
});

// 5. Poll for completion
let runStatus = await openai.beta.threads.runs.retrieve(thread.id, run.id);

while (runStatus.status !== 'completed') {
  await new Promise(resolve => setTimeout(resolve, 1000));
  runStatus = await openai.beta.threads.runs.retrieve(thread.id, run.id);
}

// 6. Retrieve messages
const messages = await openai.beta.threads.messages.list(thread.id);
console.log(messages.data[0].content[0].text.value);
```

### Basic Assistant (Fetch - Cloudflare Workers)

```typescript
// 1. Create assistant
const assistant = await fetch('https://api.openai.com/v1/assistants', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
    'Content-Type': 'application/json',
    'OpenAI-Beta': 'assistants=v2',
  },
  body: JSON.stringify({
    name: "Math Tutor",
    instructions: "You are a helpful math tutor.",
    model: "gpt-4o",
  }),
});

const assistantData = await assistant.json();

// 2. Create thread
const thread = await fetch('https://api.openai.com/v1/threads', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
    'Content-Type': 'application/json',
    'OpenAI-Beta': 'assistants=v2',
  },
});

const threadData = await thread.json();

// 3. Add message and create run
const run = await fetch(`https://api.openai.com/v1/threads/${threadData.id}/runs`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
    'Content-Type': 'application/json',
    'OpenAI-Beta': 'assistants=v2',
  },
  body: JSON.stringify({
    assistant_id: assistantData.id,
    additional_messages: [{
      role: "user",
      content: "What is 3x + 11 = 14?",
    }],
  }),
});

// Poll for completion...
```

---

## Core Concepts

The Assistants API uses four main objects:

### 1. **Assistants**
Configured AI entities with:
- Instructions (system prompt, max 256k characters)
- Model (gpt-4o, gpt-5, etc.)
- Tools (Code Interpreter, File Search, Functions)
- File attachments
- Metadata

### 2. **Threads**
Conversation containers that:
- Store message history
- Persist across runs
- Can have metadata
- Support up to 100,000 messages

### 3. **Messages**
Individual messages in a thread:
- User messages (input)
- Assistant messages (output)
- Can include file attachments
- Support text and image content

### 4. **Runs**
Execution of an assistant on a thread:
- Asynchronous processing
- Multiple states (queued, in_progress, completed, failed, etc.)
- Can stream results
- Handle tool calls automatically

---

## Assistants

### Create an Assistant

```typescript
const assistant = await openai.beta.assistants.create({
  name: "Data Analyst",
  instructions: "You are a data analyst. Use code interpreter to analyze data and create visualizations.",
  model: "gpt-4o",
  tools: [
    { type: "code_interpreter" },
    { type: "file_search" },
  ],
  tool_resources: {
    file_search: {
      vector_store_ids: ["vs_abc123"],
    },
  },
  metadata: {
    department: "analytics",
    version: "1.0",
  },
});
```

**Parameters:**
- `model` (required): Model ID (gpt-4o, gpt-5, gpt-4-turbo)
- `instructions`: System prompt (max 256k characters in v2, was 32k in v1)
- `name`: Assistant name (max 256 characters)
- `description`: Description (max 512 characters)
- `tools`: Array of tools (max 128 tools)
- `tool_resources`: Resources for tools (vector stores, files)
- `temperature`: 0-2 (default 1)
- `top_p`: 0-1 (default 1)
- `response_format`: "auto", "json_object", or JSON schema
- `metadata`: Key-value pairs (max 16 pairs)

### Retrieve an Assistant

```typescript
const assistant = await openai.beta.assistants.retrieve("asst_abc123");
```

### Update an Assistant

```typescript
const updatedAssistant = await openai.beta.assistants.update("asst_abc123", {
  instructions: "Updated instructions",
  tools: [{ type: "code_interpreter" }, { type: "file_search" }],
});
```

### Delete an Assistant

```typescript
await openai.beta.assistants.del("asst_abc123");
```

### List Assistants

```typescript
const assistants = await openai.beta.assistants.list({
  limit: 20,
  order: "desc",
});
```

---

## Threads

Threads store conversation history and persist across runs.

### Create a Thread

```typescript
// Empty thread
const thread = await openai.beta.threads.create();

// Thread with initial messages
const thread = await openai.beta.threads.create({
  messages: [
    {
      role: "user",
      content: "Hello! I need help with Python.",
      metadata: { source: "web" },
    },
  ],
  metadata: {
    user_id: "user_123",
    session_id: "session_456",
  },
});
```

### Retrieve a Thread

```typescript
const thread = await openai.beta.threads.retrieve("thread_abc123");
```

### Update Thread Metadata

```typescript
const thread = await openai.beta.threads.update("thread_abc123", {
  metadata: {
    user_id: "user_123",
    last_active: new Date().toISOString(),
  },
});
```

### Delete a Thread

```typescript
await openai.beta.threads.del("thread_abc123");
```

**⚠️ Warning**: Deleting a thread also deletes all messages and runs. Cannot be undone.

---

## Messages

### Add a Message to a Thread

```typescript
const message = await openai.beta.threads.messages.create("thread_abc123", {
  role: "user",
  content: "Can you analyze this data?",
  attachments: [
    {
      file_id: "file_abc123",
      tools: [{ type: "code_interpreter" }],
    },
  ],
  metad

Related in Backend & APIs