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

# JavaScript SDK

> Use the typed, server-side JavaScript client for Glean Feed's complete public REST API.

`@gleanfeed/sdk` is the typed server-side client for the public `/api/v1`
contract. Use it when trusted JavaScript or TypeScript code needs in-process
feedback, roadmap, changelog, workspace, tag, comment, pagination, timeout, and
error handling.

<Warning>
  API keys are server credentials. The SDK refuses to initialize in a browser by default. Never put
  a key in a public bundle, mobile app, client component, or `NEXT_PUBLIC_...` variable.
</Warning>

## Requirements and install

* Node.js 20 or later, or a server/edge runtime with standards-compatible
  `fetch`, `Headers`, `URL`, `AbortController`, and `Response` globals.
* A workspace API key with the [scopes](/api/scopes) required by each operation.

```bash theme={null}
npm install @gleanfeed/sdk
```

## Read feedback

```ts theme={null}
import { GleanFeed } from "@gleanfeed/sdk";

const glean = new GleanFeed({
  apiKey: process.env.GLEAN_FEED_API_KEY!,
});

for await (const request of glean.feedback.iterate({ stage: "in_review" })) {
  console.log(request.id, request.title);
}
```

Async iterators follow opaque cursors without loading an unbounded workspace into
memory. The API key determines the workspace; the SDK does not accept a workspace
override.

## Create feedback safely

```ts theme={null}
const request = await glean.feedback.create(
  {
    boardId: process.env.GLEAN_FEED_BOARD_ID!,
    title: "Filter exports by board",
    description: "Let workspace admins export requests from one board.",
    source: {
      kind: "github",
      externalId: "acme/product#42",
      url: "https://github.com/acme/product/issues/42",
      capturedAt: "2026-07-12T12:00:00Z",
      metadata: { label: "customer-request" },
    },
  },
  { idempotencyKey: crypto.randomUUID() },
);
```

Use a stable `source.externalId` when the same external record can be delivered
again. Source metadata is private triage context, but it must not contain
credentials, raw connector payloads, unnecessary personal data, or message
history. Use a stable idempotency key when a separate process may retry the same
logical create.

## Handle errors, timeouts, and cancellation

```ts theme={null}
import { GleanFeedAbortError, GleanFeedApiError, GleanFeedTimeoutError } from "@gleanfeed/sdk";

try {
  await glean.workspace.get({ timeoutMs: 10_000 });
} catch (error) {
  if (error instanceof GleanFeedApiError && error.code === "rate_limited") {
    console.log(error.retryAfterSeconds);
  } else if (error instanceof GleanFeedTimeoutError) {
    console.log("The request timed out.");
  } else if (error instanceof GleanFeedAbortError) {
    console.log("The caller canceled the request.");
  }
}
```

Pass an `AbortSignal` to any operation. API failures expose the HTTP status,
stable error code, optional safe details, and retry interval where applicable.

## Compatibility and versions

The SDK ships ESM and TypeScript declarations. Its major version tracks breaking
SDK interface changes. It targets `/api/v1` and is contract-tested against the
[OpenAPI reference](/api/endpoints); additive v1 response fields do not require
an SDK major release. A future `/api/v2` will require explicit SDK support rather
than silently changing this package's base path.

Pin an exact version for controlled production rollouts, or use a compatible
range when additive SDK releases are acceptable. Verify the package publisher,
repository, version, and changelog before upgrading.

Use the [Headless SDK guides](/headless/overview) for customer-facing UI patterns,
the [widget package](/widget/install#install-from-npm) for a ready-made browser
interface, or the [CLI](/api/cli) for repository and terminal workflows.
