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

# Intro

> Use the oleander API from TypeScript: query the lake, inspect Spark clusters, and submit Spark jobs.

The [`@oleanderhq/sdk`](https://www.npmjs.com/package/@oleanderhq/sdk) package provides a typed client for the oleander API. It covers lake queries, Spark job management, Spark SQL, Polars runs, catalog introspection, environment variables, Spark cluster lookup, and run polling.

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @oleanderhq/sdk
  ```

  ```bash yarn theme={null}
  yarn add @oleanderhq/sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @oleanderhq/sdk
  ```
</CodeGroup>

## Authentication

Create an API key in your [oleander settings](https://oleander.dev/app/settings), or run `oleander configure` if you use the CLI.

You can pass the key directly or, in Node.js, set the `OLEANDER_API_KEY` environment variable.

```ts theme={null}
import { Oleander } from "@oleanderhq/sdk";

// Option 1: pass the key directly
const client = new Oleander({ apiKey: "your-api-key" });

// Option 2: reads OLEANDER_API_KEY from the environment
const client = new Oleander();
```

## Quick start

```ts theme={null}
import { Oleander } from "@oleanderhq/sdk";

const client = new Oleander();

// Query the lake and iterate over results
const result = await client.query(
  "SELECT * FROM oleander.default.flowers LIMIT 10",
);
for (const row of result.results?.rows ?? []) {
  const [sepalLength, sepalWidth] = row as [number, number];
  // process each row ...
}

// List available Spark job artifacts
const { artifacts } = await client.listSparkJobs();

// Submit a Spark job and wait for it to finish
const { runId, state } = await client.submitSparkJobAndWait({
  namespace: "my-namespace",
  name: "daily-etl",
  entrypoint: "etl_pipeline.py",
});

if (state !== "COMPLETE") {
  throw new Error(`Run ${runId} ended with state: ${state}`);
}
```

## Working with clusters

Use `cluster: "oleander"` for oleander-managed Spark or pass the name of a registered cluster when submitting a job.

```ts theme={null}
const cluster = await client.getSparkCluster({ name: "emr-prod" });
console.log(cluster.type, cluster.properties);
```

## Constructor options

| Parameter | Type     | Default                    | Description                                   |
| --------- | -------- | -------------------------- | --------------------------------------------- |
| `apiKey`  | `string` | `OLEANDER_API_KEY` env var | Your oleander API key                         |
| `baseUrl` | `string` | `https://oleander.dev`     | API base URL. Override for local development. |

## Errors

The SDK throws structured HTTP errors for non-2xx responses.

```ts theme={null}
import { OleanderHttpError, RunNotFoundError } from "@oleanderhq/sdk";

try {
  await client.getRun("run-id");
} catch (error) {
  if (error instanceof RunNotFoundError) {
    console.log("Run is not visible yet:", error.runId);
  } else if (error instanceof OleanderHttpError) {
    console.log(error.status, error.path, error.apiError ?? error.apiDetails);
  } else {
    throw error;
  }
}
```
