Open Beta Archipelag.io is in open beta until June 2026. All credits and earnings are virtual. Read the announcement →

JavaScript SDK

Build web applications with the Archipelag.io JavaScript SDK

JavaScript SDK

The official JavaScript/TypeScript SDK for Archipelag.io. Works in Node.js and browsers.

Installation

{% tab(name="npm") %} ```bash npm install @archipelag/sdk ```
```bash yarn add @archipelag/sdk ```
```bash pnpm add @archipelag/sdk ```
{% end %}

For React applications, also install the React hooks package:

npm install @archipelag/react

Quick Start

import { Archipelag } from '@archipelag/sdk';

const client = new Archipelag({ apiKey: 'ak_xxx' });

// Simple chat
const result = await client.chat('What is the capital of France?');
console.log(result.content);

// Streaming chat
await client.chatStream('Tell me a story', {
  onToken: (token) => process.stdout.write(token),
  onDone: (usage) => console.log(`\nTokens: ${usage.totalTokens}`),
});

// Image generation
const image = await client.generateImage('a sunset over mountains', {
  width: 1024,
  height: 1024,
});

Configuration

const client = new Archipelag({
  apiKey: 'ak_xxx',                    // Required
  baseUrl: 'https://api.archipelag.io', // Optional
  timeout: 60000,                       // Optional, milliseconds
});

Chat API

Simple Chat

const result = await client.chat('Hello!', {
  systemPrompt: 'You are a helpful assistant',
  maxTokens: 500,
  temperature: 0.7,
});

console.log(result.content);       // Response text
console.log(result.usage.totalTokens); // Token count

Streaming Chat

await client.chatStream('Explain quantum physics', {
  onToken: (token) => {
    process.stdout.write(token);
  },
  onProgress: (step, total) => {
    console.log(`Progress: ${step}/${total}`);
  },
  onError: (error) => {
    console.error('Error:', error);
  },
  onDone: (usage) => {
    console.log(`\nTotal tokens: ${usage.totalTokens}`);
  },
});

Image Generation

const image = await client.generateImage('a cat wearing sunglasses', {
  negativePrompt: 'blurry, low quality',
  width: 1024,
  height: 1024,
  steps: 30,
  guidanceScale: 7.5,
  seed: 42,  // For reproducibility
});

// Display image
const dataUrl = `data:image/${image.imageFormat};base64,${image.imageData}`;

Job Management

For more control, use the low-level job API:

// Create a job
const job = await client.createJob('llm-chat', {
  prompt: 'Hello',
  max_tokens: 100,
});

// Check status
const status = await client.getJob(job.id);
console.log(status.status); // 'pending', 'running', 'completed', etc.

// Wait for completion
const completed = await client.waitForJob(job.id);

// Stream job output
for await (const event of client.streamJob(job.id)) {
  if (event.type === 'token') {
    console.log(event.content);
  }
}

// Cancel a job
await client.cancelJob(job.id);

Batch Operations

Process multiple jobs efficiently:

const jobs = await client.batch([
  { workload: 'llm-chat', input: { prompt: 'Hello' } },
  { workload: 'llm-chat', input: { prompt: 'Hi there' } },
  { workload: 'llm-chat', input: { prompt: 'Greetings' } },
]);

const results = await client.waitAll(jobs);

React Integration

Setup Provider

import { ArchipelagProvider } from '@archipelag/react';

function App() {
  return (
    <ArchipelagProvider apiKey="ak_xxx">
      <YourApp />
    </ArchipelagProvider>
  );
}

useChat Hook

import { useChat } from '@archipelag/react';

function ChatComponent() {
  const { messages, send, isLoading, streamingContent } = useChat({
    systemPrompt: 'You are a helpful assistant',
    onFinish: (content, usage) => {
      console.log(`Done: ${usage.totalTokens} tokens`);
    },
  });

  return (
    <div>
      {messages.map((msg, i) => (
        <div key={i}>
          <strong>{msg.role}:</strong> {msg.content}
        </div>
      ))}
      {isLoading && <div>Assistant: {streamingContent}</div>}
      <input
        onKeyPress={(e) => {
          if (e.key === 'Enter' && !isLoading) {
            send(e.currentTarget.value);
            e.currentTarget.value = '';
          }
        }}
      />
    </div>
  );
}

useImage Hook

import { useImage } from '@archipelag/react';

function ImageGenerator() {
  const { generate, isLoading, progress, image } = useImage({
    width: 1024,
    height: 1024,
  });

  return (
    <div>
      <button onClick={() => generate('a beautiful landscape')}>
        Generate
      </button>
      {isLoading && <progress value={progress} max={100} />}
      {image && (
        <img src={`data:image/png;base64,${image.imageData}`} />
      )}
    </div>
  );
}

Error Handling

import {
  ArchipelagError,
  AuthenticationError,
  RateLimitError,
  InsufficientCreditsError,
} from '@archipelag/sdk';

try {
  await client.chat('Hello');
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof InsufficientCreditsError) {
    console.error('Not enough credits');
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limited. Retry after ${error.retryAfter}ms`);
  } else if (error instanceof ArchipelagError) {
    console.error(`API error: ${error.message}`);
  }
}

TypeScript Types

The SDK is fully typed. Key types:

interface ChatResult {
  content: string;
  jobId: string;
  usage: Usage;
  finishReason?: string;
}

interface ImageResult {
  imageData: string;      // Base64 PNG
  imageFormat: string;
  width: number;
  height: number;
  seed?: number;
  jobId: string;
  usage: Usage;
}

interface Usage {
  promptTokens?: number;
  completionTokens?: number;
  totalTokens?: number;
  creditsUsed: number;
}

Resources