---
title: Get started with the Node.js SDK
description: "Install the Amplitude Node.js SDK, initialize it, send a first event from a server, and fix the problems that stop server-side events from arriving."
product: analytics
lang: en
last_updated: 2026-11-10
token_estimate: 2317
---
# Get started with the Node.js SDK

- **Package:** `@amplitude/analytics-node` ([npm](https://www.npmjs.com/package/@amplitude/analytics-node))
- **Latest version:** 1.5.83
- **Package size:** 10.5 kB gzip

This guide helps you install the Node.js SDK (`@amplitude/analytics-node`), initialize it, and send one event from your server to Amplitude. Each step lists the conditions that commonly break that step, so you can fix a problem where it happens. For the full option list, go to [Configuration options](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/reference#configuration-options). For changes between versions, go to the [Node.js SDK release notes](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk-release-notes).

> For AI agents: a documentation index is available at [/docs/llms.txt](/docs/llms.txt). Append `.md` to any page URL for markdown, or send `Accept: text/markdown`.

The Node.js SDK is for server-side code that sends events on behalf of many users. It doesn't store a user ID, device ID, or session between calls, so you pass the user's identity with each event. For browser code, use [Browser SDK 2](https://amplitude.com/docs/sdks/analytics/browser/browser-sdk-2/get-started) instead.

## Prerequisites

- An Amplitude project and its API key. Find the key in _Settings > Projects > your project > General_.
- The data center your organization uses: US (default) or EU.
- The latest Node.js SDK release, or a pinned version you check against the [Node.js SDK release notes](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk-release-notes) for the features you use.
- A Node.js runtime that supports the global `URL` class and ES2021. The package doesn't declare a minimum Node.js version. The examples on these pages run on Node.js 22.

## Install the SDK

Install the package with your package manager.

#### npm

```bash
npm install @amplitude/analytics-node
```

#### yarn

```bash
yarn add @amplitude/analytics-node
```

#### pnpm

```bash
pnpm add @amplitude/analytics-node
```

The package ships a CommonJS build and an ES module build. Import it with either syntax:

```js
import { init, track } from "@amplitude/analytics-node";
```

```js
const { init, track } = require("@amplitude/analytics-node");
```

### Fix installation problems

| Symptom | Cause | Fix |
| --- | --- | --- |
| `Cannot find module '@amplitude/analytics-node'` | The package isn't installed in the project that runs the code. | Run the install command in the directory that holds your `package.json`, and redeploy with your `node_modules` or lock file. |
| `Cannot read properties of undefined (reading 'BEFORE')`, or `'ENRICHMENT'` | Code written for SDK versions before 1.4.0 uses `Types.PluginType`, which the SDK removed. | Set `type` to the string `"before"`, `"enrichment"`, or `"destination"`. Go to [Plugins](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/instrument-and-configure#plugins). |

## Initialize the SDK

Call `init()` once when your process starts, before it handles requests. `init()` returns an object whose `promise` resolves when the SDK is ready. Calls you make before it resolves wait in a queue and run in order.

```js
import { init } from "@amplitude/analytics-node";

init("AMPLITUDE_API_KEY");
```

If your project uses the EU data center, pass `serverZone: "EU"` as the second argument: `init("AMPLITUDE_API_KEY", { serverZone: "EU" })`. For other options, go to [Configuration options](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/reference#configuration-options).

### Fix initialization problems

| Symptom | Cause | Fix |
| --- | --- | --- |
| Events resolve with `100`, `Event not tracked, no destination plugins on the instance` | Your code called `flush()` before `init()` finished. Or, with an asynchronous `storageProvider`, your code tracked events before `init()` finished. The SDK discards the queued events. | Await `init("AMPLITUDE_API_KEY").promise` before you call `flush()` or, with a `storageProvider`, before you track. |
| Events go to the wrong region, or uploads return `Invalid API key` | `serverZone` doesn't match the project's data center. | Set `serverZone: "EU"` for EU projects. Omit it for US projects. |
| `Amplitude Logger [Error]: Invalid server url`, repeated until `Event rejected due to exceeded retry count` | `serverUrl` doesn't start with `http://` or `https://`. | Use a full URL, such as `https://api2.amplitude.com/2/httpapi`. |

## Send a first event

Track one event for a user and wait for the upload result. Pass the user's ID in the third argument, because the SDK doesn't remember identity between calls. `track()` returns an object whose `promise` resolves after the upload attempt.

```js
import { init, track } from "@amplitude/analytics-node";

init("AMPLITUDE_API_KEY");

const result = await track(
  "Sign Up Completed",
  { plan: "starter" },
  { user_id: "user-12345" },
).promise;

console.log(result.code, result.message);
// 200 Event tracked successfully
```

The SDK uploads queued events every 10 seconds, in requests of up to 200 events. As a result, the `promise` resolves about 10 seconds after the call. In a server, don't await the `promise` in a request handler. Go to [Use the SDK in request handlers](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/instrument-and-configure#use-the-sdk-in-request-handlers).

### Fix upload problems

| `result.code` and `result.message` | Cause | Fix |
| --- | --- | --- |
| `0`, `Event skipped due to optOut config` | Opt-out is on for this SDK instance, through `optOut: true` or `setOptOut(true)`. | Call `setOptOut(false)`, or remove `optOut` from the options. |
| `0`, `Event skipped due to empty event type` | The event name is empty, only whitespace, or not a string. Requires 1.5.70 or later. Earlier versions send the event, and Amplitude rejects it. | Pass a non-empty string as the first argument. |
| `400`, `Event rejected due to missing API key` | `init()` received an empty API key. | Check the environment variable that holds your key. An unset variable passes `undefined` or an empty string. |
| `400`, `Invalid API key: ...` | The key is wrong, or belongs to a project in the other data center. | Copy the key again and check `serverZone`. |
| `400`, `Request missing required field` | The event has neither `user_id` nor `device_id`. The SDK sends it anyway, and Amplitude rejects it. The SDK retries other events in the same request. | Pass `user_id` or `device_id` in the third argument of every call. |
| `400`, `Invalid id length for user_id or device_id` | An ID is shorter than five characters, Amplitude's default minimum. | Use longer IDs, or set [`minIdLength`](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/instrument-and-configure#allow-shorter-ids). |
| `0`, `Unexpected error occurred`, after about 10 seconds | The request never reached a server: DNS failure, a firewall, or no outbound network. The SDK drops these events without retrying. | Confirm that the host can reach `api2.amplitude.com` (or `api.eu.amplitude.com`) on port 443. If outbound traffic must go through a proxy, set [`serverUrl`](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/instrument-and-configure#send-events-through-a-proxy). |
| `500`, `Event rejected due to exceeded retry count` | Amplitude returned server errors or timed out on every attempt, and the SDK reached `flushMaxRetries`. | Check the [debug log](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/verify-events#turn-on-debug-logging) for the status of each attempt. |
| The script exits with no error, but the event never arrives | The process exited, or a serverless runtime froze, before the next upload. | Await `init()`, then await `flush().promise` before the process ends. Go to [Serverless and short-lived processes](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/instrument-and-configure#serverless-and-short-lived-processes). |

## Confirm the event in Amplitude

1. In Amplitude, open **User Lookup** and search for the user ID you passed, `user-12345` in the example.
2. Open the **Activity** tab and turn on **Live event updates**.
3. Confirm that `Sign Up Completed` appears with the `plan` property.

If the event doesn't appear within a minute, follow [Verify events](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/verify-events). That page walks through each stage between `track()` and Amplitude's servers.

## Next steps

- Add the events and properties your tracking plan needs. Go to [Track events](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/instrument-and-configure#track-events).
- Track from a web server without slowing responses. Go to [Use the SDK in request handlers](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/instrument-and-configure#use-the-sdk-in-request-handlers).
- Flush events before a serverless function or script exits. Go to [Serverless and short-lived processes](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/instrument-and-configure#serverless-and-short-lived-processes).
- Tune batching, retries, and timeouts. Go to [Data delivery](https://amplitude.com/docs/sdks/analytics/node/node-js-sdk/instrument-and-configure#data-delivery).

