---
title: SDK client
description: >-
  createIvyClient factory, IvyClientConfig, authentication providers, and the
  IvyClient class
---

The `IvyClient` is the root object you construct once and reuse for everything else in the SDK — it holds your authentication (API key or JWT), handles HTTP requests and retries, and exposes the domain managers (`jobs`, `artifacts`, `websocket`) that the sibling reference pages document. Reach for this page when you're setting up the client, choosing an auth mode, or configuring timeouts and retries; once you have an instance, the [Jobs](/docs/api/sdk-jobs) reference covers the calls you'll make most.

## SDK Client Reference

> **Planned specification.** `@ivybiosciences/sdk` is not released, and there is no package to install. This page describes the SDK's planned interface. To call the platform today, use the [REST API](/docs/api/rest-jobs), the [ivybloom CLI](/docs/cli), or the [MCP server](/docs/cli/mcp).

The `IvyClient` is the primary entry point for the SDK. It orchestrates authentication, HTTP communication, WebSocket connections, and provides access to domain-specific managers.

## `createIvyClient(config)`

The recommended way to create an IvyClient instance. Validates that exactly one auth method is provided.

```ts
function createIvyClient(config: IvyClientConfig): IvyClient
```

**Parameters:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `config` | `IvyClientConfig` | Yes | Client configuration (see below) |

**Throws:** `Error` if neither `apiKey` nor `getToken` is provided.

**Returns:** A fully configured `IvyClient` instance.

### Examples

**TypeScript**

```ts
// API Key (server-side)
const ivy = createIvyClient({ apiKey: "ivy_your_key_here" })

// JWT (browser with Clerk)
const ivy = createIvyClient({
  getToken: () => clerk.session!.getToken({ template: "ivy_api" }),
  timeout: 60_000,
})

// Custom endpoint
const ivy = createIvyClient({
  apiKey: "ivy_test_key",
  baseUrl: "http://localhost:8000/api/v1",
  retries: 5,
})
```

**Python**

```python
import requests

# Configure a reusable session with auth
session = requests.Session()
session.headers.update({
    "Authorization": "Bearer ivy_your_key_here",
    "Content-Type": "application/json",
})

BASE_URL = "https://www.ivybiosciences.com"

# All subsequent calls use the authenticated session
response = session.get(f"{BASE_URL}/api/v1/jobs", timeout=30)
jobs = response.json()
```

**React**

```tsx
import { IvyProvider, useIvyClient } from "@ivybiosciences/sdk/react"

// Wrap your app tree with IvyProvider for auth context
function App() {
  return (
    `<IvyProvider getToken={() => clerk.session!.getToken({ template: "ivy_api" })} timeout={60_000} > <Dashboard /> </IvyProvider>`
  )
}

// Access the client anywhere in the tree
function Dashboard() {
  const ivy = useIvyClient()

  // ivy.jobs, ivy.artifacts, ivy.websocket are all available
  return `<JobsList client={ivy} />`
}
```

---

## `IvyClientConfig`

Configuration interface for creating an IvyClient.

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `baseUrl` | `string` | `DEFAULT_BASE_URL` (`https://www.ivybiosciences.com/api/v1`) | API base URL including `/api/v1` path prefix |
| `apiKey` | `string` | — | API key with `ivy_` prefix. Mutually exclusive with `getToken` |
| `getToken` | `() => Promise<string \| null>` | — | Async JWT provider. Mutually exclusive with `apiKey` |
| `timeout` | `number` | `30000` | HTTP request timeout in milliseconds |
| `retries` | `number` | `3` | Max retry attempts for transient failures (429, 5xx) |
| `onError` | `(error: Error) => void` | — | Global error callback for unhandled SDK errors |

---

## `IvyClient`

### Properties

| Property | Type | Description |
|----------|------|-------------|
| `jobs` | `JobManager` | Job submission, status polling, and lifecycle management |
| `artifacts` | `ArtifactManager` | Artifact download from presigned S3 URLs |
| `websocket` | `IvyWebSocket` | Raw WebSocket access for custom real-time subscriptions |

### Constructor

```ts
new IvyClient(config: IvyClientConfig)
```

Prefer using `createIvyClient()` which adds validation.

---

## Calling without a key

Every client on this page needs an API key or a Clerk JWT. To try the platform without a key, skip the SDK and send the keyless orchestrate request in [Guest curl](/docs/api#guest-curl); its limits are stated there.

---

## Authentication Flow

 C["AuthProvider<br/>.getHeaders()"]
    B["JwtAuth<br/>(Clerk JWT)"] --> C
    C --> D["HTTP Middleware<br/>(per-request)"]
    D --> E["IvyAI API"]`}
  caption="Both auth types feed the AuthProvider, whose getHeaders() runs in the HTTP middleware before every request to the IvyAI API."
/>

The auth provider's `getHeaders()` is called before every request, ensuring tokens are always fresh.
