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

# Node.js SDK

> Name the feature and customer of your gateway calls, call the management API, or track LLM calls made without the gateway.

<Columns cols={2}>
  <Card title="npm" icon="https://mintcdn.com/weflayr/jf99vD0W4dsGuj5S/images/icons/brand-npm.svg?fit=max&auto=format&n=jf99vD0W4dsGuj5S&q=85&s=51ba3effdfb65e756436e82a34faa4a7" href="https://www.npmjs.com/package/weflayr" width="24" height="24" data-path="images/icons/brand-npm.svg">
    The `weflayr` package.
  </Card>

  <Card title="Changelog" icon="https://mintcdn.com/weflayr/jf99vD0W4dsGuj5S/images/icons/history.svg?fit=max&auto=format&n=jf99vD0W4dsGuj5S&q=85&s=84c4ca074f5d7d74cf6f394abb6f37d9" href="/changelog/node" width="24" height="24" data-path="images/icons/history.svg">
    What changed in each release.
  </Card>
</Columns>

## Install

Requires Node.js 18 or later.

```bash theme={null}
npm install weflayr
```

## Send metadata to the gateway

Wrap your calls in `propagateMetadata` to tag them with their feature, customer and call name, through the gateway or with telemetry. See [Name features, customers and runs](/sdks/features-and-runs).

## Call the management API

`weflayr.client()` returns a client for every management route, with a key that has the Management scope. See [Call the management API](/sdks/management-api) for an example and the list of routes.

## Track calls made without the gateway

When your app calls the providers directly, the SDK can record each call with OpenTelemetry and send it to Weflayr. See [Telemetry](/sdks/telemetry) for the step by step.

```js theme={null}
const weflayr = require('weflayr');

await weflayr.autoInstrument({ aiSdks: ['openai', 'anthropic'] });
```

## Reference

### `enablePropagateMetadataToGateway`

```js theme={null}
weflayr.enablePropagateMetadataToGateway(gatewayBaseUrl?)
```

Makes every OpenAI client send the current `propagateMetadata` and `setCallName` values in the `x-weflayr-metadata` header, on requests to `https://gateway.weflayr.com`. Pass `gatewayBaseUrl` to target another gateway URL. Requires the `openai` package, and `setup()` to have run. Calls sent to the gateway are recorded by the gateway itself, never twice by the SDK.

### `propagateMetadata`

```js theme={null}
weflayr.propagateMetadata({ featureName, customerName?, extraTags?, featureRunUuid?, providerNameOverrideIfTelemetryInstrumentation? }, fn?)
```

With `fn`, runs it and returns its result. Without, returns a decorator for a class method, or a wrapper: `propagateMetadata(options)(fn)`. Every LLM call made inside, including nested ones, gets its values. Each call of `propagateMetadata` (or of a decorated method) is one feature run.

<ParamField body="featureName" type="string" required>
  The product feature making the call (e.g. `'support-chat'`).
</ParamField>

<ParamField body="customerName" type="string">
  The customer the call is made for. It joins your AI cost to your revenue.
</ParamField>

<ParamField body="extraTags" type="Record<string, string | number | boolean>">
  Your own dimensions to filter on.
</ParamField>

<ParamField body="featureRunUuid" type="string">
  Records the calls under this run instead of a new one, to group the calls of one run made in several scopes or processes. Create it with `weflayr.createFeatureRunUuid()`: 32 lowercase hexadecimal characters.
</ParamField>

<ParamField body="providerNameOverrideIfTelemetryInstrumentation" type="weflayr.AIProviderName">
  The provider to bill a call recorded by the SDK, when the client on the wire differs from it (e.g. Mistral reached through the OpenAI client). Ignored for gateway calls.
</ParamField>

### `setCallName`

```js theme={null}
weflayr.setCallName(callName, fn?)
```

Names the LLM call inside a feature (e.g. `'summarize_ticket'`). With `fn`, runs it and returns its result; without, returns a decorator. It keeps the enclosing `propagateMetadata` scope and does not start a new feature run.

### `autoInstrument`

```js theme={null}
await weflayr.autoInstrument({ aiSdks, ...setupOptions })
```

Records every call of the given provider SDKs: `'openai'`, `'anthropic'`, `'bedrock'`, `'cohere'`, `'google-genai'`, `'elevenlabs'`, `'mistral'`, or an array of them. Each needs its instrumentation package, listed in [Telemetry](/sdks/telemetry#install-and-instrument). The other options are those of `setup`.

### `setup`

```js theme={null}
weflayr.setup({ apiKey?, baseUrl?, defaultTags?, exportMode?, mask?, captureMessageContent?, warnOnExportError? })
```

Configures where recorded calls are sent, without instrumenting any provider SDK: use it when your app already runs its own OpenTelemetry instrumentation, or to send metadata to the gateway. Calling it again replaces the previous configuration.

<ParamField body="apiKey" type="string">
  A key with the Management scope. Defaults to `WEFLAYR_API_KEY`.
</ParamField>

<ParamField body="baseUrl" type="string" default="'https://api.weflayr.com'">
  Where recorded calls are sent. Defaults to `WEFLAYR_BASE_URL` when set.
</ParamField>

<ParamField body="defaultTags" type="object">
  Tags added to every recorded call.
</ParamField>

<ParamField body="exportMode" type="'batch' | 'immediate'" default="'batch'">
  `'immediate'` sends each call as soon as it ends, instead of in batches.
</ParamField>

<ParamField body="captureMessageContent" type="boolean" default="true">
  Set `false` to keep prompts, answers and tool definitions in your process: only tokens, cost and latency are sent.
</ParamField>

<ParamField body="mask" type="(attributes) => attributes">
  Receives each call's attributes and returns the ones to send. Returning `null` keeps them unchanged; throwing an error drops all of them.
</ParamField>

<ParamField body="warnOnExportError" type="boolean" default="true">
  Set `false` to silence the warning written to stderr on each failed export.
</ParamField>

### `flush`

```js theme={null}
await weflayr.flush()
```

Sends the recorded calls still in memory. Call it before a short-lived process (script, Lambda) exits; a long-running server flushes on its own.

### `client`

```js theme={null}
weflayr.client({ apiKey?, baseUrl? })
```

Returns the [management API](/api/management/get-costs) client, to pass to the `weflayr.api` functions. `apiKey` defaults to `WEFLAYR_API_KEY`, `baseUrl` to `https://app.weflayr.com/api`.

## Environment variables

| Variable | What it does |
| - | - |
| `WEFLAYR_API_KEY` | The API key used by `setup`, `autoInstrument` and `client` when none is passed. |
| `WEFLAYR_BASE_URL` | Where recorded calls are sent, when `baseUrl` is not passed. |
| `NODE_DEBUG=weflayr` | Logs what the SDK records and sends. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.