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

# NodeJS

The Gleap Admin SDK for Node.js lets your backend push authoritative customer
data into Gleap: identify contacts, manage companies, manage CRM pipeline
entries, track customer value (MRR) and send server-side events.

## Installation

```bash theme={null}
npm install gleap-admin --save
```

## Usage

Import the GleapAdmin package.

```js theme={null}
import GleapAdmin from "gleap-admin";
```

### Initialize the SDK

It is required to initialize the GleapAdmin SDK before sending events or other requests.

```js theme={null}
GleapAdmin.initialize(process.env.GLEAP_API_TOKEN);
```

The secret API token can be found within your project settings -> Secret API
token. Keep it in an environment variable; it must never ship to client apps.

### Identify a user

```js theme={null}
GleapAdmin.identify("user-id", {
  name: "John Doe",
  email: "john@doe.com",
  value: 499, // MRR: monthly recurring revenue, major units
  phone: "+4395959595",
  customData: {
    plan: "Growth plan",
  },
  // Optional: associate the user with a company.
  company: {
    id: "acme-inc",
    name: "ACME inc.",
  },
});
```

The userId should match the userId you are using to identify your users. All
key-value pairs in the user properties part are optional. Only `company.id`
is required inside the optional `company` object; `company.name` never
overwrites a name set via `updateCompany`.

### Companies

Set authoritative company attributes (plan, value, SLA, address, custom data)
from your backend. These are shown in the dashboard, used for company-level
SLAs and revenue-based prioritization, and are never overwritten by data sent
from your client apps.

```js theme={null}
// Create or update a company (companyId is your own immutable identifier).
const company = await GleapAdmin.updateCompany("acme-inc", {
  name: "ACME inc.",
  plan: "Growth plan",
  value: 4990, // MRR: monthly recurring revenue, major units
  sla: 3600, // Response-time SLA in seconds.
  domain: "acme.com",
  address: { line1: "1 Infinite Loop", city: "Cupertino", country: "US" },
  customData: { tier: "gold" },
});

// Read a company (returns null if it doesn't exist).
const existing = await GleapAdmin.getCompany("acme-inc");

// Delete a company (its contacts and conversations are kept).
const success = await GleapAdmin.deleteCompany("acme-inc");
```

### Pipelines (CRM)

Manage CRM pipeline entries from your backend: put a company or contact on a
pipeline, move it through stages, set field values, or remove it — for example
to mirror your signup or billing lifecycle onto an onboarding pipeline.

Entries are addressed by your own identifiers: the `companyId` you pass to
`updateCompany` for company pipelines, or the `userId` you pass to `identify`
for contact pipelines. Pipeline, stage and field ids come from `getPipelines`:

```js theme={null}
// [{ id, name, recordType, stages: [{ id, name, color }], fields: [{ fieldId, label, type }] }]
const pipelines = await GleapAdmin.getPipelines();
```

```js theme={null}
// Add a company to a pipeline. stageId defaults to the first stage; values
// are keyed by fieldId. If the record is already on the pipeline, the
// existing entry is returned unchanged (adding is idempotent).
const entry = await GleapAdmin.addPipelineEntry("pipeline-id", {
  companyId: "acme-inc",
  stageId: "stage-id",
  values: { dealsize: 4990 },
});

// Create-or-update (like updateCompany): adds the record, or moves it and
// updates its values if it is already on the pipeline. Values are merged,
// and null clears a field.
await GleapAdmin.updatePipelineEntry("pipeline-id", {
  companyId: "acme-inc",
  stageId: "next-stage-id",
});

// Contact pipelines address entries by userId instead.
await GleapAdmin.addPipelineEntry("pipeline-id", { userId: "user-1234" });

// Read an entry (null if the record is not on the pipeline).
const existing = await GleapAdmin.getPipelineEntry("pipeline-id", {
  companyId: "acme-inc",
});

// Remove a record from a pipeline (the company/contact itself is kept).
const success = await GleapAdmin.removePipelineEntry("pipeline-id", {
  companyId: "acme-inc",
});
```

Adding a record and moving it to a new stage run the pipeline's automations,
exactly like the same action in the dashboard. Unknown stage ids and unknown
field keys are rejected with a `400` naming the valid ids.

### Track MRR (customer value)

Gleap uses the `value` field as a customer's MRR: **monthly recurring
revenue, in your billing currency, in major units** (for example `499` or
`49.9`, not cents). Kai PM scores a company account with the maximum of the
company `value` and its members' contact `value`s, counted once per company —
so for team accounts, setting the company value is enough.

Update it from your billing webhook so Gleap always mirrors your billing
system:

```js theme={null}
// e.g. inside a Stripe customer.subscription.updated webhook handler
const mrr = computeMonthlyAmount(subscription); // yearly prices / 12, cents -> major units
await GleapAdmin.updateCompany(companyId, { value: mrr });
// On cancellation:
await GleapAdmin.updateCompany(companyId, { value: 0 });
```

Complete runnable Stripe and Paddle webhook examples ship with the SDK:
[github.com/GleapSDK/GleapAdmin-NodeJS/tree/main/examples](https://github.com/GleapSDK/GleapAdmin-NodeJS/tree/main/examples).

`identify` and `updateCompany` send immediately — safe in short-lived webhook
handlers. `trackEvent` is buffered (flushed every 2.5 seconds), so only use
it from long-running processes.

### Track an event

```js theme={null}
GleapAdmin.trackEvent("user-id", "event-name", {
  someEventData: "yeah!",
});
```

The userId should match the userId you are using to identify your users.

The event data (last param) is optional.

## Rate limit

Please note that the identify and track APIs enforce a rate limit of 1500 requests / 60 seconds per API token. If you exceed the limit, requests are rejected with `429 Too Many Requests` and the token is blocked for a short period before requests are accepted again.
