> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.rightbrain.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.rightbrain.ai/_mcp/server.

# TypeScript SDK

> Install the Rightbrain SDK, generate task types, and build a Next.js route and form that keep credentials on the server.

The [`@rightbrain/sdk`](https://www.npmjs.com/package/@rightbrain/sdk) client turns your tasks into typed functions. This walkthrough connects a Next.js form to a task with a `product_name` input and JSON output.

**Before you start:** use Node.js 22+, an existing Next.js App Router project, and a Rightbrain task. The examples use the `@/` import alias; adjust paths to match your app. For other languages, use the [REST API](/docs/api/run-tasks).

## Next.js example

Follow the steps beside the code. Each file is complete: replace `<task-id>` with an ID from your generated types and use that task's input fields.

#### Install the SDK

Run the install command in your app directory. You can also use `pnpm add @rightbrain/sdk` or `yarn add @rightbrain/sdk`.

**`Terminal (line 1)`**

```bash Terminal (line 1)
npm install @rightbrain/sdk
```

#### Sign in and generate task types

Sign in, then select your organization, project, API key and tasks in `init`. The CLI writes credentials to `.env` and generates the `Tasks` type.

The default output is `src/generated/index.ts` when `src` exists, otherwise `generated/index.ts`. Point the route's import at that directory.

Next.js loads `.env` for server code. `DirectTransport` does not load it or read environment variables itself.

**`Terminal (lines 2-3)`**

```bash Terminal (lines 2-3)
npx rightbrain@latest login --url https://app.rightbrain.ai
npx rightbrain@latest init
```

#### Keep credentials on the server

Create a `Client<Tasks>` with `DirectTransport`. Pass the API key as `accessToken`, along with your organization, project and API base URL.

This file runs on the server. Never put the key in a browser bundle or a `NEXT_PUBLIC_` variable. Browser code calls your route below; applications using `PublicTransport` also need their own server proxy.

**`app/api/tasks/product-listing/route.ts (lines 1-11)`**

```typescript app/api/tasks/product-listing/route.ts (lines 1-11)
import type { Tasks } from "@/generated";
import { Client, DirectTransport } from "@rightbrain/sdk";

const client = new Client<Tasks>({
  transport: new DirectTransport({
    baseUrl: "https://app.rightbrain.ai/api/v1",
    accessToken: process.env.RB_API_KEY!,
    orgId: process.env.RB_ORG_ID!,
    projectId: process.env.RB_PROJECT_ID!,
  }),
});
```

#### Run the task from your route

The generated task ID selects a typed runner. Its `inputs` match your task's prompt variables, and `result.response` contains the JSON output.

This sample route assumes your application's authentication and access checks already protect it. Apply those checks before exposing a paid task to users.

**`app/api/tasks/product-listing/route.ts (lines 13-19)`**

```typescript app/api/tasks/product-listing/route.ts (lines 13-19)
export async function POST(request: Request) {
  const body = await request.json();
  const result = await client["<task-id>"].run({
    inputs: { product_name: body.product_name },
  });
  return Response.json(result.response);
}
```

#### Handle loading and failures

The hook sends the form input to your route. A failed HTTP response becomes a visible error, and loading is cleared after either outcome.

**`hooks/useGenerateProductListing.ts (lines 8-24)`**

```typescript hooks/useGenerateProductListing.ts (lines 8-24)
  async function execute(inputs: { product_name: string }) {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch("/api/tasks/product-listing", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(inputs),
      });
      if (!res.ok) throw new Error(`Request failed (HTTP ${res.status})`);
      setData(await res.json());
    } catch (error) {
      setError(error instanceof Error ? error.message : "Request failed");
    } finally {
      setLoading(false);
    }
  }
```

#### Display the result

The client component disables the button during the request and displays the returned JSON or an error. It never receives your API key.

Import this component into a page in your app and submit the form to run the task.

**`components/ProductListingForm.tsx (lines 9-18)`**

```tsx components/ProductListingForm.tsx (lines 9-18)
    <form
      onSubmit={(e) => {
        e.preventDefault();
        execute({ product_name: "Headphones" });
      }}
    >
      <button disabled={loading}>{loading ? "Generating..." : "Generate"}</button>
      {error && <p role="alert">{error}</p>}
      {data !== null && <pre>{JSON.stringify(data, null, 2)}</pre>}
    </form>
```

#### Complete files

**`Terminal`**

```bash title="Terminal"
npm install @rightbrain/sdk
npx rightbrain@latest login --url https://app.rightbrain.ai
npx rightbrain@latest init
```

**`app/api/tasks/product-listing/route.ts`**

```typescript title="app/api/tasks/product-listing/route.ts"
import type { Tasks } from "@/generated";
import { Client, DirectTransport } from "@rightbrain/sdk";

const client = new Client<Tasks>({
  transport: new DirectTransport({
    baseUrl: "https://app.rightbrain.ai/api/v1",
    accessToken: process.env.RB_API_KEY!,
    orgId: process.env.RB_ORG_ID!,
    projectId: process.env.RB_PROJECT_ID!,
  }),
});

export async function POST(request: Request) {
  const body = await request.json();
  const result = await client["<task-id>"].run({
    inputs: { product_name: body.product_name },
  });
  return Response.json(result.response);
}
```

**`hooks/useGenerateProductListing.ts`**

```typescript title="hooks/useGenerateProductListing.ts"
import { useState } from "react";

export function useGenerateProductListing() {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<unknown>(null);
  const [error, setError] = useState<string | null>(null);

  async function execute(inputs: { product_name: string }) {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch("/api/tasks/product-listing", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(inputs),
      });
      if (!res.ok) throw new Error(`Request failed (HTTP ${res.status})`);
      setData(await res.json());
    } catch (error) {
      setError(error instanceof Error ? error.message : "Request failed");
    } finally {
      setLoading(false);
    }
  }

  return { execute, data, loading, error };
}
```

**`components/ProductListingForm.tsx`**

```tsx title="components/ProductListingForm.tsx"
"use client";

import { useGenerateProductListing } from "../../hooks/useGenerateProductListing";

export function ProductListingForm() {
  const { execute, data, loading, error } = useGenerateProductListing();

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        execute({ product_name: "Headphones" });
      }}
    >
      <button disabled={loading}>{loading ? "Generating..." : "Generate"}</button>
      {error && <p role="alert">{error}</p>}
      {data !== null && <pre>{JSON.stringify(data, null, 2)}</pre>}
    </form>
  );
}
```

## Keep generated types current

Run `npx rightbrain@latest generate` after changing task schemas or the selected tasks. The CLI writes `RB_ORG_ID`, `RB_PROJECT_ID` and `RB_API_KEY` to `.env`; keep that file out of version control.

For a standalone Node script, load the environment with `node --env-file=.env your-script.mjs` or your runtime's environment loader. `DirectTransport` also accepts a `config` object for additional fetch options. Credential options are covered in [Authentication](/docs/api/authentication).

For a generic hook with inferred result types and request cancellation, use [`use-task.ts` from the SDK demo](https://github.com/RightbrainAI/rightbrain-sdk-demo/blob/main/src/lib/use-task.ts).

## Demo app

The [Rightbrain SDK demo](https://github.com/RightbrainAI/rightbrain-sdk-demo) is a working Next.js app. It shows `DirectTransport` in a server route, `PublicTransport` in the browser, and a standalone Node script — each running real tasks that appear in your dashboard's **Runs** view.

## SDK or REST?

| Use case                          | Recommended                                    |
| --------------------------------- | ---------------------------------------------- |
| TypeScript / Node / Next.js apps  | SDK — typed runners, ergonomic, transports     |
| Other languages or frameworks     | [REST API](/docs/api/run-tasks)                |
| Agents and SSE streaming          | [Run agents via the API](/docs/api/run-agents) |
| Lightweight automation or scripts | REST API                                       |

#### [Authentication](/docs/api/authentication)

Create the API key the SDK uses.

#### [Run tasks via the API](/docs/api/run-tasks)

The REST endpoints behind the generated client.